我尝试制作两个fxml文件。第一个是主要的fxml。第二个是TableView的fxml。我把它们放在一起。
这是Main类:
package sceneBuilder;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Ana extends Application{
private Stage window;
private BorderPane layout;
@Override
public void start(Stage args) throws Exception {
try{
window = args;
showMainView();
showMainItems();
}
catch(Exception e){
e.printStackTrace();
}
}
private void showMainView() throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Ana.class.getResource("interface.fxml"));
layout = loader.load();
Scene scene = new Scene(layout);
window.setScene(scene);
window.show();
}
private void showMainItems() throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Ana.class.getResource("interface2.fxml"));
BorderPane layout2 = loader.load();
layout.setCenter(layout2);
}
public static void main(String[] args) {
launch(args);
}
}
这是主FXML的控制器(Controller.java):
package sceneBuilder;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
public class Controller implements Initializable{
//TreeView
@FXML
private TreeView<String> mainTree = new TreeView<>();
//TextFields
@FXML
private TextField txtf1 = new TextField();
@FXML
private TextField txtf2 = new TextField();
@FXML
private TextField txtf3 = new TextField();
@Override
public void initialize(URL location, ResourceBundle recources) {
TreeItem<String> root = new TreeItem<>("Tables");
TreeItem<String> table1 = new TreeItem<>("Table-1");
TreeItem<String> table2 = new TreeItem<>("Table-2");
root.getChildren().add(table1);
root.getChildren().add(table2);
mainTree.setRoot(root);
mainTree.setShowRoot(false);
}
@FXML
void addClicked(ActionEvent event) throws Exception{
FXMLLoader loader = new FXMLLoader(getClass().getResource("interface2.fxml"));
Controller2 controller = loader.getController();
controller.addData(txtf1.getText(), txtf2.getText(), txtf3.getText());
}
@FXML
void deleteClicked(ActionEvent event){
FXMLLoader loader = new FXMLLoader(getClass().getResource("interface2.fxml"));
Controller2 controller = loader.getController();
controller.addData(txtf1.getText(), txtf2.getText(), txtf3.getText());
}
}
这是TableView的Controller(Controller2.java):
package sceneBuilder;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
public class Controller2 implements Initializable{
//Table and columns
@FXML
private TableView<Product> table = new TableView<>();
@FXML
private TableColumn<Product, String> nameColumn = new TableColumn<>();
@FXML
private TableColumn<Product, String> priceColumn = new TableColumn<>();
@FXML
private TableColumn<Product, String> quantityColumn = new TableColumn<>();
//Items
ObservableList<Product> data = FXCollections.observableArrayList(
new Product("Tablet", "20", "1200,00"),
new Product("Samsung Note 7", "50", "3450,00"),
new Product("Kitap", "1000", "50,00")
);
//Column settings
@Override
public void initialize(URL location, ResourceBundle recources) {
nameColumn.setCellValueFactory(new PropertyValueFactory<Product, String>("ad"));
priceColumn.setCellValueFactory(new PropertyValueFactory<Product, String>("fiyat"));
quantityColumn.setCellValueFactory(new PropertyValueFactory<Product, String>("miktar"));
table.setItems(data);
}
public void addData(String t1, String t2, String t3){
//Add data
Product satir = new Product(t1, t2, t3);
data.add(satir);
}
public void deleteData(){
ObservableList<Product> productSelected, allProducts;
allProducts = table.getItems();
productSelected = table.getSelectionModel().getSelectedItems();
productSelected.forEach(allProducts::remove);
}
}
这就是问题:我想在TableView中添加或删除项目。所以我创建了三个TextField和两个按钮。我为按钮设置了setOnAction方法。在Controller.java中,我获取了TableView的FXML(interface2.fxml)文件。并尝试启动TableView的Controller(Controller2.java)中存在的addItem方法。但只要我填充TextFields并单击添加或删除按钮,它就会给我java.lang.reflect.InvocationTargetException
和java.lang.NullPointerException
。
我不知道为什么???请帮我。我不太懂英语,所以请不要写严厉的句子。 (除了编程术语)。
如果需要,这些是fxml文件: Main fxml :( interface.fxml)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TreeView?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.VBox?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sceneBuilder.Controller">
<top>
<VBox BorderPane.alignment="CENTER">
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="Dosya">
<items>
<MenuItem mnemonicParsing="false" text="Yeni" />
<MenuItem mnemonicParsing="false" text="Kaydet" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Yardım">
<items>
<MenuItem mnemonicParsing="false" text="Hakkında" />
</items>
</Menu>
</menus>
</MenuBar>
<HBox spacing="8.0">
<children>
<TextField fx:id="txtf1" promptText="İsim" />
<TextField fx:id="txtf2" layoutX="10.0" layoutY="10.0" promptText="Fiyat" />
<TextField fx:id="txtf3" layoutX="175.0" layoutY="18.0" promptText="Miktar" />
<Region HBox.hgrow="ALWAYS" />
<Button maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#addClicked" text="Ekle" textAlignment="CENTER" textOverrun="CLIP">
<padding>
<Insets bottom="4.0" left="10.0" right="10.0" top="4.0" />
</padding></Button>
<Button layoutX="159.0" layoutY="10.0" mnemonicParsing="false" onAction="#deleteClicked" text="Sil">
<padding>
<Insets bottom="4.0" left="15.0" right="15.0" top="4.0" />
</padding></Button>
</children>
<padding>
<Insets bottom="8.0" left="8.0" right="8.0" top="8.0" />
</padding>
</HBox>
</children>
</VBox>
</top>
<left>
<TreeView fx:id="mainTree" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
</left>
<bottom>
<Label text="Sorunlar:" BorderPane.alignment="CENTER_LEFT">
<padding>
<Insets bottom="8.0" left="8.0" right="8.0" top="8.0" />
</padding></Label>
</bottom>
<center>
<TableView fx:id="table" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<columns>
<TableColumn fx:id="nameColumn" prefWidth="75.0" text="C1" />
<TableColumn fx:id="priceColumn" prefWidth="75.0" text="C2" />
<TableColumn fx:id="quantityColumn" prefWidth="75.0" text="Column X" />
</columns>
</TableView>
</center>
</BorderPane>
TableView的FXML(interface2.fxml):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sceneBuilder.Controller2">
<center>
<TableView fx:id="table" BorderPane.alignment="CENTER">
<columns>
<TableColumn fx:id="nameColumn" maxWidth="200.0" minWidth="200.0" prefWidth="200.0" resizable="false" text="Ad" />
<TableColumn fx:id="priceColumn" maxWidth="100.0" minWidth="100.0" prefWidth="100.0" text="Fiyat" />
<TableColumn fx:id="quantityColumn" maxWidth="100.0" minWidth="100.0" prefWidth="100.0" text="Miktar" />
</columns>
</TableView>
</center>
</BorderPane>
答案 0 :(得分:2)
您需要在两个控制器之间共享数据。你可以这样做:
public class Controller2 implements Initializable {
// existing code...
public ObservableList<Product> getData() {
return data ;
}
}
然后给第一个控制器一个数据引用:
public class Controller implements Initializable {
private ObservableList<Product> data ;
public ObservableList<Product> getData() {
return data ;
}
public void setData(ObservableList<Product> data) {
this.data = data ;
}
// ...
@FXML
void addClicked(ActionEvent event) {
data.add(new Product(txtf1.getText(), txtf2.getText(), txtf3.getText());
}
// etc ...
}
然后你可以将它们与
结合在一起public class Ana extends Application{
private Stage window;
private BorderPane layout;
@Override
public void start(Stage args) throws Exception {
try{
window = args;
Controller mainController = showMainView();
Controller2 controller = showMainItems();
mainController.setData(controller.getData());
}
catch(Exception e){
e.printStackTrace();
}
}
private Controller showMainView() throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Ana.class.getResource("interface.fxml"));
layout = loader.load();
Scene scene = new Scene(layout);
window.setScene(scene);
window.show();
return loader.getController();
}
private Controller2 showMainItems() throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Ana.class.getResource("interface2.fxml"));
BorderPane layout2 = loader.load();
layout.setCenter(layout2);
return loader.getController();
}
public static void main(String[] args) {
launch(args);
}
}
另请参阅Applying MVC With JavaFx了解此想法的其他版本。 (在该问题的答案中,数据被移动到它自己的类中,这可能更好。)