概要

JComboBox自体の高さや、ドロップダウンリスト内にあるアイテムの高さを変更します。

サンプルコード

JComboBox<String> combo2 = new JComboBox<>(items);
combo2.setRenderer(new DefaultListCellRenderer() {
  private int cheight;
  @Override public Component getListCellRendererComponent(
      JList list, Object value, int index,
      boolean isSelected, boolean cellHasFocus) {
    super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
    Dimension d = super.getPreferredSize();
    cheight = index < 0 ? d.height : 32;
    return this;
  }

  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    d.height = cheight;
    return d;
  }
});
View in GitHub: Java, Kotlin

解説

  • setPreferredSize
    • セルレンダラーにsetPreferredSize(...)メソッドで高さを設定
      JComboBox combo1 = new JComboBox(items);
      JLabel renderer1 = (JLabel) combo1.getRenderer();
      renderer1.setPreferredSize(new Dimension(0, 32));
      
  • getListCellRendererComponent
    • セルレンダラーのgetListCellRendererComponent(...)メソッド内で、index0以上の場合はgetPreferredSize()メソッドで取得する高さを切り替える
  • html
    • htmlタグを使用してセルレンダラーに高さを指定
      JComboBox<String> combo3 = new JComboBox<>(items);
      combo3.setRenderer(new DefaultListCellRenderer() {
        @Override public Component getListCellRendererComponent(
              JList list, Object value, int index,
              boolean isSelected, boolean cellHasFocus) {
          String title = Objects.toString(value, "");
          if (index >= 0) {
            title = String.format("<html><table><td height='32'>%s", value);
          }
          return super.getListCellRendererComponent(list, title, index, isSelected, cellHasFocus);
        }
      });
      
  • icon
    • 幅ゼロのアイコンを使用してセルレンダラーに高さを指定
      JComboBox<String> combo4 = new JComboBox<>(items);
      combo4.setRenderer(new DefaultListCellRenderer() {
        @Override public Component getListCellRendererComponent(
            JList list, Object value, int index,
            boolean isSelected, boolean cellHasFocus) {
          super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
          if (index >= 0) {
            setIcon(new Icon() {
              @Override public void paintIcon(Component c, Graphics g, int x, int y) {}
              @Override public int getIconWidth()  { return 0;  }
              @Override public int getIconHeight() { return 32; }
            });
          } else {
            setIcon(null);
          }
          //setIconTextGap(0);
          return this;
        }
      });
      

  • DefaultListCellRendererを編集可能にしたJComboBoxに設定すると、リストアイテム文字列が空""の場合、ドロップダウンリスト内でのそのアイテムの高さが余白分のみ(2px)になってしまう
    • 参考: java - DefaultListCellRenderer does not render empty String correctly when using an editable combo box - Stack Overflow
    • 上記のサンプルもDefaultListCellRendererを使用しているが、直接高さを指定しているので編集可にしてもこの状態にはならない
    • JComboBox#setPrototypeDisplayValue(...)で文字列を設定していても、高さには効果がない
    • 回答にあるBasicComboBoxRendererでこの状態にならない理由は、以下のようにBasicComboBoxRenderer#getPreferredSize()をオーバーライドし、空白文字を一時的に追加してから高さを求めているため
      @Override public Dimension getPreferredSize() {
        Dimension size;
        if ((this.getText() == null) || (this.getText().equals(""))) {
          setText(" ");
          size = super.getPreferredSize();
          setText("");
        } else {
          size = super.getPreferredSize();
        }
        return size;
      }
      

参考リンク

コメント