概要

JComboBoxのドロップダウンリストにJLabelのヘッダとJMenuItemのフッタを追加します。

スクリーンショット

Swing/HeaderFooterComboPopup.png

サンプルコード

class HeaderFooterComboPopup extends BasicComboPopup {
  protected transient JLabel header;
  protected transient JMenuItem footer;

  public HeaderFooterComboPopup(JComboBox combo) {
    super(combo);
  }

  @Override protected void configurePopup() {
    super.configurePopup();
    configureHeader();
    configureFooter();
    add(header, 0);
    add(footer);
  }

  protected void configureHeader() {
    header = new JLabel("History");
    header.setBorder(BorderFactory.createEmptyBorder(4, 5, 4, 0));
    header.setMaximumSize(new Dimension(Short.MAX_VALUE, 20));
    header.setAlignmentX(1f);
  }

  protected void configureFooter() {
    int modifiers = InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK;
    footer = new JMenuItem("Show All Bookmarks");
    footer.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, modifiers));
    footer.addActionListener(e -> {
      Window w = SwingUtilities.getWindowAncestor(getInvoker());
      JOptionPane.showMessageDialog(w, "Bookmarks");
    });
  }
}
View in GitHub: Java, Kotlin

解説

  • BasicComboPopupのデフォルトレイアウトマネージャーは垂直BoxLayout
    • BasicComboPopup#configurePopup()をオーバーライドしてドロップダウンリストとして使用されるJScrollPaneのほかにコンポーネントを追加可能
  • ヘッダとしてJLabelContainer#add(label, 0)BasicComboPopupの先頭に追加
    • JLabelBoxLayoutに左揃えで追加する場合JComponent#setMaximumSize(...)での最大サイズ、JComponent#setAlignmentX(...)x軸揃えの設定が必要
    • 参考: BoxLayoutでリスト状に並べる
  • フッタとしてJMenuItemBasicComboPopupの末尾に追加
    • JButtonを使用する場合マウスクリックでイベントが実行できない
    • JMenuItemを使用すればマウスクリック後にイベントが実行され、Acceleratorなどの設定も可能

参考リンク

コメント