简体   繁体   English

不可编辑的JComboBox边框

[英]Not Editable JComboBox Border

I am using Metal L&F. 我正在使用Metal L&F。 I want to make a JComboBox , that has only 1 pixel border. 我想制作一个只有1像素边框的JComboBox This not a problem, as long as the cb is editable . 这不是问题,只要cb是可编辑的 This corresponds to the first cb in the picture named "Editable". 这对应于名为“可编辑”的图片中的第一个cb。

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

But when I do cb.setEditable(false) , an additional border occurs inside the box (changed to red in the picture "Dropdown", you see the original color in the picture named "Fixed"). 但是当我执行cb.setEditable(false)时 ,框内会出现一个额外的边框(在图片“Dropdown”中更改为红色,您会在图片中看到名为“Fixed”的原始颜色)。 Although I tried to set the border and I also tried to use my own CellRenderer, the border still gets painted. 虽然我试图设置边框,但我也尝试使用自己的CellRenderer,边框仍然会被绘制。 It seems to me, that the unwanted border does not come from the CellRenderer. 在我看来,不需要的边框不是来自CellRenderer。 When I try to manipulate the border from the cb itself (see comment //), it only adds/removes an additional outer border. 当我尝试从cb本身操纵边界时(请参阅注释//),它只会添加/删除一个额外的外边框。 The editorComponent also seems not to be responsible to me. 编辑组件似乎也不对我负责。

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

I also tried out some UI variables like the ones below without taking affect on this border. 我也尝试了一些像下面的UI变量而不影响这个边界。

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

Image: http://upload.mtmayr.com/dropdown_frame.png (link broken) 图片: http//upload.mtmayr.com/dropdown_frame.png (链接坏了)

Complete code for testing: 完整的测试代码:

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();
            }
        });
    }
}
  • not able to ...., every have got the same Borders, there must be another issue, 1st and 2nd. 不能....,每个人都有相同的边界,必须有另一个问题,第1和第2。 are editable JComboBoxes 是可编辑的JComboBoxes

  • for better help sooner post an SSCCE, short, runnable, compilable, just about two JComboBoxes, Native OS, compiled in JDK, runned in JRE 更快地发布SSCCE,简短,可运行,可编译,只有两个JComboBox,Native OS,用JDK编译,在JRE中运行

WinXP Java6 WinXP Java6

在此输入图像描述

Win7 Java7 Win7 Java7

>将被编辑

Win7 Java6 Win7 Java6

>将被编辑

Win8 Java6 Win8 Java6

在此输入图像描述

Win8 Java7 Win8 Java7

>将被编辑

from code 来自代码

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();
            }
        });
    }
}
  • How about override MetalComboBoxUI#paintCurrentValueBackground(...) 如何覆盖MetalComboBoxUI#paintCurrentValueBackground(...)
    • using JDK 1.7.0_17, Windows 7 使用JDK 1.7.0_17,Windows 7

在此输入图像描述

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM