禁用JComboBox箭头按钮

3

我尝试制作一个没有下拉箭头的可编辑 JComboBox。(它将根据用户在其编辑器中输入的内容显示其下拉列表)

到目前为止,虽然下拉箭头不可见,但仍然可以点击!并且它仍会在点击时显示列表。

public class MyComboBox<E> extends JComboBox<E> {

    public MyComboBox(E[] list) {
        super(list);
        this.setEditable(true);
        setUI(new BasicComboBoxUI() {
            @Override
            protected JButton createArrowButton() {
                return new JButton() {
                    @Override
                    public int getWidth() {
                        return 0;
                    }
                };
            }
        });
    }
}

有没有办法禁用它?

为什么不直接禁用它? - Obicere
尝试过,但没有起作用。 - pwillemet
通过调用 setEnabled(false) 方法实现禁用? - Obicere
是的,看起来显示列表的行为实际上并不是由按钮捕获的动作事件引起的。 - pwillemet
3个回答

5

我终于成功了!诀窍在于更改UI后,ComboBox不具有相同的组件:

在调用setUI方法之前列出组件时:

class javax.swing.plaf.metal.MetalComboBoxButton

class javax.swing.CellRendererPane

class javax.swing.plaf.metal.MetalComboBoxEditor$1

在调用setUI方法之后列出组件时:

class kcomponent.MyComboBox$1$1

class javax.swing.plaf.basic.BasicComboBoxEditor$BorderlessTextField

class javax.swing.CellRendererPane

然后我删除了这些组件的MouseListeners,并且它在第一个组件(MyComboBox$1$1)的第二个MouseListener上起作用。但是光标仍然不同(鼠标指针而不是插入符号位置),然后我将其完全删除,最终它运行得非常好!

这是我的修正代码:

public class MyComboBox<E> extends JComboBox<E> {

    public MyComboBox(E[] list) {
        super(list);
        this.setEditable(true);
        this.setUI(new BasicComboBoxUI() {
            @Override
            protected JButton createArrowButton() {
                return new JButton() {
                    @Override
                    public int getWidth() {
                        return 0;
                    }
                };
            }
        });
        this.remove(this.getComponent(0));
    }
}

2
你可以根据需要将其删除:
import java.awt.Component;
import java.awt.Container;

import javax.swing.AbstractButton;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;

public class PlayWithComboArrow {
   public static void main(String[] args) {
      String[] items = {"Fe", "Fi", "Fo", "Fum"};
      JComboBox<String> combo = new JComboBox<String>(items);
      combo.setEditable(true);

      removeButton(combo);

      JOptionPane.showMessageDialog(null, combo);
   }

   private static void removeButton(Container container) {
      Component[] components = container.getComponents();
      for (Component component : components) {
         if (component instanceof AbstractButton) {
            container.remove(component);
         }
      }
   }
}

我也试图将其移除,但您仍然可以在字段右侧单击,列表将被显示,此外由于不可见但存在的按钮,一些空间会丢失。 - pwillemet
@Kwoinkwoin:确实,你是正确的。我会给你一个加分,并且我需要考虑一下这个问题。 - Hovercraft Full Of Eels

2
也许你可以使用以下方法:
  • UIManager.put("ComboBox.squareButton", Boolean.FALSE);
  • JButton#setBorder(BorderFactory.createEmptyBorder());
  • JButton#setVisible(false);

enter image description here

import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicComboBoxUI;

public final class DisableArrowButtonTest {
  public JComponent makeUI() {
    String[] items = {
      "JComboBox 111111111:", "JComboBox 222:", "JComboBox 33:"
    };
    JComboBox<String> comboBox0 = new JComboBox<>(items);
    JComboBox<String> comboBox1 = new MyComboBox1<>(items);
    JComboBox<String> comboBox2 = new MyComboBox2<>(items);
    comboBox0.setEditable(true);
    comboBox1.setEditable(true);
    comboBox2.setEditable(true);

    JPanel p = new JPanel();
    p.add(comboBox0);
    p.add(Box.createRigidArea(new Dimension(300, 40)));
    p.add(comboBox1);
    p.add(Box.createRigidArea(new Dimension(300, 40)));
    p.add(comboBox2);
    return p;
  }
  public static void main(String[] args) {
    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 DisableArrowButtonTest().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

class MyComboBox1<E> extends JComboBox<E> {
  public MyComboBox1(E[] list) {
    super(list);
  }
  @Override public void updateUI() {
    super.updateUI();
    setUI(new BasicComboBoxUI() {
      @Override protected JButton createArrowButton() {
        return new JButton() {
          @Override public int getWidth() {
            return 0;
          }
        };
      }
    });
    setBorder(BorderFactory.createLineBorder(Color.GRAY));
  }
}

class MyComboBox2<E> extends JComboBox<E> {
  public MyComboBox2(E[] list) {
    super(list);
  }
  @Override public void updateUI() {
    super.updateUI();
    UIManager.put("ComboBox.squareButton", Boolean.FALSE);
    setUI(new BasicComboBoxUI() {
      @Override protected JButton createArrowButton() {
        JButton b = new JButton();
        b.setBorder(BorderFactory.createEmptyBorder());
        b.setVisible(false);
        return b;
      }
    });
    setBorder(BorderFactory.createLineBorder(Color.GRAY));
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接