java 在两个 JavaFX 控制器之间传递参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27965401/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing parameters between two JavaFX controllers
提问by Kertt123
I want to click a column and send the cell index to a new stage. But I can't pass my parameter (int clickIndex
) to another controller EditClientController
. I've tried everything, but it still does not work.
我想单击一列并将单元格索引发送到新阶段。但是我不能将我的参数 ( 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<Table> 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<Table> 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<TableColumn, TableCell> cellFactory2 =
new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
final TableCell cell = new TableCell<Table, Integer>() {
@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<MouseEvent>() {
@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<TableColumn, TableCell> cellFactory =
new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
final TableCell cell = new TableCell<Table, String>() {
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<MouseEvent>() {
@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<Table> newData){
data=newData;
}
public ObservableList<Table> 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<Table, Integer>("rLp"));
iCity.setCellValueFactory(new PropertyValueFactory<Table, String>("rCity"));
iDeviceName.setCellValueFactory(new PropertyValueFactory<Table, String>("rDeviceName"));
iSerialNumber.setCellValueFactory(new PropertyValueFactory<Table, String>("rSerialNumber"));
iCompanyName.setCellValueFactory(new PropertyValueFactory<Table, String>("rCompanyName"));
iContact.setCellValueFactory(new PropertyValueFactory<Table, String>("rContact"));
iSellDate.setCellValueFactory(new PropertyValueFactory<Table, String>("rSellDate"));
iWarranty.setCellValueFactory(new PropertyValueFactory<Table, Integer>("rWarranty"));
iNextReview.setCellValueFactory(new PropertyValueFactory<Table, String>("rNextReview"));
iWarrantyTrue.setCellValueFactory(new PropertyValueFactory<Table, String>("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);
}
}
回答by James_D
If you want to specify the controller in the FXML file (so you can't use Deepak's answer) andyou want to access the index in the initialize()
method (so you can't use José's answer), you can use a controller factory:
如果你想在 FXML 文件中指定控制器(所以你不能使用 Deepak 的答案)并且你想访问initialize()
方法中的索引(所以你不能使用 José 的答案),你可以使用控制器工厂:
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("editClient.fxml"));
fxmlLoader.setControllerFactory(new Callback<Class<?>, 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();
回答by José Pereda
All you need to do is get an instance of your second controller:
您需要做的就是获取第二个控制器的实例:
EditClientController controller=fxmlLoader.<EditClientController>getController();
and you now will be able to send the required index:
您现在将能够发送所需的索引:
controller.setIndex(clickIndex);
This is all that's required:
这就是所需的全部内容:
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("editClient.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
EditClientController controller=fxmlLoader.<EditClientController>getController();
controller.setIndex(clickIndex);
Stage stage = new Stage();
stage.setTitle("Edytuj klienta");
stage.setScene(new Scene(root1));
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
EDIT
编辑
As clickIndex
will be sent afterthe second controller is initialized, this value won't be available on Initialize
.
由于clickIndex
将在第二个控制器初始化后发送,此值在 上不可用Initialize
。
A valid way to solve this is adding a listener to changes:
解决此问题的有效方法是向更改添加侦听器:
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());
});
}
回答by KayDK
When moving from one controller to another(one view to another), you could initialize the EditClientController with the required parameters
当从一个控制器移动到另一个控制器(一个视图到另一个视图)时,您可以使用所需的参数初始化 EditClientController
Eg:
例如:
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("editClient.fxml"));
EditClientController ctrl = new EditClientController();
ctrl.setCellIndex(id);
fxmlLoader.setController(ctrl);
If you have specified the controller in the fxml file, the you could use:
如果您在 fxml 文件中指定了控制器,则可以使用:
editWrapper.getCurrentController().setCellIndex(id);
where editControllerWrapper is a class that loads the new view and has a method getCurrentController that returns an instance of javafx controller.
其中 editControllerWrapper 是一个加载新视图的类,并且有一个方法 getCurrentController 返回一个 javafx 控制器的实例。
Eg: public class EditControllerWrapper {
例如:公共类 EditControllerWrapper {
private Parent root;
public EditControllerWrapper () {
try
{
FXMLLoader loader = new FXMLLoader(getClass().getResource("editClient.fxml"),
...
} catch (Exception e) {
...
}
}
public <T> T getCurrentController () {
return loader.getController();
}