2016-01-10

【備忘録】ListView にポップアップメニューをつける - JavaFX

JavaFX の ListView の各アイテムを右クリックしてポップアップメニューを表示させるのにはどうすればいいんだろうとあれこれ試してみましたがうまくいきません。ポップアップメニューは ContextMenu クラスを利用するとして、ListView のアイテムに表示するには…。

たまたま ListView のアイテムが凝ったオブジェクトだったこともあり、このアイテムにバインディングすることを意識しすぎて、解に近づけませんでした。参考サイト [1] を見つけて唖然、どうせ座標計算をするのだから ListView に処理をバインディングすれば良かったのでした。

ということで、備忘録として簡単なサンプルを紹介します。

動作環境

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

  • OS: Fedora 23 x86_64
  • jdk1.8.0_66-1.8.0_66-fcs.x86_64 (Oracle)
  • IDE: NetBeans IDE 8.1

Sample_ListView クラス

リスト:Sample_ListView.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package sample_listview;
 
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.ListView;
import javafx.scene.control.MenuItem;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
 
public class Sample_ListView extends Application {
 
    List<Pref> pref = new ArrayList<>();
    ObservableList<Pref> observableList = FXCollections.observableList(pref);
 
    @Override
    public void start(Stage primaryStage) {
        pref.add(new Pref("青森県", "青森市", "青森県青森市長島一丁目1番1号"));
        pref.add(new Pref("岩手県", "盛岡市", "岩手県盛岡市内丸10番1号"));
        pref.add(new Pref("宮城県", "仙台市", "宮城県仙台市青葉区本町3丁目8番1号"));
        pref.add(new Pref("秋田県", "秋田市", "秋田県秋田市山王四丁目1番1号"));
        pref.add(new Pref("山形県", "山形市", "山形県山形市松波2丁目8番1号"));
        pref.add(new Pref("福島県", "福島市", "福島県福島市杉妻町2番16号"));
        pref.add(new Pref("茨城県", "水戸市", "茨城県水戸市笠原町978番地6"));
 
        // popup menu
        ContextMenu popup = new ContextMenu();
 
        // prefecture list UI
        ListView<Pref> lv = new ListView<>(observableList);
        lv.setPrefHeight(150);
        lv.setPrefWidth(150);
        lv.setContextMenu(popup);
        lv.setOnContextMenuRequested((ContextMenuEvent event) -> {
            popup.show(lv, event.getScreenX(), event.getScreenY());
            event.consume();
        });
 
        MenuItem itemCapital = new MenuItem("県庁所在地");
        itemCapital.setOnAction((ActionEvent t) -> {
            Pref selected = lv.getSelectionModel().getSelectedItem();
            System.out.println(selected.getPrefecture() + "の県庁所在地は、" + selected.getCapital() + "です。");
        });
 
        MenuItem itemAddress = new MenuItem("住所");
        itemAddress.setOnAction((ActionEvent t) -> {
            Pref selected = lv.getSelectionModel().getSelectedItem();
            System.out.println(selected.getPrefecture() + "の県庁の住所は、" + selected.getAddress() + "です。");
        });
 
        popup.getItems().addAll(itemCapital, itemAddress);
 
        StackPane root = new StackPane();
        root.getChildren().add(lv);
 
        Scene scene = new Scene(root);
 
        primaryStage.setTitle("Sample_ListView");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
 
    class Pref {
 
        String prefecture;
        String capital;
        String address;
 
        public Pref(String prefecture, String capital, String address) {
            this.prefecture = prefecture;
            this.capital = capital;
            this.address = address;
        }
 
        public void setPrefecture(String prefecture) {
            this.prefecture = prefecture;
        }
 
        public String getPrefecture() {
            return prefecture;
        }
 
        public void setCapital(String capital) {
            this.capital = capital;
        }
 
        public String getCapital() {
            return capital;
        }
 
        public void setAddress(String address) {
            this.address = address;
        }
 
        public String getAddress() {
            return address;
        }
 
        @Override
        public String toString() {
            return prefecture;
        }
    }
 
    public static void main(String[] args) {
        launch(args);
    }
}

実行例

宮城県の県庁所在地は、仙台市です。
宮城県の県庁の住所は、宮城県仙台市青葉区本町3丁目8番1号です。

 

参考サイト

  1. JavaFX: create a ContextMenu on a ListView – Das JAVA-Hilfe Blog und mehr

0 件のコメント: