2013-03-25 7 views
2

Я использую Metal L & F. Я хочу сделать JComboBox, который имеет только 1 пиксельную границу. Это не проблема, если cb равен editable. Это соответствует первому cb в изображении под названием «Редактируемый».Не редактируемые JComboBox Border

cb.setEditable(true); 
((JTextComponent) (cb.getEditor().getEditorComponent())).setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, COLOR)); 

Но когда я cb.setEditable (ложь), дополнительная граница происходит внутри коробки (изменен на красный в картине «раскрывающийся», вы видите оригинальный цвет в картине под названием «Fixed»). Хотя я попытался установить границу, и я также попытался использовать свой собственный CellRenderer, граница по-прежнему окрашивается. Мне кажется, что нежелательная граница не исходит от CellRenderer. Когда я пытаюсь манипулировать границей из самого cb (см. Комментарий //), он только добавляет/удаляет дополнительную внешнюю границу. Редактор Компонент также, похоже, не несет ответственности за меня.

cb.setRenderer(new CbCellRenderer()); 
//cb.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, COLOR)); 
//cb.setBorder(BorderFactory.createEmptyBorder()); 

class CbCellRenderer implements ListCellRenderer { 

    protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer(); 

    @Override 
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 
     JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 
     renderer.setBorder(BorderFactory.createEmptyBorder()); 
     return renderer; 
    }   
} 

Я также опробовал некоторые переменные пользовательского интерфейса, подобные приведенным ниже, не влияя на эту границу.

UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); 
UIManager.put("ComboBox.selectionForeground", Color.green); 
UIManager.put("ComboBox.disabledBackground", Color.green); 
... 

Изображение: http://upload.mtmayr.com/dropdown_frame.png(ссылка сломана)

Полный код для тестирования:

import java.awt.*; 
import java.util.Vector; 
import javax.swing.*; 
import javax.swing.plaf.basic.BasicComboPopup; 

public class ComboTest { 

    private Vector<String> listSomeString = new Vector<String>(); 
    private JComboBox editableComboBox = new JComboBox(listSomeString); 
    private JComboBox nonEditableComboBox = new JComboBox(listSomeString); 
    private JFrame frame; 
    public final static Color COLOR_BORDER = new Color(122, 138, 153); 

    public ComboTest() { 
     listSomeString.add("row 1"); 
     listSomeString.add("row 2"); 
     listSomeString.add("row 3"); 
     listSomeString.add("row 4"); 

     editableComboBox.setEditable(true); 
     editableComboBox.setBackground(Color.white); 
     Object child = editableComboBox.getAccessibleContext().getAccessibleChild(0); 
     BasicComboPopup popup = (BasicComboPopup) child; 
     JList list = popup.getList(); 
     list.setBackground(Color.white); 
     list.setSelectionBackground(Color.red); 
     JTextField tf = ((JTextField) editableComboBox.getEditor().getEditorComponent()); 
     tf.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, COLOR_BORDER)); 

     nonEditableComboBox.setEditable(false); 
     nonEditableComboBox.setBorder(BorderFactory.createEmptyBorder()); 
     nonEditableComboBox.setBackground(Color.white); 
     Object childNonEditable = nonEditableComboBox.getAccessibleContext().getAccessibleChild(0); 
     BasicComboPopup popupNonEditable = (BasicComboPopup) childNonEditable; 
     JList listNonEditable = popupNonEditable.getList(); 
     listNonEditable.setBackground(Color.white); 
     listNonEditable.setSelectionBackground(Color.red); 

     frame = new JFrame(); 
     frame.setLayout(new GridLayout(0, 1, 10, 10)); 
     frame.add(editableComboBox); 
     frame.add(nonEditableComboBox); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocation(100, 100); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 

     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ComboTest ct = new ComboTest(); 
      } 
     }); 
    } 
} 
+0

аналогичные проводки: [link1] (http://stackoverflow.com/questions/10569759/ border-editor-when-rendering-item-in-jcombobox-and-editable-false) [link2] (http://stackoverflow.com/questions/10169022/jcombobox-does-not-behave-same-as-jtextfield -how-can-i-have-it-look-like) [link3] (http://stackoverflow.com/questions/9322903/how-do-you-change-border-of-the-pop-up-section-of-a-jcombobox) [link4] (http: //stackoverflow.com/questions/776893/remove-border-from-jcombobox) – mtmayr

ответ

2
  • Как насчет переопределения MetalComboBoxUI # paintCurrentValueBackground (...)
    • использованием JDK 1.7.0_17, Windows 7

enter image description here

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.text.*; 
import javax.swing.plaf.*; 
import javax.swing.plaf.basic.*; 
import javax.swing.plaf.metal.*; 

public class ComboBoxUIDemo { 
    private static Color BORDER = Color.GRAY; 
    public JComponent makeUI() { 
    //UIManager.put("ComboBox.foreground", Color.WHITE); 
    //UIManager.put("ComboBox.background", Color.BLACK); 
    //UIManager.put("ComboBox.selectionForeground", Color.CYAN); 
    //UIManager.put("ComboBox.selectionBackground", Color.BLACK); 

    //UIManager.put("ComboBox.buttonDarkShadow", Color.WHITE); 
    //UIManager.put("ComboBox.buttonBackground", Color.GRAY); 
    //UIManager.put("ComboBox.buttonHighlight", Color.WHITE); 
    //UIManager.put("ComboBox.buttonShadow", Color.WHITE); 
    //UIManager.put("ComboBox.editorBorder", BorderFactory.createLineBorder(Color.RED)); 

    Box box = Box.createVerticalBox(); 

    UIManager.put("ComboBox.border", BorderFactory.createEmptyBorder()); 
    for(int i=0; i<2; i++) { // Defalut 
     JComboBox<String> cb = new JComboBox<>(makeModel()); 
     if(i%2==0) setEditable(cb); 
     setPopupBorder(cb); 
     box.add(cb); 
     box.add(Box.createVerticalStrut(10)); 
    } 

    { 
     // Override MetalComboBoxUI#paintCurrentValueBackground(...) 
     JComboBox<String> cb = new JComboBox<>(makeModel()); 
     cb.setUI(new MetalComboBoxUI() { 
     @Override public void paintCurrentValueBackground(
     Graphics g, Rectangle bounds, boolean hasFocus) { 
      //if (MetalLookAndFeel.usingOcean()) { 
      if(MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme) { 
      g.setColor(MetalLookAndFeel.getControlDarkShadow()); 
      g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height - 1); 
      //COMMENTOUT>>> 
      //g.setColor(MetalLookAndFeel.getControlShadow()); 
      //g.drawRect(bounds.x + 1, bounds.y + 1, bounds.width - 2, 
      //   bounds.height - 3); 
      //<<<COMMENTOUT 
      if (hasFocus && !isPopupVisible(comboBox) && arrowButton != null) { 
       g.setColor(listBox.getSelectionBackground()); 
       Insets buttonInsets = arrowButton.getInsets(); 
       if (buttonInsets.top > 2) { 
       g.fillRect(bounds.x + 2, bounds.y + 2, bounds.width - 3, 
          buttonInsets.top - 2); 
       } 
       if (buttonInsets.bottom > 2) { 
       g.fillRect(bounds.x + 2, bounds.y + bounds.height - 
          buttonInsets.bottom, bounds.width - 3, 
          buttonInsets.bottom - 2); 
       } 
      } 
      } else if (g == null || bounds == null) { 
      throw new NullPointerException(
       "Must supply a non-null Graphics and Rectangle"); 
      } 
     } 
     }); 
     setPopupBorder(cb); 

     box.add(cb); 
     box.add(Box.createVerticalStrut(10)); 
    } 

    UIManager.put("ComboBox.border", BorderFactory.createLineBorder(BORDER)); 
    for(int i=0; i<2; i++) { // BasicComboBoxUI 
     JComboBox<String> cb = new JComboBox<>(makeModel()); 
     if(i%2==0) setEditable(cb); 
     cb.setUI(new BasicComboBoxUI()); 
     setPopupBorder(cb); 
     box.add(cb); 
     box.add(Box.createVerticalStrut(10)); 
    } 

    JPanel p = new JPanel(new BorderLayout()); 
    p.setBorder(BorderFactory.createEmptyBorder(10,20,10,20)); 
    p.add(box, BorderLayout.NORTH); 
    return p; 
    } 
    private static void setEditable(JComboBox cb) { 
    cb.setEditable(true); 
    ComboBoxEditor editor = cb.getEditor(); 
    Component c = editor.getEditorComponent(); 
    if(c instanceof JTextField) { 
     JTextField tf = (JTextField)c; 
     tf.setBorder(BorderFactory.createMatteBorder(1,1,1,0,BORDER)); 
    } 
    } 
    private static void setPopupBorder(JComboBox cb) { 
    Object o = cb.getAccessibleContext().getAccessibleChild(0); 
    JComponent c = (JComponent)o; 
    c.setBorder(BorderFactory.createMatteBorder(0,1,1,1,BORDER)); 
    } 
    private static DefaultComboBoxModel<String> makeModel() { 
    DefaultComboBoxModel<String> m = new DefaultComboBoxModel<>(); 
    m.addElement("1234"); 
    m.addElement("5555555555555555555555"); 
    m.addElement("6789000000000"); 
    return m; 
    } 
    public static void main(String[] args) { 
//  OceanTheme theme = new OceanTheme() { 
//  @Override protected ColorUIResource getSecondary2() { 
//   return new ColorUIResource(Color.RED); 
//  } 
//  }; 
//  MetalLookAndFeel.setCurrentTheme(theme); 

    EventQueue.invokeLater(new Runnable() { 
     @Override public void run() { 
     createAndShowGUI(); 
     } 
    }); 
    } 
    public static void createAndShowGUI() { 
    JFrame f = new JFrame(); 
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    f.getContentPane().add(new ComboBoxUIDemo().makeUI()); 
    f.setSize(320, 240); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
    } 
} 
+0

+1 .... сумасшедший взлом, вывод выглядит как для ATARI :-), – mKorbel

+0

спасибо атерай! что, кажется, решает мою проблему! я все еще занят, применяя его к моей программе. – mtmayr

2
  • не в состоянии ...., каждый имеет получили те же границы, должно быть другое выпуск, 1-й и 2-й. редактируемые JComboBoxes

  • для лучшей помощи рано опубликовать SSCCE, короткий, работоспособным, компилируется, всего около двух JComboBoxes, Native OS, составленного в JDK, запущенный в JRE

WinXP Java6

enter image description here

Win7 Java7

> will be edited

Win7 Java6

> will be edited

Win8 Java6

enter image description here

Win8 Java7

> will be edited

из кода

import java.awt.*; 
import java.util.Vector; 
import javax.swing.*; 
import javax.swing.UIManager; 
import javax.swing.plaf.ColorUIResource; 
import javax.swing.plaf.metal.MetalComboBoxButton; 

public class MyComboBox { 

    private Vector<String> listSomeString = new Vector<String>(); 
    private JComboBox someComboBox = new JComboBox(listSomeString); 
    private JComboBox editableComboBox = new JComboBox(listSomeString); 
    private JComboBox non_EditableComboBox = new JComboBox(listSomeString); 
    private JFrame frame; 

    public MyComboBox() { 
     listSomeString.add("-"); 
     listSomeString.add("Snowboarding"); 
     listSomeString.add("Rowing"); 
     listSomeString.add("Knitting"); 
     listSomeString.add("Speed reading"); 
// 
     someComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); 
     someComboBox.setFont(new Font("Serif", Font.BOLD, 16)); 
     someComboBox.setEditable(true); 
     someComboBox.getEditor().getEditorComponent().setBackground(Color.YELLOW); 
     ((JTextField) someComboBox.getEditor().getEditorComponent()).setBackground(Color.YELLOW); 
// 
     editableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); 
     editableComboBox.setFont(new Font("Serif", Font.BOLD, 16)); 
     editableComboBox.setEditable(true); 
     JTextField text = ((JTextField) editableComboBox.getEditor().getEditorComponent()); 
     text.setBackground(Color.YELLOW); 
     JComboBox coloredArrowsCombo = editableComboBox; 
     Component[] comp = coloredArrowsCombo.getComponents(); 
     for (int i = 0; i < comp.length; i++) { 
      if (comp[i] instanceof MetalComboBoxButton) { 
       MetalComboBoxButton coloredArrowsButton = (MetalComboBoxButton) comp[i]; 
       coloredArrowsButton.setBackground(null); 
       break; 
      } 
     } 
// 
     non_EditableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); 
     non_EditableComboBox.setFont(new Font("Serif", Font.BOLD, 16)); 
// 
     frame = new JFrame(); 
     frame.setLayout(new GridLayout(0, 1, 10, 10)); 
     frame.add(someComboBox); 
     frame.add(editableComboBox); 
     frame.add(non_EditableComboBox); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocation(100, 100); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     UIManager.put("ComboBox.background", new ColorUIResource(Color.yellow)); 
     UIManager.put("JTextField.background", new ColorUIResource(Color.yellow)); 
     UIManager.put("ComboBox.selectionBackground", new ColorUIResource(Color.magenta)); 
     UIManager.put("ComboBox.selectionForeground", new ColorUIResource(Color.blue)); 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       MyComboBox aCTF = new MyComboBox(); 
      } 
     }); 
    } 
} 
+0

спасибо за ваш ответ. Я уже видел вашу публикацию в другом потоке. Я думаю, что ваши сборники также показывают внутреннюю границу, о которой я говорю! – mtmayr

Смежные вопросы