JPopupMenuのMenuItemとしてJSpinnerを配置する
Total: 426, Today: 1, Yesterday: 0
Posted by aterai at
Last-modified:
Summary
JPopupMenuのMenuItemとしてMenuElementを実装しないJSpinnerやJSliderなどのコンポーネントを使用します。
Screenshot

Advertisement
Source Code Examples
private static Component makeSpinnerMenuItem(String title, Component c) {
JMenuItem item = new JMenuItem() {
@Override public void updateUI() {
super.updateUI();
setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
setEnabled(false);
setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0));
}
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = Math.max(d.height, c.getPreferredSize().height);
return d;
}
};
item.add(new JLabel(title));
item.add(c);
return item;
}
private static JMenu makeSpinnerMenu() {
SpinnerNumberModel model1 = new SpinnerNumberModel(100, 10, 300, 10);
SpinnerNumberModel model2 = new SpinnerNumberModel(150, 10, 300, 10);
JMenu menu = new JMenu("JSpinner");
menu.add(makeMenuBox("L: ", makeSpinner(model1)));
menu.add(makeMenuBox("R: ", makeSpinner(model2)));
menu.add(new JSeparator());
menu.add(makeSpinnerMenuItem("Left: ", makeSpinner(model1)));
menu.add(makeSpinnerMenuItem("Right: ", makeSpinner(model2)));
menu.addSeparator();
menu.add("JMenuItem1");
menu.add("JMenuItem2");
menu.add(Box.createHorizontalStrut(160));
return menu;
}
private static JSpinner makeSpinner(SpinnerModel model) {
JSpinner spinner = new JSpinner(model);
((JSpinner.DefaultEditor) spinner.getEditor()).getTextField().setColumns(8);
spinner.addMouseWheelListener(e -> {
JSpinner s = (JSpinner) e.getComponent();
SpinnerModel o = s.getModel();
if (s.isEnabled() && o instanceof SpinnerNumberModel) {
SpinnerNumberModel m = (SpinnerNumberModel) o;
m.setValue(m.getNumber().intValue() - e.getWheelRotation());
}
e.consume();
});
return spinner;
}
View in GitHub: Java, KotlinDescription
JSpinnerメニュー上:Box.createHorizontalBox()にタイトル表示用のJLabelとJSpinnerを配置してJMenu#add(...)でJPopupMenuに配置MenuElementを実装しないコンポーネントなので↑キー入力などでのメニュー選択などは不可だが、JSpinner自体のマウス入力での操作やTabキー入力によるフォーカス移動は可能
JSpinnerメニュー下: 無効化したJMenuItemのタイトルを空、かつ右寄せのFlowLayoutを設定し、別途タイトル表示用のJLabelとJSpinnerを配置してJMenu#add(...)でJPopupMenuに配置MenuElementを実装するJMenuItemなので↑キー入力などでのメニュー選択が可能で、かつJSpinner自体のマウス入力での操作やTabキー入力によるフォーカス移動も可能- 無効化した
JMenuItemの選択状態表示はDisabledなJMenuItemのハイライトをテストのようにLookAndFeelに依存する JSpinnerに追加したMouseWheelListenerでホイール回転による値の変更も可能Java 8ではJSpinnerやJMenuItem上でホイールを回転するとJPopupMenuが閉じてしまうのでJPopupMenuに追加したJSliderの表示・非表示をチェックボックスで切り替えるのようにホイールイベントを消費するMouseWheelListenerを追加する必要があったが、Java 9では修正されて不要になった
- 無効化した
JMenuItemでクリックしてもJPopupMenuを閉じないよう設定するのではなく、選択アイコンを非表示化したJCheckBoxMenuItemにputClientProperty("CheckBoxMenuItem.doNotCloseOnMouseClick", true)を設定して使用する方法もJava 9以降では可能
JSliderメニュー- 同様に
JSliderを配置して使用も可能 - JPopupMenuに追加したJSliderの表示・非表示をチェックボックスで切り替える
- 同様に
- 同様にマウスクリック可能な
JButtonを無効化したJMenuItemに配置して使用も可能 - マウスクリックは無効でマウスドラッグのみ可能な
JLabelを配置することも可能 JComboBoxも配置可能だがJComboBoxのドロップダウンリストが開くとその親のJPopupMenuが閉じてしまうJMenuItemの代わりにJScrollPaneにJListを配置してスクロール可能なメニューにすることも可能
Reference
- JPopupMenuのレイアウトを変更して上部にメニューボタンを追加する
- JPopupMenuに追加したJSliderの表示・非表示をチェックボックスで切り替える
- JPopupMenuにマウスドラッグで位置変更を可能にするヘッダを追加する
- JMenuのJPopupMenuにスクロール可能なJListを配置する