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

Passing parameters between two JavaFX controllers

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

主控制器

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);

    }
}

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

EditClientController controller=fxmlLoader.<EditClientController>getController();

您现在可以发送所需的索引:

controller.setIndex(clickIndex);

这就是全部要求:

    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();
    }

编辑

由于 clickIndex 将在 第二个控制器初始化后 发送,因此此值在 Initialize 上不可用。

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

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 是一个 class 加载新视图并有一个方法 getCurrentController returns javafx 控制器的一个实例。

例如: public class 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();
}

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

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();