在两个JavaFX控制器之间传递参数

我想单击一列并将单元格索引发送到新阶段。 但是我无法将我的参数( int clickIndex )传递给另一个控制器EditClientController 。 我已经尝试了一切,但它仍然无法正常工作。

MainController

 package controller; 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.*; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.input.MouseEvent; import javafx.scene.text.Text; import javafx.stage.Stage; import javafx.util.Callback; import model.Table; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.net.URL; import java.util.ResourceBundle; public class MainController implements Initializable { @FXML TableView tableID; @FXML TableColumn iLp; @FXML TableColumn iCity; @FXML TableColumn iDeviceName; @FXML TableColumn iSerialNumber; @FXML TableColumn iCompanyName; @FXML TableColumn iContact; @FXML TableColumn iSellDate; @FXML TableColumn iWarranty; @FXML TableColumn iNextReview; @FXML TableColumn iWarrantyTrue; @FXML Button addButton; @FXML ComboBox warrantyLength; @FXML ComboBox nextReview; @FXML ComboBox warrantyTrue; //Define variables private int iNumber= 1; public int clickIndex; //Create table data ObservableList
data = FXCollections.observableArrayList(); //Combo box final ObservableList warranty = FXCollections.observableArrayList("---",12,24,36); final ObservableList review = FXCollections.observableArrayList("---","tydzień","miesiąc","2 miesiące", "6 miesięcy"); final ObservableList warrantyTF = FXCollections.observableArrayList("---","tak","nie"); Callback cellFactory2 = new Callback() { public TableCell call(TableColumn p) { final TableCell cell = new TableCell
() { @Override public void updateItem(Integer item, boolean empty) { super.updateItem(item, empty); setText(empty ? null : getString()); setGraphic(null); } private String getString() { return getItem() == null ? "" : getItem().toString(); } }; cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler() { @Override public void handle(MouseEvent event) { if (event.getClickCount() > 1) { clickIndex=cell.getIndex(); try { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("editClient.fxml")); Parent root1 = (Parent) fxmlLoader.load(); Stage stage = new Stage(); stage.setTitle("Edytuj klienta"); stage.setScene(new Scene(root1)); stage.show(); } catch(Exception e) { e.printStackTrace(); } } } }); return cell; } }; Callback cellFactory = new Callback() { public TableCell call(TableColumn p) { final TableCell cell = new TableCell
() { private Text text; @Override public void updateItem(String item, boolean empty) { super.updateItem(item, empty); text = new Text(item); text.setWrappingWidth(100); setGraphic(text); } private String getString() { return getItem() == null ? "" : getItem().toString(); } }; cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler() { @Override public void handle(MouseEvent event) { if (event.getClickCount() > 1) { clickIndex = cell.getIndex(); try { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("editClient.fxml")); Parent root1 = (Parent) fxmlLoader.load(); Stage stage = new Stage(); stage.setTitle("Edytuj klienta"); stage.setScene(new Scene(root1)); stage.show(); } catch(Exception e) { e.printStackTrace(); } } } }); return cell; } }; public void setClickedIndex(int click){ this.clickIndex=click; } public int getClickIndex(){ return clickIndex; } //Plik public void openFile() { FileReader plik = null; int tab0=1; int tab7=0; String tab9=null; try { plik = new FileReader("dane.txt"); } catch (FileNotFoundException e) { e.printStackTrace(); } BufferedReader bfr = new BufferedReader(plik); String linia = null; try { while ((linia = bfr.readLine()) != null) { String[] tab = linia.split(";"); tab7=Integer.parseInt(tab[7]); if(tab.length==10) { if(tab[9].contains(tab[8])){ tab9="Tak"; }else{ tab9="Nie"; } } Table tablica = new Table(tab0++, tab[1], tab[2], tab[3], tab[4], tab[5], tab[6], tab7, tab[8], tab9); data.add(tablica); } } catch (Exception e) { System.out.println("BŁĄD ODCZYTU Z PLIKU!"); System.exit(2); } try { plik.close(); } catch (IOException e) { System.out.println("BŁĄD PRZY ZAMYKANIU PLIKU!"); System.exit(3); } } public void setData(ObservableList
newData){ data=newData; } public ObservableList
getData(){ return data; } public void pressButton(ActionEvent event) throws Exception { try { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("addClient.fxml")); Parent root1 = (Parent) fxmlLoader.load(); Stage stage = new Stage(); stage.setTitle("Dodaj klienta"); stage.setScene(new Scene(root1)); stage.show(); } catch(Exception e) { e.printStackTrace(); } } @Override public void initialize(URL location, ResourceBundle resources) { openFile(); iLp.setCellValueFactory(new PropertyValueFactory
("rLp")); iCity.setCellValueFactory(new PropertyValueFactory
("rCity")); iDeviceName.setCellValueFactory(new PropertyValueFactory
("rDeviceName")); iSerialNumber.setCellValueFactory(new PropertyValueFactory
("rSerialNumber")); iCompanyName.setCellValueFactory(new PropertyValueFactory
("rCompanyName")); iContact.setCellValueFactory(new PropertyValueFactory
("rContact")); iSellDate.setCellValueFactory(new PropertyValueFactory
("rSellDate")); iWarranty.setCellValueFactory(new PropertyValueFactory
("rWarranty")); iNextReview.setCellValueFactory(new PropertyValueFactory
("rNextReview")); iWarrantyTrue.setCellValueFactory(new PropertyValueFactory
("rWarrantyTrue")); iLp.setCellFactory(cellFactory2); iCity.setCellFactory(cellFactory); iDeviceName.setCellFactory(cellFactory); iSerialNumber.setCellFactory(cellFactory); iCompanyName.setCellFactory(cellFactory); iContact.setCellFactory(cellFactory); iSellDate.setCellFactory(cellFactory); iWarranty.setCellFactory(cellFactory2); iNextReview.setCellFactory(cellFactory); iWarrantyTrue.setCellFactory(cellFactory); tableID.setItems(data); //comboboxy warrantyLength.setItems(warranty); warrantyLength.getSelectionModel().select(0); nextReview.setItems(review); nextReview.getSelectionModel().select(0); warrantyTrue.setItems(warrantyTF); warrantyTrue.getSelectionModel().select(0); } }

EditClientController

 package controller; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.ComboBox; import javafx.scene.control.TextField; import java.net.URL; import java.util.ResourceBundle; /** * Created by Krzysztof on 2015-01-14. */ public class EditClientController implements Initializable { @FXML ComboBox warrantyLength; @FXML TextField city; public int index; //Combo box dla okresu gwarancyjnego final ObservableList warranty = FXCollections.observableArrayList("---", 12, 24, 36); public void setIndex(int index){ this.index=index; } public int getIndex(){ return index; } @Override public void initialize(URL location, ResourceBundle resources) { // city.setText(tablica.get(index).getRCity()); warrantyLength.setItems(warranty); warrantyLength.getSelectionModel().select(0); } } 

如果你想在FXML文件中指定控制器(所以你不能使用Deepak的答案) 并且你想在initialize()方法中访问索引(所以你不能使用José的答案),你可以使用一个控制器厂:

 FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("editClient.fxml")); fxmlLoader.setControllerFactory(new Callback, Object>() { @Override public Object call(Class controllerClass) { if (controllerClass == EditClientController.class) { EditClientController controller = new EditClientController() controller.setIndex(clickIndex); return controller ; } else { try { return controllerClass.newInstance(); } catch (Exception exc) { throw new RuntimeException(exc); // just bail } } } }); Parent root1 = fxmlLoader.load(); 

您需要做的就是获取第二个控制器的实例:

 EditClientController controller=fxmlLoader.getController(); 

现在您将能够发送所需的索引:

 controller.setIndex(clickIndex); 

这就是所需要的:

  try { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("editClient.fxml")); Parent root1 = (Parent) fxmlLoader.load(); EditClientController controller=fxmlLoader.getController(); controller.setIndex(clickIndex); Stage stage = new Stage(); stage.setTitle("Edytuj klienta"); stage.setScene(new Scene(root1)); stage.show(); } catch(Exception e) { e.printStackTrace(); } 

编辑

由于clickIndex将在初始化第二个控制器发送因此初始化时该值不可用。

解决此问题的有效方法是为更改添加侦听器:

 private IntegerProperty index = new SimpleIntegerProperty(-1); public void setIndex(int index){ this.index.set(index); } public int getIndex(){ return index.get(); } @Override public void initialize(URL location, ResourceBundle resources) { index.addListener((ob,n,n1)->{ city.setText(tablica.get(n1.intValue()).getRCity()); }); } 

从一个控制器移动到另一个控制器(一个视图到另一个视图)时,可以使用所需参数初始化EditClientController

例如:

 FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("editClient.fxml")); EditClientController ctrl = new EditClientController(); ctrl.setCellIndex(id); fxmlLoader.setController(ctrl); 

如果您在fxml文件中指定了控制器,则可以使用:

 editWrapper.getCurrentController().setCellIndex(id); 

editControllerWrapper是一个加载新视图的类,它有一个方法getCurrentController,它返回一个javafx控制器的实例。

例如:public class EditControllerWrapper {

 private Parent root; public EditControllerWrapper () { try { FXMLLoader loader = new FXMLLoader(getClass().getResource("editClient.fxml"), ... } catch (Exception e) { ... } } public  T getCurrentController () { return loader.getController(); }