JavaFXツリービューにポップアップメニューを追加
ツリービューを選択したら、
ポップアップメニューを表示させるようにしました。
全てのツリーアイテムに同じメニューを追加する方法と、ツリーアイテムに応じてメニューを変更する方法のサンプルプログラムを載せています。
下の動画、左が同一メニュー、右が変更メニューです。
ツリービューに同一のポップアップメニューを追加する
まずは簡単な方から。TreeViewのどのTreeItemを選択しても同じメニューが表示されるように設定します。
選択はマウスの右クリックになります。
まず、TreeViewを定義します。
TreeItem<String>[] ti = new TreeItem[12];
ti[0] = new TreeItem<String>( "TOP" );
ti[1] = new TreeItem<String>( "部屋" );
ti[2] = new TreeItem<String>( "ボディ" );
ti[3] = new TreeItem<String>( "服" );
for(int i=1;i<4;i++){ ti[0].getChildren().add(ti[i]); }
ti[4] = new TreeItem<String>( "照明" );
ti[5] = new TreeItem<String>( "カメラ" );
ti[6] = new TreeItem<String>( "壁1" );
ti[7] = new TreeItem<String>( "壁2" );
ti[8] = new TreeItem<String>( "床" );
for(int i=4;i<9;i++){ ti[1].getChildren().add(ti[i]); }
ti[9] = new TreeItem<String>( "布" );
ti[10] = new TreeItem<String>( "身頃" );
ti[11] = new TreeItem<String>( "縫合" );
for(int i=9;i<12;i++){ ti[3].getChildren().add(ti[i]); }
TreeView<String> tree = new TreeView<String>( ti[0] );
次にPopupMenuを定義。
ContextMenu menu = new ContextMenu();
MenuItem[] menui = new MenuItem[4];
menui[0] = new MenuItem( "定義" );
menui[1] = new MenuItem( "抑制" );
menui[2] = new SeparatorMenuItem();
menui[3] = new MenuItem( "削除" );
menu.getItems().addAll( menui );
TreeViewにPopupMenuをセットすれば完了。
tree.setContextMenu( menu );
サンプルプログラム
動画左側のソースコードです。
package tomojavalib.fx;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.*;
import javafx.stage.Stage;
/**TreeViewにポップアップメニューを追加する*/
public class TreePopTest extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
stage.setTitle("TreeView試験");
TreeItem<String>[] ti = new TreeItem[12];
ti[0] = new TreeItem<String>( "TOP" );
ti[1] = new TreeItem<String>( "部屋" );
ti[2] = new TreeItem<String>( "ボディ" );
ti[3] = new TreeItem<String>( "服" );
for(int i=1;i<4;i++){ ti[0].getChildren().add(ti[i]); }
ti[4] = new TreeItem<String>( "照明" );
ti[5] = new TreeItem<String>( "
カメラ
楽天 " );
ti[6] = new TreeItem<String>( "壁1" );
ti[7] = new TreeItem<String>( "壁2" );
ti[8] = new TreeItem<String>( "床" );
for(int i=4;i<9;i++){ ti[1].getChildren().add(ti[i]); }
ti[9] = new TreeItem<String>( "布" );
ti[10] = new TreeItem<String>( "身頃" );
ti[11] = new TreeItem<String>( "縫合" );
for(int i=9;i<12;i++){ ti[3].getChildren().add(ti[i]); }
TreeView<String> tree = new TreeView<String>( ti[0] );
ti[0].setExpanded(true);
ContextMenu popup = createPopupMenu(tree);
tree.setContextMenu( popup );
FlowPane root = new FlowPane();
root.getChildren().add(tree);
stage.setScene(new Scene(root, 320, 240));
stage.show();
}
ContextMenu createPopupMenu(TreeView tree) {
ContextMenu menu = new ContextMenu();
MenuItem[] menui = new MenuItem[4];
menui[0] = new MenuItem( "定義" );
menui[1] = new MenuItem( "抑制" );
menui[2] = new SeparatorMenuItem();
menui[3] = new MenuItem( "削除" );
menu.getItems().addAll( menui );
for(int i=0;i<menui.length;i++){
menui[i].setOnAction((ActionEvent t) -> {
TreeItem selItem = (TreeItem) tree.getSelectionModel().getSelectedItem();
System.out.println( selItem.getValue() + " " + ((MenuItem)t.getSource()).getText() + " が選択されました。");
});
}
return menu;
}
}
選択したTreeItemに応じたPopupMenuを表示
TreeViewをあらかじめ作っておき、PopupMenuをリクエストされたときに、PopupMenuを作成して表示させます。
ポップアップメニューがリクエストされたときの処理。
tree.setOnContextMenuRequested((ContextMenuEvent event) -> {
popup.hide();
popup = createPopupMenu(tree);
popup.show(tree, event.getScreenX(), event.getScreenY());
event.consume();
});
PopupMenuの作成。選択されているTreeItemを調べて、Itemに応じたメニューを作ります。
ContextMenu createPopupMenu(TreeView tree) {
ContextMenu menu = new ContextMenu();
MenuItem[] menui =null;
String itemname = (String)((TreeItem) tree.getSelectionModel().getSelectedItem()).getValue();
if(itemname.equals("カメラ")){
menui = new MenuItem[1];
menui[0] = new MenuItem( "定義" );
}else if(itemname.equals("照明")){
menui = new MenuItem[2];
menui[0] = new MenuItem( "定義" );
menui[1] = new MenuItem( "消灯" );
}else {
menui = new MenuItem[4];
menui[0] = new MenuItem( "定義" );
menui[1] = new MenuItem( "抑制" );
menui[2] = new SeparatorMenuItem();
menui[3] = new MenuItem( "削除" );
}
menu.getItems().addAll( menui );
return menu;
}
ポップアップメニューを開いて、選択せずに再びTreeItemを選択すると、たくさんポップアップメニューが開いてしまいます。
そこで、選択表示させる前に古いメニューを消しています。また、マウスクリック時にもメニューを消すようにしています。
サンプルプログラム
右側の動画ののソースコードです。
package tomojavalib.fx;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.stage.Stage;
/**TreeViewにポップアップメニューを追加する*/
public class TreePopTest2 extends Application {
ContextMenu popup =null;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
stage.setTitle("TreeView試験2");
TreeItem<String>[] ti = new TreeItem[12];
ti[0] = new TreeItem<String>( "TOP" );
ti[1] = new TreeItem<String>( "部屋" );
ti[2] = new TreeItem<String>( "ボディ" );
ti[3] = new TreeItem<String>( "服" );
for(int i=1;i<4;i++){ ti[0].getChildren().add(ti[i]); }
ti[4] = new TreeItem<String>( "照明" );
ti[5] = new TreeItem<String>( "カメラ" );
ti[6] = new TreeItem<String>( "壁1" );
ti[7] = new TreeItem<String>( "壁2" );
ti[8] = new TreeItem<String>( "床" );
for(int i=4;i<9;i++){ ti[1].getChildren().add(ti[i]); }
ti[9] = new TreeItem<String>( "布" );
ti[10] = new TreeItem<String>( "身頃" );
ti[11] = new TreeItem<String>( "縫合" );
for(int i=9;i<12;i++){ ti[3].getChildren().add(ti[i]); }
TreeView<String> tree = new TreeView<String>( ti[0] );
ti[0].setExpanded(true);
popup = new ContextMenu();
//ポップアップメニューがリクエストされた場合の処理
tree.setOnContextMenuRequested((ContextMenuEvent event) -> {
popup.hide();
popup = createPopupMenu(tree);
popup.show(tree, event.getScreenX(), event.getScreenY());
event.consume();
});
//マウスクリックの場合、ポップアップメニューを不可視にする
tree.setOnMouseClicked((MouseEvent event) -> { popup.hide(); });
FlowPane root = new FlowPane();
root.getChildren().add(tree);
stage.setScene(new Scene(root, 320, 240));
stage.show();
}
/**選択されたツリーアイテムに合わせてメニューを作成する*/
ContextMenu createPopupMenu(TreeView tree) {
ContextMenu menu = new ContextMenu();
MenuItem[] menui =null;
String itemname = (String)((TreeItem) tree.getSelectionModel().getSelectedItem()).getValue();
if(itemname.equals("カメラ")){
menui = new MenuItem[1];
menui[0] = new MenuItem( "定義" );
}else if(itemname.equals("照明")){
menui = new MenuItem[2];
menui[0] = new MenuItem( "定義" );
menui[1] = new MenuItem( "消灯" );
}else {
menui = new MenuItem[4];
menui[0] = new MenuItem( "定義" );
menui[1] = new MenuItem( "抑制" );
menui[2] = new SeparatorMenuItem();
menui[3] = new MenuItem( "削除" );
}
menu.getItems().addAll( menui );
for(int i=0;i<menui.length;i++){
menui[i].setOnAction((ActionEvent t) -> {
TreeItem selItem = (TreeItem) tree.getSelectionModel().getSelectedItem();
System.out.println( selItem.getValue() + " " + ((MenuItem)t.getSource()).getText() + " が選択されました。");
});
}
return menu;
}
}
最終更新日: 2017-04-10 11:22:21