JavaFX 2.2 画面遷移時の値受け渡し。Controllerさん、どうぞ。
こんな感じ。
public static finalで渡す よりいいと思うけれど、果たしてこれが画面遷移時の正解なのか??
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("fxml/UpdateScreen.fxml")); Scene scene = new Scene((Parent) fxmlLoader.load());// initialize が呼ばれる // ロードしたFXMLファイルに関連づくControllerを取得 final UpdateScreenController controller = (UpdateScreenController) fxmlLoader.getController(); // Controllerさん、どうぞ。 controller.setId(customer.getId());
Controller側にSetterを用意しておきます。
public class UpdateScreenController implements Initializable { // (中略) /** * 更新対象CustomerのId * * @see Customer */ private Integer id; public void setId(Integer i) { id = i; } }
JavaFX 2.2 FXML利用時のController取得方法
こんな感じ。
Controller取得前にFXMLファイルをロード(fxmlLoader.load())しているのがポイント。
順番が逆だと取得できない。
// FXMLファイルをロード FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("fxml/AlertScreen.fxml")); Scene scene = new Scene((Parent) fxmlLoader.load()); stage.setScene(scene); // ロードしたFXMLファイルに関連づくControllerを取得 final AlertScreenController controller = (AlertScreenController) fxmlLoader.getController();
JavaFX 2.2 TableView プロパティの変更が反映されない
TableView を使っていて困ったのが、データ行追加はイベントとして認識されるけれどプロパティ(Customer.firstName 等)が変更されてもTableViewが更新されないこと。
検索ボタン押下時処理に
こんなんとか
tableView.getItems().clear(); List<Customer> cList = CustomerAccess.selectAll(); tableView.getItems().addAll(cList);
こんなんとか
List<Customer> cList = CustomerAccess.selectAll(); ObservableList<Customer> oList = FXCollections.observableArrayList(cList); tableView.setItems(oList);
書いても初回の検索結果が表示されたまま。
Debug実行でcListの中身を見ると変更後の値がとれているのに、それがTableViewに反映されない。
http://javafx-jira.kenai.com/browse/RT-22599
を参考に
tableView.layout();
を挟んだらいけました。ふー。
JavaFX 2.2 TableViewに単一選択のラジオボタン列を表示
見よう見まねで作ったけれど、お作法というか、やり方というか、合ってるのかしらん?
一覧画面から編集画面を開き、編集画面が閉じたタイミングで一覧画面にて再検索します。
package dbaccesstest; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ResourceBundle; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.RadioButton; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.ToggleGroup; import javafx.scene.layout.AnchorPane; import javafx.stage.Modality; import javafx.stage.Stage; import javafx.stage.WindowEvent; import javafx.util.Callback; /** * 一覧画面 Controller * * @author denko */ public class SearchScreenController implements Initializable { @FXML private TableView tableView; @FXML private TableColumn selectColumn; @FXML private AnchorPane rootPane; @Override public void initialize(URL url, ResourceBundle rb) { tableView.setEditable(true); Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>() { @Override public TableCell call(TableColumn p) { return new RadioButtonCell(); } }; selectColumn.setCellFactory(cellFactory); // TableViewをデータ0件で初期化 ObservableList<Customer> oList = FXCollections.observableArrayList(new ArrayList<Customer>()); tableView.setItems(oList); } /** * 検索ボタン押下時処理 * * @param event */ @FXML private void handleSearchButtonAction(ActionEvent event) { search(); } /** * 顧客情報一覧検索処理 */ private void search() { tableView.getItems().clear(); tableView.layout();// reflesh代わり http://javafx-jira.kenai.com/browse/RT-22599 List<Customer> cList = CustomerAccess.selectAll(); tableView.getItems().addAll(cList); } /** * 編集ボタン押下時処理 * * @param event * @throws IOException */ @FXML private void handleEditButtonAction(ActionEvent event) throws IOException { Customer selectedCustomer = null; final ObservableList<Customer> items = tableView.getItems(); for (Iterator<Customer> it = items.iterator(); it.hasNext();) { Customer customer = it.next(); final Boolean selected = customer.getSelected(); if (selected != null && selected) { selectedCustomer = customer; break; } } if (selectedCustomer == null) { showAlertStage("顧客情報が選択されていません。"); } else { showUpdateStage(selectedCustomer); } } /** * アラート画面表示処理 * * @param message * @throws IOException */ private void showAlertStage(String message) throws IOException { Stage stage = new Stage(); // FXMLファイルをロード FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("fxml/AlertScreen.fxml")); Scene scene = new Scene((Parent) fxmlLoader.load()); stage.setScene(scene); // ロードしたFXMLファイルに関連づくControllerを取得 final AlertScreenController controller = (AlertScreenController) fxmlLoader.getController(); controller.setMessageText(message); stage.showAndWait(); } /** * 編集画面表示処理 * * @param customer * @throws IOException */ private void showUpdateStage(Customer customer) throws IOException { // 次画面をモーダルで起動 Stage newStage = new Stage(); // モーダルで開いてみる newStage.initModality(Modality.APPLICATION_MODAL); newStage.initOwner(rootPane.getScene().getWindow()); // FXMLファイルをロード FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("fxml/UpdateScreen.fxml")); Scene scene = new Scene((Parent) fxmlLoader.load());// initialize が呼ばれる // ロードしたFXMLファイルに関連づくControllerを取得 final UpdateScreenController controller = (UpdateScreenController) fxmlLoader.getController(); controller.setId(customer.getId()); newStage.setScene(scene); newStage.setOnShowing(new EventHandler<WindowEvent>() { @Override public void handle(WindowEvent t) { // 画面が開いたことをControllerに通知 controller.onShown(); } }); // closeで閉じるとHiddenイベントが発生する // http://stackoverflow.com/questions/10212366/javafx-2-0-closing-a-stage-window newStage.setOnHidden(new EventHandler<WindowEvent>() { @Override public void handle(WindowEvent t) { // 編集画面終了時に自画面の再検索を行う search(); } }); // 新しいウインドウを表示 newStage.show(); } /** * RadioButtonCell用ラジオボタングループ */ final ToggleGroup group = new ToggleGroup(); /** * RadioButton型のTableCell */ class RadioButtonCell extends TableCell<Customer, Boolean> { private RadioButton radio; public RadioButtonCell() { createRadioButton(); } /** * ラジオボタン生成。 * <p> * ラジオボタングループに登録する */ private void createRadioButton() { radio = new RadioButton(); radio.focusedProperty().addListener(new ChangeListener<Boolean>() { @Override public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) { if (!arg2) { commitEdit(radio.isSelected()); } } }); radio.setToggleGroup(group); } @Override public void commitEdit(Boolean t) { super.commitEdit(t); final ObservableList<Customer> items = getTableView().getItems(); for (int i = 0; i < items.size(); i++) { Customer customer = items.get(i); if (i == getIndex()) { customer.setSelected(t); } else { customer.setSelected(Boolean.FALSE); } } } @Override public void updateItem(Boolean item, boolean empty) { super.updateItem(item, empty); // データが存在する行のみラジオボタン表示 // 引数のemptyは初期表示時全てfalseなのでこんな方法を採択 final ObservableList<Customer> items = getTableView().getItems(); if (items != null) { if (getIndex() < items.size()) { setGraphic(radio); } } } } }