質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

1642閲覧

javaFX tableViewのイベントハンドラについて

noct

総合スコア8

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/09/20 04:25

親ウィンドウの名前列のいずれかを選択してる状態でF3キーを入力後子ウィンドウが表示、その子ウィンドウのテキストフィールドに値を入力(文字列、数字何でも可)後OKボタンを押下すると子ウィンドウが閉じ、親ウィンドウの選択していたセルの表記がテキストフィールドで入力された値に切り替わる。というプログラムを作成中です。 ```package sample; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.stage.Stage; import java.io.IOException; import java.net.URL; import java.util.ResourceBundle; public class Controller implements Initializable{ @FXML private TableView<Person> tableView; @FXML private TableColumn firstName; @FXML private TableColumn<Person,String> lastName; @FXML private TableColumn email; @Override public void initialize(URL location, ResourceBundle resources) { //セルの編集を許可する処理(一先ず必要ないのでコメアウト) //Callback<TableColumn<Person,String>,TableCell<Person,String>> //lastNameFactory = TextFieldTableCell.forTableColumn(); //lastName.setCellFactory(lastNameFactory); //単一セルの選択の有効化 tableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); tableView.getSelectionModel().setCellSelectionEnabled(true); //名前列のデータ行のセルの配色変更(sample.css) lastName.setCellFactory(TableColumn -> new TableCell<Person, String>(){ //セルに変更があった場合呼ばれるupdateItemメソッドを利用する public void updateItem(String item,boolean empty){ super.updateItem(item,empty); if(empty || item == null){ setText(null); setGraphic(null); }else{ setText(item); getStyleClass().add("tableCellClass"); } } }); //選択状態を検知するバインディングの設定 tableView.getSelectionModel().selectedItemProperty().addListener((ov,old,current)-> { //どこが選択されてるか確認用出力 System.out.println( "選択セル(TableView)" ); //選択セルの取得処理 for (TablePosition pos : tableView.getSelectionModel().getSelectedCells()) { //選択行、列の取得 int row = pos.getRow(); TableColumn lastName = pos.getTableColumn(); Person item = tableView.getItems().get(row); String selected = (String) lastName.getCellObservableValue(item).getValue(); } }); } //キーイベント処理(F3) 名前カラム選択時 public void onGetfanc(KeyEvent keyEvent) throws IOException { //Person.setLastName(lastName.getText()); tableView.setOnKeyPressed((KeyEvent event) ->{ if(event.getCode() == KeyCode.F3){ //if(se)); try { Stage stage = new Stage(); Parent root = FXMLLoader.load(getClass().getResource("lastName.fxml")); Scene scene = new Scene(root); stage.setScene(scene); stage.setTitle("名前入力画面"); stage.showAndWait(); } catch (IOException e) { e.printStackTrace(); } } //tableView.setItems(Person); }); } } FXMLファイル <?xml version="1.0" encoding="UTF-8"?> <?import javafx.collections.FXCollections?> <?import javafx.geometry.Insets?> <?import javafx.scene.control.cell.PropertyValueFactory?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <?import sample.Person?> <?import java.net.URL?> <GridPane alignment="center" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller"> <padding> <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> </padding> <Label style="-fx-font:NORMAL 20 Tahoma;" text="アドレス帳" GridPane.columnIndex="0" GridPane.rowIndex="0"> </Label> <TableView fx:id="tableView" editable="true" onKeyPressed="#onGetfanc" GridPane.columnIndex="0" GridPane.rowIndex="1"> <columns> <!-- TableCollumクラスを利用して、データを表示する為の列を追加 --> <TableColumn text="名字"> <!-- 列ごとにセル・ファクトリを指定して、データを列に関連付ける --> <cellValueFactory> <!-- PropertyValueFactoryクラスを使用することでセル・ファクトリは実装 --> <!-- Personクラスの対応するメソッドへの参照として表の列のプロパティを使用する --> <PropertyValueFactory property="firstName" /> </cellValueFactory> </TableColumn> <TableColumn fx:id="lastName" text="名前"> <cellValueFactory> <PropertyValueFactory property="lastName" /> </cellValueFactory> </TableColumn> <TableColumn text="メールアドレス"> <cellValueFactory> <PropertyValueFactory property="email"/> </cellValueFactory> </TableColumn> </columns> <items> <!-- データの行を定義して、そのデータを表の列に関連付ける --> <FXCollections fx:factory="observableArrayList"> <Person firstName="Jacob" lastName="aa" email="aaaa.aa@aaaa.aa"/> <Person firstName="Isabella" lastName="bb" email="bbbb.bb@bbbb.bb"/> <Person firstName="Ethan" lastName="cc" email="cccc.cc@cccc.cc"/> <Person firstName="Michael" lastName="dd" email="dddd.dd@dddd.dd"/> </FXCollections> </items> </TableView> <stylesheets> <URL value="@sample.css" /> </stylesheets> <columnConstraints> <ColumnConstraints /> </columnConstraints> <rowConstraints> <RowConstraints /> <RowConstraints /> </rowConstraints> </GridPane>

###試したこと
選択状態の検知をするバインディングは僕なりに記述をしてみたつもりです。
僕自身は後キータイプ処理のイベントハンドラをどうするか。という部分なのですが、列指定の情報を受取りイベントハンドラを起動する。というif文の記述方法が分かりません。説明下手で申し訳ないですが、ご教授して頂けたら幸いです。

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

キータイプ処理のイベントハンドラをどうするか

元のコードではStageを作成してFXMLLoaderでlastName.fxmlをロードして・・・という方法を想定しておられますが、単にTextInputDialogを用いた方が簡単です。元のコードのように自前でダイアログを実装するのでもよいのですが、モーダルにしたり、OKを押したかキャンセルしたかや、入力結果を得るためのインターフェースを設けたコントローラーを実装したりと若干面倒くさいことをしなければなりません。TextInputDialogを用いればそのような面倒なことをしなくてもshowAndWaitの戻り値をチェックすることで簡単にユーザー入力を実現できますので本回答ではTextInputDialogを用いた例としました。
ちなみにonKeyfancの中でsetOnKeyPressedを用いていますが、ここでハンドラーを登録するのは不適切(不要)と思います。以下の回答例を参照ください。

選択状態の検知をするバインディングは僕なりに記述をしてみたつもりです。

これは選択状態の変化を自前で監視している点を指していると思いますが、それは必要ないと思います。'F3'キー押下時のイベントハンドラーの方で、「lastNameが選択されているかどうか」をTableViewSelectionModelを通じて容易にチェックできますし、わざわざ選択状態の変更を監視する意義はなさそうです。

実装は概ね次のようになると思います。

java

1@FXML 2private void onGetFunc(KeyEvent event) { 3 if (event.getCode() == KeyCode.F3) { 4 editSelectedLastName(); 5 } 6} 7 8private void editSelectedLastName() { 9 TableView.TableViewSelectionModel<Person> sm = tableView.getSelectionModel(); 10 int index = sm.getSelectedIndex(); 11 if (index == -1) { 12 // 選択されているセルがなければ何もしない 13 return; 14 } 15 if (!sm.isSelected(index, lastName)) { 16 // 選択セルが名字でなければ何もしない 17 return; 18 } 19 20 Person person = sm.getSelectedItem(); 21 TextInputDialog dialog = new TextInputDialog(person.getLastName()); 22 dialog.setTitle("名字入力画面"); 23 Optional<String> result = dialog.showAndWait(); 24 if (result.isPresent()) { 25 person.setLastName(result.get().trim()); 26 } 27}

なお・・・

  • GetKeyfanc

FXML上でonKeyPressedのハンドラーとしてこのメソッドが定義されてますが、メソッドのシグナチャーが@FXMLなしのpublicになっています。回答コードではおそらく一般的な定義方法と思えるので@FXMLありのprivateとしています。またメソッド名はtypoのような気がしたので、GetKeyFuncという名称に変えています。FXML上のハンドラー定義がonKeyPressed="#onGetFunc"となっている前提です。

  • 名前と名字

親ウィンドウの名前列のいずれかを選択してる状態でF3キーを入力後

元のFXML定義をみると「名前=lastName、名字=firstName」になっていますが本来は逆ですね?回答コードでは「lastName=名字」とし、ダイアログのタイトルを「名字入力画面」としています。

投稿2017/09/25 04:53

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

noct

2017/09/26 06:48

親切な回答有難う御座います。 TextInputDialogを利用すれば簡単に実装出来るという事知れました。 僕自身簡単な処理方法というよりオブジェクト指向の概念も交えて処理出来たらなと考えていたのであの様な方法を使っていたのですが、ここまで簡単に実装が出来るとなるとオブジェクトに拘らない方が簡潔になりますね。 一つの事に拘らず幅広く組み立てられるようにしていきたいと思います。 有難う御座いました。
KSwordOfHaste

2017/09/26 08:16

> 簡単な処理方法というよりオブジェクト指向の概念も交えて処理出来たらなと考えていた 自前でStage+FXMLで実装するかTextInputDialogを用いるかについては、オブジェクト指向あるいはJavaFXの練習として前者で実装してみるというのは無駄ではないと思います。実際TextInputDialogを利用可能なのはごく単純な入力でよい場合だけであり、多少なりとも複雑なダイアログにしたい場合はDialog/DialogPaneあるいはStage+FXMLによる実装が必要になります。 最初はなるべく単純な機能にし、できあいのクラスをうまく利用しつつ、JavaFXに慣れていくにつれてより複雑で応用的な実装に挑戦してみるとよいかも知れません。例えばTextInputDialogと同様のものを自前で実装してみるとJavaFXの仕組みを知る上でも有効な練習になると思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問