我只是试图用SceneBuilder和JavaFx构建一个简单的Gui,但是我不知道为什么不能填充TableView,即使插入简单的Testobjects之后,TableView仍然保持空白。这是主要类别和目标类别。请帮我,我似乎找不到错误...
package application;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URL;
import java.util.ResourceBundle;
import Objects.Goal;
import UtilityClasses.GoalManager;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
public class Main extends Application implements Initializable {
private Stage primaryStage;
private AnchorPane mainLayout;
public static ObservableList<Goal> goalsData = FXCollections.observableArrayList();
@FXML
static TableView<Goal> goalTable = new TableView<Goal>();
@FXML
static TableColumn<Goal, String> goalsColumn = new TableColumn<>();
@FXML
static TableColumn<Goal, String> statusColumn = new TableColumn<>();
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("MainWindow");
try {
showMainView();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] args) {
try {
setDefaultSettings();
launch(args);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void showMainView() throws IOException {
SettingControlls mainController = new SettingControlls();
FXMLLoader loader = new FXMLLoader();
loader.setController(mainController);
loader.setLocation(Main.class.getResource("mainFXML.fxml"));
mainLayout = loader.load();
Scene scene = new Scene(mainLayout);
primaryStage.setScene(scene);
primaryStage.show();
}
private static void setDefaultSettings() throws IOException {
File f = new File("Goals.txt");
if(!f.exists()) {
OutputStream os = new FileOutputStream("Goals.txt");
Writer w = new OutputStreamWriter(os);
w.close();
}
}
private static ObservableList<Goal> getObservableList() throws FileNotFoundException, IOException {
ObservableList<Goal> ol = FXCollections.observableArrayList(new Goal("testGoal"));
return ol;
}
@Override
public void initialize(URL location, ResourceBundle resources) {
goalsData.add(new Goal("test"));
System.out.println(goalsData.get(0).getGoal());
goalsColumn.setCellValueFactory(new PropertyValueFactory<Goal, String>("goal"));
statusColumn.setCellValueFactory(new PropertyValueFactory<Goal, String>("status"));
goalTable.setItems(goalsData);
}
}
这是目标类别:
package Objects;
import javafx.beans.property.SimpleStringProperty;
public class Goal {
private SimpleStringProperty goal;
private SimpleStringProperty status;
public Goal(String goal) {
this.goal = new SimpleStringProperty(goal);
this.status = new SimpleStringProperty("ongoing");
}
public Goal(String goal, String status) {
this.goal = new SimpleStringProperty(goal);
this.status = new SimpleStringProperty(status);
}
public String getGoal() {
return this.goal.get();
}
public String getStatus() {
return this.status.get();
}
public void setGoal(String newGoal) {
this.goal = new SimpleStringProperty(newGoal);
}
public void setStatus(String newStatus) {
this.status = new SimpleStringProperty(newStatus);
}
}
因为在我的fxml文件中声明了TableView和列,所以用new生成它们似乎很奇怪,但是如果我不这样做,则会得到Nullpointerexception。
编辑:添加了fxml文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ContextMenu?>
<?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.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<AnchorPane prefHeight="406.0" prefWidth="721.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<children>
<MenuBar layoutX="-7.0" layoutY="14.0" prefHeight="25.0" prefWidth="733.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<menus>
<Menu mnemonicParsing="false" onAction="#GoalsClicked" style="-fx-font-size: 23;" text="Goals" />
<Menu disable="true" mnemonicParsing="false" style="-fx-font-size: 23;" text="Matchups" />
</menus>
</MenuBar>
<Text layoutX="14.0" layoutY="87.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Your current Goals:">
<font>
<Font size="24.0" />
</font>
</Text>
<TableView fx:id="goalTable" layoutY="103.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0">
<columns>
<TableColumn fx:id="goalsColumn" maxWidth="1.7976931348623157E308" minWidth="0.0" prefWidth="625.0" text="Goals" />
<TableColumn fx:id="statusColumn" maxWidth="1.7976931348623157E308" minWidth="0.0" prefWidth="72.0" text="Status" />
</columns>
<contextMenu>
<ContextMenu>
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
<MenuItem mnemonicParsing="false" text="Set status" />
</items>
</ContextMenu>
</contextMenu>
</TableView>
<Button layoutX="619.0" layoutY="315.0" mnemonicParsing="false" onAction="#addGoal" text="+" />
<Button layoutX="655.0" layoutY="315.0" mnemonicParsing="false" onAction="#removeGoal" text="-" />
</children>
</AnchorPane>
答案 0 :(得分:2)
您在那里有很多问题:
Main
类用作Controller
类。Node
中使用的.fxml
永远不会是静态的,因为它们属于实例而不是类,因此请将其删除。Node
文件中定义的.fxml
。与new
无关。 FXMLLoader
为您完成工作。因此,重写以下部分:
@FXML
static TableView<Goal> goalTable = new TableView<Goal>();
@FXML
static TableColumn<Goal, String> goalsColumn = new TableColumn<>();
@FXML
static TableColumn<Goal, String> statusColumn = new TableColumn<>();
我还建议将Main类分为Main
和Controller
类。
在Main中,您应该只加载文件,然后在Controller
中进行与UI相关的工作。
您可以按以下方式拆分:
主要:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
AnchorPane pane = loader.load();
primaryStage.setScene(new Scene(pane, 400, 400));
primaryStage.show();
}
}
控制器:
import javafx.fxml.Initializable;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
@Override
public void initialize(URL location, ResourceBundle resources) {
}
}
和.fxml
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="stackoverflow.dummy.Controller">
</AnchorPane>
然后您就可以按照我在2和3中提到的两条规则完成这些课程。