概要

JPopupMenuに追加したJSliderの表示・非表示などを同じくJPopupMenuに追加したJCheckBoxJCheckBoxMenuItemを使用して切り替えます。

サンプルコード

private static void addCheckBoxMenuItemAndSlider(JComponent popup) {
  JMenuItem slider = makeBorderLayoutMenuItem();
  slider.add(makeSlider());

  JMenuItem mi = new JCheckBoxMenuItem("JCheckBoxMenuItem + JSlider");
  mi.addActionListener(e -> {
    AbstractButton b = (AbstractButton) e.getSource();
    slider.setVisible(b.isSelected());
    Container p = SwingUtilities.getAncestorOfClass(JPopupMenu.class, b);
    if (p instanceof JPopupMenu) {
      p.setVisible(true);
      ((JPopupMenu) p).pack();
    }
  });

  popup.add(mi);
  popup.add(slider);
}
View in GitHub: Java, Kotlin

解説

  • JCheckBox + JSlider + JMenuItem
    • テキストなどが空のJMenuItemBorderLayoutを設定してJCheckBoxと無効化したJSliderを追加し、JCheckBoxが選択されたらJSliderを有効化
    • JPopupMenu上でホイールを回転しても閉じないようMouseWheelListenerを追加してInputEvent#consume()でホイールイベントを消費
      • JPopupMenu#addMouseWheelListener(InputEvent::consume);
    • JSliderMouseWheelListenerを追加してホイールの回転で値を変更可能に設定し、InputEvent#consume()を実行して親コンポーネントにホイールイベントが伝わらないよう消費
  • JCheckBox + JSlider
    • JCheckBoxを追加したJMenuItemを作成し、非表示化したJSliderと並べてJPopupMenuなどに追加
    • JCheckBoxのクリックでJSliderの表示・非表示を切り替えるActionListenerを追加
      • JSliderの表示で親JPopupMenuのサイズを拡大、非表示で縮小するためこのActionListenerJPopupMenu#pack()を実行する必要がある
      • JMenuJSliderを追加している場合でもSwingUtilities.getAncestorOfClass(JPopupMenu.class, ...)で親JPopupMenuが取得可能
    • GTKLookAndFeelで使用する場合ノブ上に値を表示しないようUIManager.put("Slider.paintValue", Boolean.FALSE)を設定する必要がある
  • JCheckBoxMenuItem + JSlider

参考リンク

コメント