当前位置: 首页 > 知识库问答 >
问题:

不可编辑的 JComboBox 边框

戴浩初
2023-03-14

我正在使用金属 L

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

但当我这样做时,cb。setEditable(false),框内出现一个附加边框(在图片“下拉”中变为红色,您可以在名为“固定”的图片中看到原始颜色)。虽然我尝试设置边界,也尝试使用自己的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;
    }        
}

我还尝试了一些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 < sup >(链接断开)

完整的测试代码:

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

共有2个答案

卢英范
2023-03-14

> < li>

无法....,每有相同的边界,一定有另一个问题,第一和第二。是可编辑的JComboBoxes

为了更好的帮助,更快地发布一个SSCCE,简短,可运行,可编译,只有大约两个JComboBox,Native OS,在JDK中编译,在JRE中运行

WinXP Java6

Win7 Java7

Win7 Java6

Win8 Java6

Win8 Java7

代码

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();
            }
        });
    }
}
万嘉石
2023-03-14
  • 重写metalcomboxUI#paintCurrentValueBackground(…)怎么样
    • 使用JDK1.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);
      }
    }
    

 类似资料:
  • 在我的应用程序中,有一个JComboBox,其中包含大约200个条目。使用该应用程序的人抱怨说,即使他们确切地知道列表的最后一个元素是什么,也必须一直滚动到底部是令人沮丧的。 所以我把JComboBox设置成可编辑的,这样他们就可以输入最后一个元素了。但是,我的数据库不接受该组合框的下拉列表中没有的任何值。 有没有办法使JComboBox仅“可键入”而不是“可编辑”,因此它将允许您键入值,但前提是

  • < br >我有这段代码,其中我设计了一个< code >可编辑的JComboBox来侦听我的< code>keyPressed事件,并显示一条消息,说明键已被按下。但我不知道为什么这没用。作为初学者,我可能在逻辑上/概念上犯了错误。 因此,我想征求关于如何构建代码的建议,以使其工作。 密码

  • 问题内容: 首先:很抱歉,我无法提供SSCCE。我试图在一个小项目上重现此问题,但是没有成功,或者我应该说成功,因为它在那里工作! 所以这是我的问题:我有一个可编辑的JCombobox,它应通过单击编辑器组件来监听焦点事件。但事实并非如此。 这是我附加侦听器的代码段: 我已经尝试删除组合框上的所有其他侦听器,删除观察者模式,保护组合框并将侦听器附加到每个孩子上,… 是否有调试事件的好方法? 可以在

  • 首先:很抱歉,我无法提供SSCCE。我试图在一个小项目上重现这个问题,但没有成功,或者说成功,因为它在那里工作! 这就是我的问题:我有一个可编辑的JCombobox,它应该通过单击编辑器组件来收听焦点事件。但它没有。 下面是一个代码片段,我在其中附加了侦听器: 我已经尝试删除组合框上的所有其他侦听器,删除观察者模式,使组合框受到保护并将侦听器附加到每个孩子上,... 我也试着像这篇文章中写的那样重

  • 如何在jcombobox中添加键事件侦听器,以便它接受EX的整个字符串。如果我添加's',它应该在数据库中搜索以's'开头的字符串,如果没有结果,那么它应该等待用户在组合框中键入其他字符来获得类似的结果

  • 我想要一个有4列的jtable。一列必须是组合框。其他列是字符串。 只要找到问题:在注释语句jcb.seteditable(true)时;,如果我在comboxcell上单击一次,它就会打开这个单元格。但我不知道为什么效果更好。此外,我希望combox可编辑。 我怎么能对其他细胞有同样的行为。 再次您好,我已经更新了代码,以便使-如果我通过重写方法在单元格上单击一次,单元格可以编辑-如果我通过重写