2016-03-05

JavaFX: TreeView と ContextMenu (1)

JavaFX の TreeView のツリー項目を右クリックすると、ポップアップ・メニュー (ContextMenu) が表示されるサンプルを、二回に亘って紹介します。今回は ListView で紹介した方法 [1] と同じです。なお、今回紹介するサンプルでは、[2] のサイトで掲載されている素材を 32 x 32 に縮小して利用させていただきました。

動作環境は次の通りです。

  • OS: Fedora 23 (x86_64)
  • Java: jdk1.8.0_74-1.8.0_74-fcs.x86_64 (Oracle)
  • IDE: NetBeans IDE 8.1
リスト:Sample_TreeView.java 
package sample_treeview;

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.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Sample_TreeView extends Application {

    Image CAROT = new Image(getClass().getResource("carot.png").toString());
    Image EGGPLANT = new Image(getClass().getResource("eggplant.png").toString());
    Image TOMATO = new Image(getClass().getResource("tomato.png").toString());
    Image APPLE = new Image(getClass().getResource("apple.png").toString());
    Image GRAPE = new Image(getClass().getResource("grape.png").toString());
    Image BANANA = new Image(getClass().getResource("banana.png").toString());

    @Override
    public void start(Stage primaryStage) {

        TreeItem<String> top = new TreeItem<>("root");

        TreeItem<String> nodeItemA = new TreeItem<>("野菜");
        addNode(top, nodeItemA);
        nodeItemA.setExpanded(true);
        TreeItem<String> nodeItemB = new TreeItem<>("果物");
        addNode(top, nodeItemB);
        nodeItemB.setExpanded(true);

        TreeItem<String> nodeItemA1 = new TreeItem<>("にんじん", new ImageView(CAROT));
        addNode(nodeItemA, nodeItemA1);
        TreeItem<String> nodeItemA2 = new TreeItem<>("なす", new ImageView(EGGPLANT));
        addNode(nodeItemA, nodeItemA2);
        TreeItem<String> nodeItemA3 = new TreeItem<>("とまと", new ImageView(TOMATO));
        addNode(nodeItemA, nodeItemA3);

        TreeItem<String> nodeItemB1 = new TreeItem<>("りんご", new ImageView(APPLE));
        addNode(nodeItemB, nodeItemB1);
        TreeItem<String> nodeItemB2 = new TreeItem<>("ぶどう", new ImageView(GRAPE));
        addNode(nodeItemB, nodeItemB2);
        TreeItem<String> nodeItemB3 = new TreeItem<>("ばなな", new ImageView(BANANA));
        addNode(nodeItemB, nodeItemB3);

        ContextMenu popup = new ContextMenu();
        TreeView<String> tree = new TreeView<>(top);
        tree.setShowRoot(false);
        tree.setContextMenu(popup);
        createPopupMenu(popup, tree);

        StackPane root = new StackPane();
        root.getChildren().add(tree);

        Scene scene = new Scene(root, 200, 300);

        primaryStage.setTitle(getClass().getSimpleName());
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    void addNode(TreeItem<String> parent, TreeItem<String> child) {
        parent.getChildren().add(child);
    }

    void createPopupMenu(ContextMenu menu, TreeView tree) {
        MenuItem item = new MenuItem("処理");
        item.setOnAction((ActionEvent t) -> {
            TreeItem selItem = (TreeItem) tree.getSelectionModel().getSelectedItem();
            System.out.println("「" + selItem.getValue() + "」が選択されました。");
        });
        menu.getItems().add(item);
    }

    public static void main(String[] args) {
        launch(args);
    }
}

実行例を以下に示します。

「野菜」が選択されました。
「にんじん」が選択されました。
「果物」が選択されました。
「なす」が選択されました。
「ぶどう」が選択されました。

問題点

ListView の項目に対しては、同一のポップアップ・メニューを表示させることができれば用が足りましたが、TreeView の場合は事情が少し違います。もちろん、今回紹介したようなポップアップメニューで十分な場合もあるのかもしれませんが、大抵の場合、各ノード(項目)の階層(レベル)によって、ポップアップ・メニューの表示内容を変えたり、あるいはレベルごとに表示/非表示を変えたい場合が多いのではないでしょうか。

次回は、TreeItem に ContextMenu を関連付けてポップアップ・メニューを表示させるサンプルを紹介する予定です。

参考サイト

  1. bitWalk's: 【備忘録】ListView にポップアップメニューをつける - JavaFX
  2. 野菜・果物アイコン 画像フリー素材集|無料素材倶楽部

 

0 件のコメント: