编程语言
首页 > 编程语言> > java-不可编辑的JComboBox边框

java-不可编辑的JComboBox边框

作者:互联网

我正在使用Metal L& F.我想制作一个JComboBox,它只有1个像素边框.只要cb是可编辑的,这不是问题.这对应于图片中名为“可编辑”的第一个cb.

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

但是,当我执行cb.setEditable(false)时,框内会出现一个额外的边框(在图片“ Dropdown”中变为红色,您会在图片中看到“ Fixed”的原始颜色).尽管我尝试设置边框,也尝试使用自己的CellRenderer,但边框仍然被绘制.在我看来,不需要的边框不是来自CellRenderer.当我尝试从cb本身操纵边框时(请参阅注释//),它只会添加/删除其他外部边框. editorComponent似乎也不对我负责.

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;
    }        
}

我还尝试了一些如下所示的UI变量,但不影响此边界.

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();
            }
        });
    }
}

解决方法:

>如何覆盖MetalComboBoxUI#paintCurrentValueBackground(…)

>在Windows 7中使用JDK 1.7.0_17

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);
  }
}

标签:jcombobox,border,swing,java
来源: https://codeday.me/bug/20191031/1973071.html