JavaFX在不同页面上向TableView添加行 [英] JavaFX Adding Rows to TableView on Different Page

查看:149
本文介绍了JavaFX在不同页面上向TableView添加行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我一直在研究该程序的一些问题,我认为我终于可以理解到哪里出了问题.我正在尝试按照本教程进行一些操作: http://docs.oracle .com/javafx/2/fxml_get_started/fxml_tutorial_intermediate.htm 但我的程序在与表视图不同的FXML页面上添加了一行.我认为程序无法将两者连接.我一直在尝试寻找使他们彼此交谈的方法(将所有内容都放在一个Controller中,它不喜欢它,尝试将控制器传递给类,但没有用{可能做错了尽管}).我的程序中还包含Integers和Doubles,但该教程未介绍它们,因此我尝试自己解决这些问题(可能比我做的更好的方法).

Okay, I've been working through some issues with this program and I think I've finally gotten it to a point where I understand what is wrong. I'm trying to follow this tutorial a bit: http://docs.oracle.com/javafx/2/fxml_get_started/fxml_tutorial_intermediate.htm But my program has the add a row on a different FXML page than the Table View is on. I think the program is having trouble connecting the two. I've looked in to trying to find ways to make them talk to each other (put everything in one Controller and it didn't like it, tried passing the controller through the class and that didn't work {might have done it wrong though}). My program also has Integers and Doubles in it which are not covered in that tutorial so I've tried to figure those out on my own (probably better ways of doing it than I did).

但是现在我只专注于弄清楚为什么它一直在思考

But right now I'm just focused on figuring out why it keeps thinking

data = partTable.getItems();

为空(AddPartController中的第77行).任何帮助或其他FXML/JavaFX教程都将不胜感激(尽管我已经浏览了很多).

Is null (line 77 in AddPartController). Any help or other FXML/JavaFX tutorials would be greatly appreciated (though I've already looked through a lot of them).

FXMLDocument.fxml(主页)

FXMLDocument.fxml (main page)

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

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.cell.*?> 
<?import javafx.collections.*?>
<?import fxmltableview.*?>
<?import ims.Part?> 
<?import ims.Inhouse?> 
<?import ims.Outsourced?> 

<BorderPane id="main" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ims.FXMLDocumentController" >
    <top>
        <Label fx:id="mainTitle" text="Inventory Management System" /> 
    </top>
    <center>
        <HBox fx:id="holding">
            <children>
                <VBox styleClass="contentBox">
                    <children>
                        <HBox styleClass="topBox">
                            <HBox styleClass="subHeading">
                                <Label text="Parts" />
                            </HBox>
                            <HBox styleClass="searchBox">
                                <Button text="Search" />
                                <TextField />
                            </HBox>
                        </HBox>
                        <TableView fx:id="partTable" styleClass="dataTable">
                            <columns>
                                <TableColumn text="Part ID">
                                    <cellValueFactory>
                                        <PropertyValueFactory property="id" />
                                    </cellValueFactory>
                                </TableColumn>
                                <TableColumn fx:id="nameColumn" text="Part Name">
                                    <cellValueFactory>
                                        <PropertyValueFactory property="name" />
                                    </cellValueFactory>
                                </TableColumn>
                                <TableColumn text="Inventory Level">
                                    <cellValueFactory>
                                        <PropertyValueFactory property="instock" />
                                    </cellValueFactory>
                                </TableColumn>
                                <TableColumn text="Price/Cost per Unit">
                                    <cellValueFactory>
                                        <PropertyValueFactory property="price" />
                                    </cellValueFactory>
                                </TableColumn>
                            </columns>
                            <items>
                                <FXCollections fx:factory="observableArrayList">
                                    <Inhouse name="Part 1" price="5.00" instock="5" max="10" min="1" />
                                    <Inhouse name="Part 2" price="7.00" instock="2" max="11" min="2" />
                                </FXCollections>
                            </items>
                            <sortOrder>
                                <fx:reference source="nameColumn" />
                            </sortOrder>
                        </TableView>
                        <HBox styleClass="modificationButtons">
                            <children>
                                <Button onAction="#addPart" text="Add" /> 
                                <Button onAction="#modifyPart" text="Modify" /> 
                                <Button text="Delete" /> 
                            </children>
                        </HBox>
                    </children>
                </VBox>
                <VBox styleClass="contentBox">
                    <children>
                        <HBox styleClass="topBox">
                            <HBox styleClass="subHeading">
                                <Label text="Products" />
                            </HBox>
                            <HBox styleClass="searchBox">
                                <Button text="Search" />
                                <TextField />
                            </HBox>
                        </HBox>
                        <TableView fx:id="productTable" styleClass="dataTable">
                            <columns>
                                <TableColumn text="Part ID" />
                                <TableColumn text="Part Name" />
                                <TableColumn text="Inventory Level" />
                                <TableColumn text="Price/Cost per Unit" />
                            </columns>
                        </TableView>
                        <HBox styleClass="modificationButtons">
                            <children>
                                <Button onAction="#addProduct" text="Add" /> 
                                <Button onAction="#modifyProduct" text="Modify" /> 
                                <Button text="Delete" /> 
                            </children>
                        </HBox>
                    </children>
                </VBox>
            </children>
        </HBox>
    </center>
    <bottom>
        <HBox fx:id="exitButton">
            <children>
                <Button onAction="#closeProgram" text="Exit" />
            </children>
        </HBox>
    </bottom>
</BorderPane>

FXMLDocumentController

FXMLDocumentController

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ims;

import java.io.IOException;
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.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;

/**
 *
 * @author chelseacamper
 */
public class FXMLDocumentController implements Initializable {

    @FXML
    private Label label;


    @FXML
    private void addPart(ActionEvent event) throws IOException {
        Parent add_part_parent = FXMLLoader.load(getClass().getResource("addPart.fxml"));
        Scene add_part_scene = new Scene(add_part_parent);
        add_part_scene.getStylesheets().add("style.css");
        Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
        app_stage.setScene(add_part_scene);
        app_stage.show();
    }

    @FXML
    private void modifyPart(ActionEvent event) throws IOException {
        Parent modify_part_parent = FXMLLoader.load(getClass().getResource("modifyPart.fxml"));
        Scene modify_part_scene = new Scene(modify_part_parent);
        modify_part_scene.getStylesheets().add("style.css");
        Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
        app_stage.setScene(modify_part_scene);
        app_stage.show();
    }

    @FXML
    private void addProduct(ActionEvent event) throws IOException {
        Parent add_product_parent = FXMLLoader.load(getClass().getResource("addProduct.fxml"));
        Scene add_product_scene = new Scene(add_product_parent);
        add_product_scene.getStylesheets().add("style.css");
        Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
        app_stage.setScene(add_product_scene);
        app_stage.show();
    }

    @FXML
    private void modifyProduct(ActionEvent event) throws IOException {
        Parent modify_product_parent = FXMLLoader.load(getClass().getResource("modifyProduct.fxml"));
        Scene modify_product_scene = new Scene(modify_product_parent);
        modify_product_scene.getStylesheets().add("style.css");
        Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
        app_stage.setScene(modify_product_scene);
        app_stage.show();
    }    

    @FXML
    private void closeProgram(ActionEvent event) throws IOException {
        Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
        app_stage.close();
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    

}

addPart.fxml

addPart.fxml

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

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

<BorderPane id="addPage" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ims.AddPartController">
    <fx:define>
        <ToggleGroup fx:id="inOutGroup" />
    </fx:define>
    <center>
        <VBox fx:id="verticalHolding">
            <children>
                <HBox fx:id="topRow">
                    <Label text="Add Part"/>
                    <RadioButton fx:id="inhouse" toggleGroup="$inOutGroup" text="In-House"/>
                    <RadioButton fx:id="outsourced" toggleGroup="$inOutGroup" selected="true" text="Outsourced"/>
                </HBox>
                <HBox styleClass="fullWidth">
                    <HBox styleClass="halfWidthLeft">
                        <Label text="ID" />
                    </HBox>
                    <HBox styleClass="halfWidthRight">
                        <TextField promptText="Auto Gen - Disabled" />
                    </HBox>
                </HBox>
                <HBox styleClass="fullWidth">
                    <HBox styleClass="halfWidthLeft">
                        <Label text="Name" />
                    </HBox>
                    <HBox styleClass="halfWidthRight">
                        <TextField fx:id="partNameField" promptText="Part Name" />
                    </HBox>
                </HBox>
                <HBox styleClass="fullWidth">
                    <HBox styleClass="halfWidthLeft">
                        <Label text="Inv" />
                    </HBox>
                    <HBox styleClass="halfWidthRight">
                        <TextField fx:id="partInstockField" promptText="Inv" />
                    </HBox>
                </HBox>
                <HBox styleClass="fullWidth">
                    <HBox styleClass="halfWidthLeft">
                        <Label text="Price/Cost" />
                    </HBox>
                    <HBox styleClass="halfWidthRight">
                        <TextField fx:id="partPriceField" promptText="Price/Cost" />
                    </HBox>
                </HBox>
                <HBox styleClass="fullWidth">
                    <HBox styleClass="halfWidthLeft">
                        <Label text="Max" />
                    </HBox>
                    <HBox styleClass="halfWidthRight">
                        <TextField styleClass="smallTextField" fx:id="partMaxField" promptText="Max" />
                        <Label text="Min" />
                        <TextField styleClass="smallTextField" fx:id="partMinField" promptText="Min" />
                    </HBox>
                </HBox>
                <HBox styleClass="fullWidth">
                    <HBox styleClass="halfWidthLeft">
                        <Label fx:id="inhouseLabel" text="Machine ID" />
                        <Label fx:id="outsourcedLabel" text="Company Name" />
                    </HBox>
                    <HBox styleClass="halfWidthRight">
                        <TextField fx:id="inhouseTextField" promptText="Mach ID" />
                        <TextField fx:id="outsourcedTextField" promptText="Comp Nm" />
                    </HBox>
                </HBox>
                <HBox styleClass="fullWidth">
                    <HBox styleClass="halfWidthLeft">
                    </HBox>
                    <HBox styleClass="halfWidthRight">
                        <Button onAction="#addInhouse" text="Save" />
                        <Button onAction="#backToMain" text="Cancel" />
                    </HBox>
                </HBox>
            </children>
        </VBox>
    </center>
</BorderPane>

AddPartController

AddPartController

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ims;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.stage.Stage;

/**
 * FXML Controller class
 *
 * @author chelseacamper
 */
public class AddPartController implements Initializable {
    @FXML
    ToggleButton inhouse;
    @FXML
    ToggleButton outsourced;
    @FXML
    Label inhouseLabel;
    @FXML
    Label outsourcedLabel;
    @FXML
    TextField inhouseTextField;
    @FXML
    TextField outsourcedTextField;
    @FXML
    private TableView<Inhouse> partTable;
    @FXML
    private TextField partNameField;
    @FXML
    private TextField partInstockField;
    @FXML
    private TextField partPriceField;
    @FXML
    private TextField partMaxField;
    @FXML
    private TextField partMinField;

    /**
     * Initializes the controller class.
     * @param url
     * @param rb
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        inhouseLabel.visibleProperty().bind( inhouse.selectedProperty() );
        outsourcedLabel.visibleProperty().bind( outsourced.selectedProperty() );
        inhouseTextField.visibleProperty().bind( inhouse.selectedProperty() );
        outsourcedTextField.visibleProperty().bind( outsourced.selectedProperty() );
        inhouseLabel.managedProperty().bind( inhouse.selectedProperty() );
        outsourcedLabel.managedProperty().bind( outsourced.selectedProperty() );
        inhouseTextField.managedProperty().bind( inhouse.selectedProperty() );
        outsourcedTextField.managedProperty().bind( outsourced.selectedProperty() );

    }

    @FXML
    public void addInhouse(ActionEvent event){
        ObservableList<Inhouse> data;
        data = partTable.getItems();
        data.add(new Inhouse(partNameField.getText(),
                Integer.parseInt(partInstockField.getText()),
                Double.parseDouble(partPriceField.getText()),
                Integer.parseInt(partMaxField.getText()),
                Integer.parseInt(partMinField.getText()),
                Integer.parseInt(inhouseTextField.getText())
//                Integer.parseInt(outsourcedTextField.getText())
                ));
        partNameField.setText("");
        partInstockField.setText(String.valueOf(partInstockField));
        partPriceField.setText(String.valueOf(partPriceField));
        partMaxField.setText(String.valueOf(partMaxField));
        partMinField.setText(String.valueOf(partMinField));
        inhouseTextField.setText(String.valueOf(inhouseTextField));
//        outsourcedTextField.setText(String.valueOf(outsourcedTextField));
    }

    @FXML
    private void backToMain(ActionEvent event) throws IOException {
        Parent add_main_parent = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
        Scene add_main_scene = new Scene(add_main_parent);
        add_main_scene.getStylesheets().add("style.css");
        Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
        app_stage.setScene(add_main_scene);
        app_stage.show();
    }

}

点击添加然后保存时出现的错误(甚至不必输入内容)

Errors that you get when you click add and then Save (don't even have to enter stuff)

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1770)
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1653)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Node.fireEvent(Node.java:8390)
    at javafx.scene.control.Button.fire(Button.java:185)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3758)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3486)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2495)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:350)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$350(GlassViewEventHandler.java:385)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$294/109927940.get(Unknown Source)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:404)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:384)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:927)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1765)
    ... 46 more
Caused by: java.lang.NullPointerException
    at ims.AddPartController.addInhouse(AddPartController.java:77)
    ... 56 more

推荐答案

addPart.fxml中的fx:id="partTable"中没有元素.因此,partTable为空,并且

The is no element in addPart.fxml with fx:id="partTable". Consequently partTable is null, and

partTable.getItems();

引发空指针异常.

您需要将partTable注入到定义了它的FXML的控制器中:

You need to inject partTable into the controller for the FXML in which it is defined:

public class FXMLDocumentController implements Initializable {

    @FXML
    private Label label;

    @FXML
    private TableView<Inhouse> partTable ;

    // ...
}

AddPartController仅需要访问与表关联的项目列表,因此您可以为其定义一个字段以及用于初始化它的方法:

The AddPartController only needs access to the list of items associated with the table, so you can define a field for it, and a method for initializing it:

public class AddPartController implements Initializable {

    // ...

    private ObservableList<Inhouse> tableItems ;

    public void setTableItems(ObservableList<Inhouse> tableItems) {
        this.tableItems = tableItems ;
    }

    // ...
}

然后在加载addPart.fxml时设置项目:

Then set the items when you load addPart.fxml:

@FXML
private void addPart(ActionEvent event) throws IOException {

    FXMLLoader loader = new FXMLLoader(getClass().getResource("addPart.fxml"));
    Parent add_part_parent = loader.load();

    AddPartController addPartController = loader.getController();
    addPartController.setTableItems(partTable.getItems());

    Scene add_part_scene = new Scene(add_part_parent);
    add_part_scene.getStylesheets().add("style.css");
    Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
    app_stage.setScene(add_part_scene);
    app_stage.show();
}

然后您当然只需要

@FXML
public void addInhouse(ActionEvent event){

    tableItems.add(new Inhouse(partNameField.getText(),
            Integer.parseInt(partInstockField.getText()),
            Double.parseDouble(partPriceField.getText()),
            Integer.parseInt(partMaxField.getText()),
            Integer.parseInt(partMinField.getText()),
            Integer.parseInt(inhouseTextField.getText())
            //  Integer.parseInt(outsourcedTextField.getText())
            ));
}

(FWIW我不知道是什么

(FWIW I have no idea what

partInstockField.setText(String.valueOf(partInstockField));

等应该做的.)

这篇关于JavaFX在不同页面上向TableView添加行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆