首页 文章

使用SceneBuilder的JavaFX TableView

提问于
浏览
0

我有一个非常简单的类,它接受一个作业列表并尝试用它们填充TableView . 我没有使用FXML,但我正在尝试新的方法 . 我的问题是;

tView.getItems().addAll(jobList);

返回一个空指针,但是如果我创建一个新的TableView,表中根本就没有数据 .

我相信我出错的地方是使用在SceneBuilderand中构造的TableView并没有正确地初始化它,但是我对如何做到这一点很困惑 . 这是我的InterFace方法类;

public class InterfaceMethods {

    @FXML TableView<Job> tView;

    @SuppressWarnings("unchecked")
    public void populateTableView(Connection connection, Stage stage) throws Exception {

        Parent root;
        root = FXMLLoader.load(getClass().getResource("TableViewInterface.fxml"));
        Scene scene = new Scene(root);
        stage.setScene(scene);

        JobDataAccessor jobAccessor = new JobDataAccessor();
        final String query = "SELECT * FROM progdb.adamJobs";
        List<Job> jobList = jobAccessor.getJobList(connection, query);
        //System.out.println(query);
        //System.out.println(connection);
        tView.getItems().addAll(jobList);
    }
}

这是我的MainApp课程;

public class MainApp extends Application {

private CheckUserDetails checkDetails;
private String pString, username = System.getProperty("user.name");
private InterfaceMethods iMethods;
private Connection connection;
@FXML private Button submitButton;
@FXML private PasswordField passField;
@FXML private Label warnLabel;

@Override
public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("MainInterface.fxml"));
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.show();
}

@FXML
private void loginCheck() throws Exception {
    checkDetails = new CheckUserDetails();
    pString = new String();
    pString = passField.getText();
    System.out.println(pString);
    if (checkDetails.checkUserDetails(pString, username) != null) {
        setConnection(checkDetails.connection);
        handleTableView();
    } else {
        warnLabel.setVisible(true);
    }
}

@FXML
public void handleTableView() throws Exception {
    iMethods = new InterfaceMethods();

    Stage stage = (Stage) submitButton.getScene().getWindow();  

    connection = getConnection();

    iMethods.populateTableView(connection, stage);
}

public static void main(String[] args) {
    launch(args);
}

最后这是我的两个FXML文件之一,其中包含TableView;

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.GridPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.InterfaceMethods">
   <children>
      <TableView fx:id="tView" layoutX="17.0" layoutY="19.0" prefHeight="347.0" prefWidth="570.0">
        <columns>
          <TableColumn prefWidth="75.0" text="CaseNO." />
          <TableColumn prefWidth="75.0" text="Case Notes" />
            <TableColumn prefWidth="75.0" text="Date Created" />
            <TableColumn prefWidth="75.0" text="Deadline" />
            <TableColumn prefWidth="75.0" text="Priority" />
            <TableColumn prefWidth="75.0" text="Completed" />
        </columns>
         <columnResizePolicy>
            <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
         </columnResizePolicy>
      </TableView>
   </children>
</AnchorPane>

getJobList方法(在不同的类中);

public List<Job> getJobList(final Connection connection, final String query) throws SQLException {
    try (Statement stmnt = connection.createStatement(); ResultSet rs = stmnt.executeQuery(query);) {
        jobList = new ArrayList<>();
        System.out.println(connection);
        System.out.println(query);
        while (rs.next()) {
            caseNumber = rs.getString("CaseNO");
            caseNotes = rs.getString("CaseNotes");
            dateCreated = rs.getString("DateCreated");
            deadlineDate = rs.getString("Deadline");
            prioritySetting = rs.getInt("Priority");
            completedSetting = rs.getString("Completed");
            job = new Job(caseNumber, caseNotes, dateCreated, deadlineDate, prioritySetting, completedSetting);
            jobList.add(job);
        }
        return jobList;
    }
}

2 回答

  • 0

    您需要为FXML定义控制器 .

    例如,您的FXML部分是: -

    <AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="288.0" prefWidth="293.0" xmlns:fx="http://javafx.com/fxml">
    <children>
        <TableView fx:id="tableView" layoutX="35.0" layoutY="28.0" prefHeight="200.0" prefWidth="227.0">
        <columns>
            <!-- Columns for table view-->
        </columns>
        </TableView>
    </children>
    </AnchorPane>
    

    1)为您的FXML页面创建一个控制器,如: -

    fx:controller="com.code.Controller"
    

    2)现在在您的控制器中,您可以这样做: -

    package com.code;
    
        public class Controller implements Initializable {
    
            @FXML private TableView<User> tableView;
    
  • 0

    所有@FXML带注释的控制器类字段都由FXMLLoader实例化,同时加载 fx:controller 等于该控制器类的fxml文件或由fxmlLoader.setController()设置的类 . 如果您自己实例化控制器类,则这些@FXML带注释的字段将为null . 所以这里是在fxml文件中使用setController()而不是fx:controller的示例方法:

    MainApp

    public class MainApp extends Application
    {
        @Override
        public void start( Stage stage ) throws Exception
        {
            MainController mainController = new MainController(getConnection());
    
            Scene scene = new Scene( mainController.getLayout() );
    
            stage.setScene( scene );
            stage.show();
        }
    
    
        public static void main( String[] args )
        {
            launch( args );
        }
    }
    

    MainController

    public class MainController implements Initializable
    {
    
        @FXML
        private Label label;
    
        private Parent layout;
    
        private Connection connection;
    
    
        public MainController(Connection connection)
        {
            this.connection = connection;
    
            FXMLLoader fxmlLoader = new FXMLLoader( getClass().getResource( "Main.fxml" ) );
            fxmlLoader.setController( this );
            try
            {
                layout = ( Parent ) fxmlLoader.load();
            }
            catch ( IOException exception )
            {
                throw new RuntimeException( exception );
            }
        }
    
    
        public Parent getLayout()
        {
            return layout;
        }
    
    
        @FXML
        private void handleTableView( ActionEvent event )
        {
            InterfaceMethods iMethods = new InterfaceMethods( connection );
            label.getScene().setRoot(iMethods.getLayout());
            label.getScene().getWindow().sizeToScene();
        }
    
    
        @Override
        public void initialize( URL url, ResourceBundle rb )
        {
            // do work with @FXML annotated fields in here
            label.setText( "Initial data!");
        }
    
    }
    

    Main.fxml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    
    <AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1">
        <children>
            <Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleTableView" fx:id="button" />
            <Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
        </children>
    </AnchorPane>
    

    InterfaceMethods

    public class InterfaceMethods implements Initializable
    {
    
        @FXML
        TableView<Job> tView;
    
        private Parent layout;
    
        private Connection connection;
    
    
        public MainController( Connection connection )
        {
            this.connection = connection;
    
            FXMLLoader fxmlLoader = new FXMLLoader( getClass().getResource( "TableViewInterface.fxml" ) );
            fxmlLoader.setController( this );
            try
            {
                layout = ( Parent ) fxmlLoader.load();
            }
            catch ( IOException exception )
            {
                throw new RuntimeException( exception );
            }
        }
    
    
        public Parent getLayout()
        {
            return layout;
        }
    
        @Override
        public void initialize( URL url, ResourceBundle rb )
        {
            // do work with @FXML annotated fields in here
            tView.setItems(...);
        }
    
    }
    

    请注意,Main.fxml和TableViewInterface.fxml中没有 fx:controller .

相关问题