如何更改JComboBox显示区域的外观 [英] How to change appearance of JComboBox's display area

查看:73
本文介绍了如何更改JComboBox显示区域的外观的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为JComboBox使用自定义的BasicComboBoxRenderer,并且更改了下拉列表中各项的外观.但是,这些更改也适用于组合框中显示的单个顶部项(不知道如何调用它).

I'm using a custom BasicComboBoxRenderer for a JComboBox and I've changed the appearance of the items of the drop-down list. However these changes also apply to the single top item that shows in the combobox (don't know how to call it).

如果可能的话,我希望最上面的项目独立于列表中的其他项目.我还想消除焦点放在顶部的蓝色(setFocusable(false)不是我想要的颜色).

I want the top item to be independent of the other items in the list, if possible. I would also like to get rid of the top item's blue color when it is focused (setFocusable(false) is not what I want).

我尝试使用渲染器索引"(-1)影响顶部项目,但似乎无济于事.

I've tried to use the "renderer index" (-1) to affect the top item but it doesn't seem to help.

有什么想法吗?

P.S不幸的是,我无法添加更清晰的图像(没有信誉).

P.S Unfortunately I couldn't add images to be more clear (no reputation).

当我说我想让顶层项目与下拉列表中的所有其他项目保持独立时,我的意思是总是看起来与其他项目有所不同.例如,在我的自定义BasicComboBoxRenderer中,我将所选项目设置为具有不同的背景,但是该背景也适用于顶部项目(因为所选项目成为组合框的顶部项目).

When I say that I want the top item to be independent from all the other items of the drop-down list I mean to always look different from the rest of them. For example in my custom BasicComboBoxRenderer I've set the selected item to have a different background, but this background also applies to the top item (since the selected item becomes the top item of the combobox).

顶部项目=我的意思是组合框显示区域,因此我想影响显示区域中显示的项目,而不是下拉列表中的第一项.我设法通过在组合框本身上使用setBackground和setFocusable(false)来做到这一点(这不是很有用,因为我想保留焦点机制).但是问题是(焦点问题除外),例如,如果我通过自定义BasicComboBoxRenderer或ListCellRenderer类在列表中的每个项目上设置了边框,则该边框会出现在显示区域中显示的项目上.所以这里有两个问题:

EDIT 2: top item = I meant the combobox display area, so I want to affect the item that is shown at the display area and not the first item in the drop-down list. I managed to do this by using setBackground on the combobox itself AND setFocusable(false) (which is not very helpful because I want to keep the focus mechanism). But the problem is (except the focus issue) that if for example I set a border on each item in the list through a custom BasicComboBoxRenderer or ListCellRenderer class, this same border appears on the item that is shown in the display area. So there are 2 questions here:

-是否可以区分下拉列表中的项目和显示区域中的单个项目?

--Is there any way to differentiate the layout of the items in the drop-down list and the single item in the display area?

-是否有任何方法可以在不禁用焦点机制的情况下禁用组合框的焦点颜色,就像在按钮上使用setFocusPainted(false)一样? (我也尝试过在组合框上添加自定义FocusListener,但是通过focusGained()对背景所做的任何更改都只会影响按钮,而不会影响显示区域中显示的项目.)

--Is there any way to disable the focus color of the combobox without disabling the focus mechanism, just like when we use setFocusPainted(false) on buttons? (I've also tried to add a custom FocusListener on the combobox but any change made of the background through focusGained() affects only the button and not the item shown in the display area).

很抱歉造成混乱,并进行了多次修改...

Sorry for the confusion and the multiple edits...

推荐答案

  • 查看了组合框提示通过@camickr,

    • have look at Combo Box Prompt by @camickr,

      定义的提示不能从JComboBox.getSelectedXxx

      编辑

      BasicComboBoxRenderer或ListCellRenderer可以通过这种方式实现

      BasicComboBoxRenderer or ListCellRenderer can do that this way

      import java.awt.*;
      import javax.swing.*;
      
      public class TestHighLightRow {
      
          public void makeUI() {
              Object[] data = {"One", "Two", "Three"};
              JComboBox comboBox = new JComboBox(data);
              comboBox.setPreferredSize(comboBox.getPreferredSize());
              comboBox.setRenderer(new HighLightRowRenderer(comboBox.getRenderer()));
              JFrame frame = new JFrame();
              frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
              frame.getContentPane().add(comboBox);
              frame.pack();
              frame.setLocationRelativeTo(null);
              frame.setVisible(true);
          }
      
          public static void main(String[] args) {
              SwingUtilities.invokeLater(new Runnable() {
      
                  @Override
                  public void run() {
                      new TestHighLightRow().makeUI();
                  }
              });
          }
      
          public class HighLightRowRenderer implements ListCellRenderer {
      
              private final ListCellRenderer delegate;
              private int height = -1;
      
              public HighLightRowRenderer(ListCellRenderer delegate) {
                  this.delegate = delegate;
              }
      
              @Override
              public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                  Component component = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                  Dimension size = component.getPreferredSize();
                  if (index == 0) {
                      component.setBackground(Color.red);
                      if (component instanceof JLabel) {
                          ((JLabel) component).setHorizontalTextPosition(JLabel.CENTER);
                      }
                  }
                  return component;
              }
          }
      }
      

      EDIT2

      JComboBox具有两种状态

      JComboBox has two states

      • 可编辑

      • editable

      不可编辑

      基本上所有值都可以从UIManager,快捷方式访问

      basically all values could be accesible from UIManager, shortcuts

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

      这篇关于如何更改JComboBox显示区域的外观的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆