• category: swing folder: ComboItemHeight title: JComboBoxの高さを変更する tags: [JComboBox, ListCellRenderer] author: aterai pubdate: 2009-03-02T12:37:58+09:00 description: JComboBox自体の高さや、ドロップダウンリスト内にあるアイテムの高さを変更します。 image: https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTJ6VVptrI/AAAAAAAAAVI/x72zWGymqHk/s800/ComboItemHeight.png

概要

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

参考リンク

  • メモ: java - DefaultListCellRenderer does not render empty String correctly when using an editable combo box - Stack Overflow
    • DefaultListCellRendererを編集可能にしたJComboBoxに設定すると、リストアイテム文字列が空""の場合、ドロップダウンリスト内でのそのアイテムの高さが余白分のみ(2px)になってしまう
      • 上記のサンプルも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;
}

コメント