This question already has answers here:
Javafx tableview not showing data in all columns
(3 answers)
Why should I avoid using PropertyValueFactory in JavaFX?
(1 answer)
Closed last month.
I'm making a product list and products can have multiple parts attached to it, because sometimes a product is made up of multiple parts. This part of the code is to create a new product. I'm trying to copy a selected row from the list of parts to the table of parts that make up the product. The lists are ObservableList types. The logic seems to make sense, but for some reasons the PropertyValueFactory throws out the same error multiple times whenever I click the button to run the copy.
Information:
Java: javafx-sdk-19
OS: Windows 10 Home
IDE: IntelliJ IDEA Community Edition 2022.3
FXML was made with SceneBuilder 19
The four errors :
javafx.scene.control.cell.PropertyValueFactory getCellDataReflectively
WARNING: Can not retrieve property 'productID' in PropertyValueFactory: javafx.scene.control.cell.PropertyValueFactory#15ee4827 with provided class type: class InventoryManagementSystem.Outsourced
java.lang.IllegalStateException: Cannot read from unreadable property productID
at javafx.base#19/com.sun.javafx.property.PropertyReference.get(PropertyReference.java:167)
at javafx.controls#19/javafx.scene.control.cell.PropertyValueFactory.getCellDataReflectively(PropertyValueFactory.java:184)
at javafx.controls#19/javafx.scene.control.cell.PropertyValueFactory.call(PropertyValueFactory.java:154)
at javafx.controls#19/javafx.scene.control.cell.PropertyValueFactory.call(PropertyValueFactory.java:133)
at javafx.controls#19/javafx.scene.control.TableColumn.getCellObservableValue(TableColumn.java:592)
at javafx.controls#19/javafx.scene.control.TableColumn.getCellObservableValue(TableColumn.java:577)
at javafx.controls#19/javafx.scene.control.TableCell.updateItem(TableCell.java:681)
at javafx.controls#19/javafx.scene.control.TableCell.indexChanged(TableCell.java:485)
at javafx.controls#19/javafx.scene.control.IndexedCell$1.invalidated(IndexedCell.java:85)
at javafx.base#19/javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
at javafx.base#19/javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:148)
at javafx.controls#19/javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:130)
at javafx.controls#19/javafx.scene.control.skin.TableRowSkinBase.updateCells(TableRowSkinBase.java:530)
at javafx.controls#19/javafx.scene.control.skin.TableRowSkinBase.<init>(TableRowSkinBase.java:155)
at javafx.controls#19/javafx.scene.control.skin.TableRowSkin.<init>(TableRowSkin.java:82)
at javafx.controls#19/javafx.scene.control.TableRow.createDefaultSkin(TableRow.java:213)
at javafx.controls#19/javafx.scene.control.Control.doProcessCSS(Control.java:886)
at javafx.controls#19/javafx.scene.control.Control$1.doProcessCSS(Control.java:89)
at javafx.controls#19/com.sun.javafx.scene.control.ControlHelper.processCSSImpl(ControlHelper.java:67)
at javafx.graphics#19/com.sun.javafx.scene.NodeHelper.processCSS(NodeHelper.java:147)
at javafx.graphics#19/javafx.scene.Node.processCSS(Node.java:9603)
at javafx.graphics#19/javafx.scene.Node.applyCss(Node.java:9690)
at javafx.controls#19/javafx.scene.control.skin.VirtualFlow.setCellIndex(VirtualFlow.java:1811)
at javafx.controls#19/javafx.scene.control.skin.VirtualFlow.getCell(VirtualFlow.java:1788)
at javafx.controls#19/javafx.scene.control.skin.VirtualFlow.getOrCreateCellSize(VirtualFlow.java:3026)
at javafx.controls#19/javafx.scene.control.skin.VirtualFlow.getOrCreateCellSize(VirtualFlow.java:2998)
at javafx.controls#19/javafx.scene.control.skin.VirtualFlow.recalculateAndImproveEstimatedSize(VirtualFlow.java:3086)
at javafx.controls#19/javafx.scene.control.skin.VirtualFlow.recalculateEstimatedSize(VirtualFlow.java:3069)
at javafx.controls#19/javafx.scene.control.skin.VirtualFlow$5.invalidated(VirtualFlow.java:860)
at javafx.base#19/javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
at javafx.base#19/javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:148)
at javafx.controls#19/javafx.scene.control.skin.VirtualFlow.setCellCount(VirtualFlow.java:904)
at javafx.controls#19/javafx.scene.control.skin.TableViewSkinBase.updateItemCount(TableViewSkinBase.java:555)
at javafx.controls#19/javafx.scene.control.skin.VirtualContainerBase.checkState(VirtualContainerBase.java:184)
at javafx.controls#19/javafx.scene.control.skin.VirtualContainerBase.layoutChildren(VirtualContainerBase.java:159)
at javafx.controls#19/javafx.scene.control.skin.TableViewSkinBase.layoutChildren(TableViewSkinBase.java:407)
at javafx.controls#19/javafx.scene.control.Control.layoutChildren(Control.java:588)
at javafx.graphics#19/javafx.scene.Parent.layout(Parent.java:1207)
at javafx.graphics#19/javafx.scene.Parent.layout(Parent.java:1214)
at javafx.graphics#19/javafx.scene.Parent.layout(Parent.java:1214)
at javafx.graphics#19/javafx.scene.Scene.doLayoutPass(Scene.java:592)
at javafx.graphics#19/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2512)
at javafx.graphics#19/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:407)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics#19/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:406)
at javafx.graphics#19/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:436)
at javafx.graphics#19/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:575)
at javafx.graphics#19/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:555)
at javafx.graphics#19/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:548)
at javafx.graphics#19/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:352)
at javafx.graphics#19/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics#19/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics#19/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:1589)
javafx.scene.control.cell.PropertyValueFactory getCellDataReflectively
WARNING: Can not retrieve property 'productName' in PropertyValueFactory: javafx.scene.control.cell.PropertyValueFactory#4f5b087e with provided class type: class
[THE REST OF THE ERROR IS THE SAME AS THE FIRST ERROR]
javafx.scene.control.cell.PropertyValueFactory getCellDataReflectively
WARNING: Can not retrieve property 'productInventory' in PropertyValueFactory: javafx.scene.control.cell.PropertyValueFactory#276f30b0 with provided class type: class
[THE REST OF THE ERROR IS THE SAME AS THE FIRST ERROR]
javafx.scene.control.cell.PropertyValueFactory getCellDataReflectively
WARNING: Can not retrieve property 'productPrice' in PropertyValueFactory: javafx.scene.control.cell.PropertyValueFactory#6b95e213 with provided class type: class
[THE REST OF THE ERROR IS THE SAME AS THE FIRST ERROR]
Code:
Note - I stubbed out unrelated methods for readability.
Controller Code: By my best deduction, the errors are thrown in the addProductAddButton after linkedPartsTable.setItems(linkedParts); runs.
package Controllers;
import InventoryManagementSystem.Inventory;
import InventoryManagementSystem.Part;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
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.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.Optional;
import java.util.ResourceBundle;
public class AddProductFormController implements Initializable {
#FXML private TextField partsSearchField;
#FXML private TextField productIDField;
#FXML private TextField productNameField;
#FXML private TextField productInventoryField;
#FXML private TextField productPriceField;
#FXML private TextField productMaxField;
#FXML private TextField productMinField;
#FXML private TableView<Part> availablePartsTable;
#FXML private TableColumn<?, ?> partsIDColumn;
#FXML private TableColumn<?, ?> partsNameColumn;
#FXML private TableColumn<?, ?> partsInventoryColumn;
#FXML private TableColumn<?, ?> partsPriceColumn;
#FXML private TableView<Part> linkedPartsTable;
#FXML private TableColumn<?, ?> linkedPartsIDColumn;
#FXML private TableColumn<?, ?> linkedPartsNameColumn;
#FXML private TableColumn<?, ?> linkedPartsInventoryColumn;
#FXML private TableColumn<?, ?> linkedPartsPriceColumn;
#FXML private Button addButton;
#FXML private Button removeButton;
#FXML private Button cancelButton;
#FXML private Button saveButton;
private ObservableList<Part> linkedParts = FXCollections.observableArrayList();
Stage stage;
Parent scene;
#Override
public void initialize(URL url, ResourceBundle rb)
{
partsIDColumn.setCellValueFactory(new PropertyValueFactory<>("partID"));
partsNameColumn.setCellValueFactory(new PropertyValueFactory<>("partName"));
partsInventoryColumn.setCellValueFactory(new PropertyValueFactory<>("partInventory"));
partsPriceColumn.setCellValueFactory(new PropertyValueFactory<>("partPrice"));
availablePartsTable.setItems(Inventory.allParts);
linkedPartsIDColumn.setCellValueFactory(new PropertyValueFactory<>("productID"));
linkedPartsNameColumn.setCellValueFactory(new PropertyValueFactory<>("productName"));
linkedPartsInventoryColumn.setCellValueFactory(new PropertyValueFactory<>("productInventory"));
linkedPartsPriceColumn.setCellValueFactory(new PropertyValueFactory<>("productPrice"));
linkedPartsTable.setItems(linkedParts);
productIDField.setText("Automatically Generated");
productIDField.setDisable(true);
}
#FXML private void Search() {}
#FXML private void addProductAddButton(ActionEvent event) throws IOException
{
Part selectedPart = availablePartsTable.getSelectionModel().getSelectedItem();
if(selectedPart != null)
{
linkedParts.add(selectedPart);
linkedPartsTable.setItems(linkedParts);
}
else
{
System.out.println("here 6");
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Error!");
alert.setHeaderText(null);
alert.setContentText("No Part Selected.");
alert.showAndWait();
}
}
#FXML private void addProductRemoveButton(ActionEvent event) throws IOException {}
#FXML private void addProductSaveButton(ActionEvent event) throws IOException {}
#FXML private void addProductCancelButton(ActionEvent event) throws IOException {}
}
Imported Part Code:
package InventoryManagementSystem;
public class Part
{
private int partID, partInventory, partMin, partMax;
private String partName, partAdaptive;
private Double partPrice;
public Part(int partID, String partName, double partPrice, int partInventory, int partMin, int partMax, String partAdaptive)
{
this.partID = partID;
this.partName = partName;
this.partPrice = partPrice;
this.partInventory = partInventory;
this.partMin = partMin;
this.partMax = partMax;
this.partAdaptive = partAdaptive;
}
public int getPartID() { return partID; }
public String getPartName() { return partName; }
public double getPartPrice() { return partPrice; }
public int getPartInventory() { return partInventory; }
public int getPartMin() { return partMin; }
public int getPartMax() { return partMax; }
public String getPartAdaptive() { return partAdaptive; }
public void setPartID(int partID) { this.partID = partID; }
public void setPartName(String partName) { this.partName = partName; }
public void setPartPrice(double partPrice) { this.partPrice = partPrice; }
public void setPartInventory(int partInventory) { this.partInventory = partInventory; }
public void setPartMin(int partMin) { this.partMin = partMin; }
public void setPartMax(int partMax) { this.partMax = partMax; }
public void setAdaptive(String partAdaptive) { this.partAdaptive = partAdaptive; }
}
Imported Inventory Code:
package InventoryManagementSystem;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class Inventory
{
public static ObservableList<Part> allParts = FXCollections.observableArrayList();
public static ObservableList<Product> allProducts = FXCollections.observableArrayList();
private static int inventoryPartID;
private static int inventoryProductID;
public static ObservableList<Part> getAllParts() { return allParts; }
public static int inventoryPartID()
{
inventoryPartID++;
return inventoryPartID;
}
public static Part lookupPart(int partID)
{
for(Part p : allParts)
{
if (p.getPartID() == partID)
{
return p;
}
}
return null;
}
public static void addPart(Part newPart) { allParts.add(newPart); }
public static void updatePart(Part selectedPart) { allParts.set(selectedPart.getPartID() - 1, selectedPart); }
public static boolean deletePart(int selectedPart)
{
for(Part p : allParts)
{
if (p.getPartID() == selectedPart)
{
allParts.remove(p);
return true;
}
}
return false;
}
public static ObservableList<Product> getAllProducts() { return allProducts; }
public static int inventoryProductID()
{
inventoryProductID++;
return inventoryProductID;
}
public static Product lookupProduct(int productID)
{
for(Product p : allProducts)
{
if (p.getProductID() == productID)
{
return p;
}
}
return null;
}
public static void addProduct(Product newProduct) { allProducts.add(newProduct); }
public static void updatedProduct(Product newProduct) { allProducts.set(newProduct.getProductID(), newProduct); }
public static boolean deleteProduct(int selectedProduct)
{
for(Product p : allProducts)
{
if (p.getProductID() == selectedProduct)
{
allProducts.remove(p);
return true;
}
}
return false;
}
}
Outsourced Code referenced in the error:
package InventoryManagementSystem;
public class Outsourced extends Part
{
private String companyName;
public Outsourced(int id, String name, double price, int inventory, int min, int max, String adaptive)
{
super(id, name, price, inventory, min, max, adaptive);
this.companyName = companyName;
}
public String getCompanyName() { return companyName; }
public void setCompanyName(String companyName) { this.companyName = companyName; }
}
FXML file in case it helps:
<?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.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.shape.Rectangle?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="400.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controllers.AddProductFormController">
<children>
<Pane prefHeight="800.0" prefWidth="1000.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<Label text="Add Product" AnchorPane.leftAnchor="20.0" AnchorPane.topAnchor="20.0">
<font>
<Font name="System Bold" size="20.0" />
</font>
</Label>
<TextField fx:id="partsSearchField" onAction="#onEnter" prefHeight="25.0" prefWidth="159.0" promptText="Search by Part ID or Name" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="20.0" />
<AnchorPane prefHeight="275.0" prefWidth="450.0" AnchorPane.leftAnchor="20.0" AnchorPane.topAnchor="100.0">
<children>
<GridPane prefHeight="275.0" prefWidth="450.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="122.0" minWidth="10.0" prefWidth="108.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="162.0" minWidth="10.0" prefWidth="154.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="124.0" minWidth="8.0" prefWidth="75.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="165.0" minWidth="10.0" prefWidth="94.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="ID" />
<Label text="Name" GridPane.rowIndex="1" />
<Label text="Inventory" GridPane.rowIndex="2" />
<Label text="Price/Cost" GridPane.rowIndex="3" />
<Label text="Max" GridPane.rowIndex="4" />
<TextField fx:id="productIDField" promptText="Product ID" GridPane.columnIndex="1" />
<TextField fx:id="productNameField" promptText="Product Name" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<TextField fx:id="productInventoryField" promptText="Available Units" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<TextField fx:id="productPriceField" promptText="Price/Cost" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<TextField fx:id="productMaxField" promptText="Max Units" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<Label alignment="CENTER" text="Min" GridPane.columnIndex="2" GridPane.rowIndex="4">
<padding>
<Insets left="35.0" />
</padding>
</Label>
<TextField fx:id="productMinField" promptText="Min Units" GridPane.columnIndex="3" GridPane.rowIndex="4" />
</children>
</GridPane>
</children>
</AnchorPane>
<AnchorPane prefHeight="275.0" prefWidth="450.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="60.0">
<children>
<Rectangle arcHeight="5.0" arcWidth="5.0" fill="TRANSPARENT" height="275.0" stroke="BLACK" strokeLineCap="ROUND" strokeType="INSIDE" width="450.0" />
<TableView fx:id="availablePartsTable" layoutY="-1.0" prefHeight="275.0" prefWidth="448.0" AnchorPane.bottomAnchor="1.0" AnchorPane.leftAnchor="1.0" AnchorPane.rightAnchor="1.0" AnchorPane.topAnchor="1.0">
<columns>
<TableColumn fx:id="partsIDColumn" prefWidth="75.0" text="Part ID" />
<TableColumn fx:id="partsNameColumn" prefWidth="153.0" text="Part Name" />
<TableColumn fx:id="partsInventoryColumn" prefWidth="100.0" text="Inventory Level" />
<TableColumn fx:id="partsPriceColumn" prefWidth="120.0" text="Price/Cost Per Unit" />
</columns>
</TableView>
</children>
</AnchorPane>
<Button fx:id="addButton" mnemonicParsing="false" onAction="#addProductAddButton" text="Add" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="350.0" />
<AnchorPane prefHeight="275.0" prefWidth="450.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="400.0">
<children>
<Rectangle arcHeight="5.0" arcWidth="5.0" fill="TRANSPARENT" height="275.0" stroke="BLACK" strokeLineCap="ROUND" strokeType="INSIDE" width="450.0" />
<TableView fx:id="linkedPartsTable" layoutY="-1.0" prefHeight="275.0" prefWidth="448.0" AnchorPane.bottomAnchor="1.0" AnchorPane.leftAnchor="1.0" AnchorPane.rightAnchor="1.0" AnchorPane.topAnchor="1.0">
<columns>
<TableColumn fx:id="linkedPartsIDColumn" prefWidth="75.0" text="Part ID" />
<TableColumn fx:id="linkedPartsNameColumn" prefWidth="153.0" text="Part Name" />
<TableColumn fx:id="linkedPartsInventoryColumn" prefWidth="100.0" text="Inventory Level" />
<TableColumn fx:id="linkedPartsPriceColumn" prefWidth="120.0" text="Price/Cost Per Unit" />
</columns>
</TableView>
</children>
</AnchorPane>
<Button fx:id="removeButton" mnemonicParsing="false" onAction="#addProductRemoveButton" text="Remove Associated Part" AnchorPane.bottomAnchor="55.0" AnchorPane.rightAnchor="20.0" />
<Button fx:id="saveButton" mnemonicParsing="false" onAction="#addProductSaveButton" text="Save" AnchorPane.bottomAnchor="20.0" AnchorPane.rightAnchor="80.0" />
<Button fx:id="cancelButton" mnemonicParsing="false" onAction="#addProductCancelButton" text="Cancel" AnchorPane.bottomAnchor="20.0" AnchorPane.rightAnchor="20.0" />
</children>
</AnchorPane>
Related
I have a problem again.
I am trying to understand FXML and I am currently using the "Mastering FXML" guide of oracle "creating an address book with FXML".
I am pretty near at the end of the guide but i am not able to fix a problem I have since yesterday.
I want to write a Maintenance Program for my father but I am always getting the statement:javafx.fxml.LoadException: Maintenance is not a valid type.
there are 3 classes that are important for this problem I guess. That would be my "mainLayout.fxml", "FXMLDocumentController.java" and "Maintenance.java"
So I am just posting them in this order
<?xml version="1.0" encoding="UTF-8"?>
<?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.ScrollPane?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<?import javafx.collections.*?>
<Pane fx:controller="FXMLDocumentController" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="858.0" prefWidth="1276.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<SplitPane dividerPositions="0.8687747035573122" layoutX="2.0" layoutY="25.0" prefHeight="839.0" prefWidth="1276.0">
<items>
<AnchorPane fx:id="anchorpaneLeft" minHeight="0.0" minWidth="0.0" prefHeight="811.0" prefWidth="1104.0">
<children>
<ScrollPane id="scrollpane" fx:id="scrollpane" layoutX="452.0" layoutY="319.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<content>
<TableView id="tableView" fx:id="tableView" prefHeight="834.0" prefWidth="1102.0">
<columns>
<TableColumn text="%tablecolumnName" >
<cellValueFactory><PropertyValueFactory property = "name"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="%tablecolumnAddress" >
<cellValueFactory><PropertyValueFactory property = "address"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="%tablecolumnNumber" >
<cellValueFactory><PropertyValueFactory property = "number"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="%tablecolumnMail" >
<cellValueFactory><PropertyValueFactory property = "mail"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="%tablecolumnLast" >
<cellValueFactory><PropertyValueFactory property = "last"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="%tablecolumnNext" >
<cellValueFactory><PropertyValueFactory property = "next"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="%tablecolumnNote" >
<cellValueFactory><PropertyValueFactory property = "note"/>
</cellValueFactory>
</TableColumn>
</columns>
<items>
<FXCollections fx:factory="observableArrayList">
<Maintenance name="jacob" address="fichtestraße 5" number="01515242" mail="jacob#jacob.com" last="10.10.2018" next="10.10.2019" note="leer jung"/>
</FXCollections>
</items>
</TableView>
</content>
</ScrollPane>
</children>
</AnchorPane>
<AnchorPane fx:id="anchorpaneRight" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<VBox fx:id="vboxNew" alignment="TOP_CENTER" layoutX="50.0" layoutY="52.0" prefHeight="85.0" prefWidth="164.0" spacing="15.0" AnchorPane.bottomAnchor="726.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="26.0">
<children>
<Label fx:id="labelNew" prefHeight="17.0" prefWidth="192.0" text="%labelNew">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Label>
<Button fx:id="buttonInsert" mnemonicParsing="false" prefHeight="25.0" prefWidth="100.0" text="%buttonInsert" onAction="#handleInsertButton" textAlignment="CENTER" />
</children>
</VBox>
<VBox fx:id="vboxEdit" alignment="TOP_CENTER" layoutY="120.0" prefHeight="717.0" prefWidth="164.0" spacing="15.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="120.0">
<children>
<Label fx:id="labelEdit" prefHeight="17.0" prefWidth="166.0" text="%labelEdit">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Label>
<Button fx:id="buttonEdit" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" prefHeight="25.0" prefWidth="100.0" text="%buttonEdit" textAlignment="CENTER" />
<Button fx:id="buttonDelete" mnemonicParsing="false" prefHeight="25.0" prefWidth="100.0" text="%buttonDelete" />
<Button fx:id="buttonWeek" mnemonicParsing="false" prefHeight="25.0" prefWidth="100.0" text="%buttonWeek" />
<Button fx:id="buttonMonth" mnemonicParsing="false" prefHeight="25.0" prefWidth="100.0" text="%buttonMonth" />
<Button fx:id="buttonYear" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" prefHeight="25.0" prefWidth="100.0" text="%buttonYear" />
</children>
</VBox>
</children>
</AnchorPane>
</items>
</SplitPane>
<MenuBar fx:id="menubar" layoutX="2.0" layoutY="2.0" prefHeight="25.0" prefWidth="1276.0">
<menus>
<Menu fx:id="menuFile" mnemonicParsing="false" text="%menuFile">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu fx:id="menuEdit" mnemonicParsing="false" text="%menuEdit">
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
</items>
</Menu>
<Menu fx:id="menuHelp" mnemonicParsing="false" text="%menuHelp">
<items>
<MenuItem fx:id="itemAbout" mnemonicParsing="false" text="%itemAbout" />
</items>
</Menu>
<Menu fx:id="menuLanguage" mnemonicParsing="false" text="%menuLanguage">
<items>
<MenuItem fx:id="itemGer" mnemonicParsing="false" text="%itemGer" />
<MenuItem fx:id="itemEng" mnemonicParsing="false" text="%itemEng" />
</items>
</Menu>
</menus>
</MenuBar>
</children>
</Pane>
FXMLDocumentController.java:
import java.net.URL;
import java.util.*;
import javafx.collections.*;
import javafx.event.*;
import javafx.fxml.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.stage.*;
public class FXMLDocumentController implements Initializable {
#FXML private Label label;
#FXML private TableView<Maintenance> table;
#FXML private TableColumn tablecolumnName;
#FXML private TableColumn tablecolumnAddress;
#FXML private TableColumn tablecolumnNumber;
#FXML private TableColumn tablecolumnMail;
#FXML private TableColumn tablecolumnLast;
#FXML private TableColumn tablecolumnNext;
#FXML private TableColumn tablecolumnNote;
#FXML private Button buttonInsert;
#FXML private Button buttonEdit;
#FXML private Button buttonDelete;
#FXML private Button buttonWeek;
#FXML private Button buttonMonth;
#FXML private Button buttonYear;
#FXML private TextField textfieldName;
#FXML private TextField textfieldAddress;
#FXML private TextField textfieldMail;
#FXML private TextField textfieldNumber;
#FXML private TextField textfieldLast;
#FXML private TextField textfieldNext;
#FXML private TextField textfieldNote;
#FXML private TableView<Maintenance> tableView;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
void handleInsertButton(ActionEvent event){
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("insertWindow.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.setTitle("Insert Window");
Scene scene = new Scene (root1);
stage.setScene(scene);
stage.show();
} catch(Exception e){
e.printStackTrace();
}
}
protected void handleEditButton() {
}
protected void handleDeleteButton() {
}
protected void handleWeekButton() {
}
protected void handleMonthButton() {
}
protected void handleYearButton() {
}
protected void handleGerButton() {
}
protected void handleEngButton() {
}
#FXML
protected void addMaintenance(ActionEvent event){
ObservableList <Maintenance> data = tableView.getItems();
data.add(new Maintenance(textfieldName.getText(), textfieldAddress.getText(),
textfieldMail.getText(), textfieldNumber.getText(),
textfieldLast.getText(), textfieldNext.getText(),
textfieldNote.getText()));
textfieldName.setText("");
textfieldAddress.setText("");
textfieldMail.setText("");
textfieldNumber.setText("");
textfieldLast.setText("");
textfieldNext.setText("");
textfieldNote.setText("");
}
}
and finally Maintenance.java
import javafx.beans.property.SimpleStringProperty;
public class Maintenance {
private final SimpleStringProperty name = new SimpleStringProperty("");
private final SimpleStringProperty address = new SimpleStringProperty("");
private final SimpleStringProperty number = new SimpleStringProperty("");
private final SimpleStringProperty mail = new SimpleStringProperty("");
private final SimpleStringProperty last = new SimpleStringProperty("");
private final SimpleStringProperty next = new SimpleStringProperty("");
private final SimpleStringProperty note = new SimpleStringProperty("");
public Maintenance(){
this("", "", "", "", "", "", "");
}
public Maintenance(String name, String address, String number, String mail, String last, String next, String note){
setName(name);
setAddress(address);
setNumber(number);
setMail(mail);
setLast(last);
setNext(next);
setNote(note);
}
public String getName() {
return name.get();
}
public String getAddress() {
return address.get();
}
public String getNumber() {
return number.get();
}
public String getMail() {
return mail.get();
}
public String getLast() {
return last.get();
}
public String getNext() {
return next.get();
}
public String getNote() {
return note.get();
}
public final void setName(String Name){
name.set(Name);
}
public final void setAddress(String Address){
address.set(Address);
}
public final void setNumber(String Number){
number.set(Number);
}
public final void setMail(String Mail){
mail.set(Mail);
}
public final void setLast(String Last){
last.set(Last);
}
public final void setNext(String Next){
next.set(Next);
}
public final void setNote(String Note){
note.set(Note);
}
}
insertwindow.fxml is existing and worked great so far so I won't post it to shorten my post same for main.java and my 4 property files.
Hope someone can tell me what I am doing wrong again.
Thanks for help!
Executing C:\Users\Schurke\Documents\NetBeansProjects\Maintenance\dist\run365389303\Maintenance.jar using platform D:\Program Files\Java\jdk1.8.0_202\jre/bin/java
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
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:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$159(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: javafx.fxml.LoadException:
file:/C:/Users/Schurke/Documents/NetBeansProjects/Maintenance/dist/run365389303/Maintenance.jar!/mainLayout.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2848)
at javafx.fxml.FXMLLoader.processImport(FXMLLoader.java:2692)
at javafx.fxml.FXMLLoader.processProcessingInstruction(FXMLLoader.java:2661)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2517)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3116)
at Main.start(Main.java:19)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$166(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$179(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$177(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$178(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$152(WinApplication.java:177)
... 1 more
Caused by: java.lang.ClassNotFoundException
at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2899)
at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2846)
... 19 more
Exception running application Main
Java Result: 1
For custom FXML type you should add an import statement:
<?import Maintenance?>
In general it is bad practice to use default packages. Put the Maintenance.java into some package and import it as:
<?import yourPackageName.Maintenance?>
I been searching in YouTube, Stack-Overflow and fxexperience, even oracle documentation but I still don't get it.
There's not similar example :(
The problem is how to do a stack and queue simulator.
Generate 10 random numbers. Done.
Show the numbers in a table. Done.
Use the 10 random numbers to simulate a stack and a queue. I don't now how to comunicate the service with the TextField.
Pause the simulation. or Stop.
-The program needs a pause method. I don't know how to pause a thead. Perhaps with wait() and notify(). I don't know.
I have used label.textProperty.bind(service.progressProperty()). this works but when i try to bind a variable instead
the method updateProgress(i,n) throws a exception.
Maybe I need to use 2 Tasks.
Main class:
package simulation;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("/simulation/simulation.fxml"));
primaryStage.setTitle("JavaFX and concurrency, Stack and Queue");
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller Class:
package simulation;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Worker;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import java.net.URL;
import java.util.ResourceBundle;
public class SimulationCt implements Initializable {
#FXML private TableView table;
#FXML private TableColumn i_tc;
#FXML private TableColumn random_tc;
#FXML private TextField stack_start;
#FXML private TextField stack_1;
#FXML private TextField stack_2;
#FXML private TextField stack_3;
#FXML private TextField stack_4;
#FXML private TextField stack_5;
#FXML private TextField stack_final;
#FXML private TextField queue_start;
#FXML private TextField queue_1;
#FXML private TextField queue_2;
#FXML private TextField queue_3;
#FXML private TextField queue_4;
#FXML private TextField queue_5;
#FXML private TextField queue_final;
#FXML private Button new_b;
#FXML private Button play_pause_b;
#FXML private Button stop_b;
#FXML private ProgressBar progress_bar;
private ObservableList<RandomNumber> numberList = FXCollections.observableArrayList();
private CalculateService backProcess;
#FXML
private void createNew () {
disableNew(true);
generateRandom();
backProcess = new CalculateService();
progress_bar.progressProperty().bind(backProcess.progressProperty());
Platform.runLater(() -> {
backProcess.start();
});
}
#FXML
private void playPause () {
if(backProcess.getState().equals(Worker.State.RUNNING)) {
System.out.println("stoping...");
backProcess.cancel();
} else if (backProcess.getState().equals(Worker.State.CANCELLED)) {
System.out.println("restarting...");
backProcess.restart();
}
}
#FXML
private void stop () {
if(backProcess.getState().equals(Worker.State.RUNNING)) {
System.out.println("stoping...");
backProcess.cancel();
} else if (backProcess.getState().equals(Worker.State.CANCELLED)) {
System.out.println("already stoped...");
}
clearItems();
disableNew(false);
}
// cleans the list and the progress bar.
private void clearItems () {
progress_bar.progressProperty().unbind();
progress_bar.progressProperty().set(0.0);
numberList.clear();
}
private void disableNew (boolean b) {
new_b.setDisable(b);
play_pause_b.setDisable(!b);
stop_b.setDisable(!b);
}
// generates random numbers to fill the table, these numbers are the ones for the stack and the queue.
private void generateRandom () {
for (int i = 1; i < 11; i++) {
int rnd = (int)(Math.random() * (200 - 0 + 1)) + 0;
numberList.add(new RandomNumber(i, rnd ));
}
}
private void startTable () {
i_tc.setCellValueFactory( new PropertyValueFactory("i"));
random_tc.setCellValueFactory( new PropertyValueFactory("number"));
table.setItems(numberList);
}
#Override
public void initialize(URL url, ResourceBundle rb) {
disableNew(false);
startTable();
}
}
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<AnchorPane id="AnchorPane" prefHeight="300.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="simulation.SimulationCt">
<children>
<TableView fx:id="table" layoutX="8.0" layoutY="10.0" prefHeight="282.0" prefWidth="162.0">
<columns>
<TableColumn fx:id="i_tc" prefWidth="28.0" text="i" />
<TableColumn fx:id="random_tc" prefWidth="122.0" text="Random Number" />
</columns>
</TableView>
<GridPane layoutX="303.0">
<columnConstraints>
<ColumnConstraints fillWidth="false" minWidth="10.0" prefWidth="50.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
<ColumnConstraints fillWidth="false" halignment="RIGHT" hgrow="SOMETIMES" minWidth="10.0" prefWidth="50.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Stack" />
<VBox GridPane.rowIndex="1" GridPane.valignment="TOP">
<children>
<TextField fx:id="stack_start" prefHeight="25.0" prefWidth="25.0" />
<Label text="new" />
</children>
</VBox>
<VBox GridPane.columnIndex="1" GridPane.rowIndex="1">
<children>
<TextField fx:id="stack_1" prefHeight="25.0" prefWidth="25.0" />
<TextField fx:id="stack_2" prefHeight="25.0" prefWidth="25.0" />
<TextField fx:id="stack_3" prefHeight="25.0" prefWidth="25.0" />
<TextField fx:id="stack_4" prefHeight="25.0" prefWidth="25.0" />
<TextField fx:id="stack_5" prefHeight="25.0" prefWidth="25.0" />
</children>
</VBox>
<VBox GridPane.columnIndex="2" GridPane.rowIndex="1" GridPane.valignment="TOP">
<children>
<TextField fx:id="stack_final" prefHeight="25.0" prefWidth="25.0" />
<Label text="last" />
</children>
</VBox>
</children>
</GridPane>
<GridPane layoutX="193.0" layoutY="155.0">
<columnConstraints>
<ColumnConstraints fillWidth="false" hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
<ColumnConstraints fillWidth="false" hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Queue" GridPane.columnIndex="1" />
<VBox GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="TOP">
<children>
<TextField fx:id="queue_start" prefHeight="25.0" prefWidth="25.0" />
<Label text="new" />
</children>
</VBox>
<HBox spacing="5.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
<children>
<TextField fx:id="queue_1" prefHeight="25.0" prefWidth="25.0" />
<TextField fx:id="queue_2" prefHeight="25.0" prefWidth="25.0" />
<TextField fx:id="queue_3" prefHeight="25.0" prefWidth="25.0" />
<TextField fx:id="queue_4" prefHeight="25.0" prefWidth="25.0" />
<TextField fx:id="queue_5" prefHeight="25.0" prefWidth="25.0" />
</children>
</HBox>
<VBox GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="TOP">
<children>
<TextField fx:id="queue_final" prefHeight="25.0" prefWidth="25.0" />
<Label text="last" />
</children>
</VBox>
</children>
</GridPane>
<Button fx:id="new_b" onAction="#createNew" layoutX="266.0" layoutY="243.0" mnemonicParsing="false" text="New" />
<Button fx:id="play_pause_b" onAction="#playPause" layoutX="326.0" layoutY="243.0" mnemonicParsing="false" text="Play / Pause" />
<Button fx:id="stop_b" onAction="#stop" layoutX="428.0" layoutY="243.0" mnemonicParsing="false" text="Stop" />
<ProgressBar fx:id="progress_bar" layoutX="266.0" layoutY="277.0" prefWidth="200.0" progress="0.0" />
</children>
</AnchorPane>
DataHelper:
package simulation;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
public class RandomNumber {
private IntegerProperty i;
private IntegerProperty number;
public RandomNumber(int i, int number) {
this.i = new SimpleIntegerProperty(i);
this.number = new SimpleIntegerProperty(number);
}
public int getI() {
return i.get();
}
public IntegerProperty iProperty() {
return i;
}
public void setI(int i) {
this.i.set(i);
}
public int getNumber() {
return number.get();
}
public IntegerProperty numberProperty() {
return number;
}
public void setNumber(int number) {
this.number.set(number);
}
}
Service class:
package simulation;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
public class CalculateService extends Service {
int n = 20; // this does the trick to simulate the pause.
int j = 0; // even if the task is canceled the last value is saved here.
#Override
protected Task createTask() {
return new Task() {
#Override protected Void call() throws Exception {
int a;
int b;
int iterations;
for (iterations = j; iterations <= n; iterations++) {
j = iterations;
if (isCancelled()) {
updateMessage("Cancelled");
break;
}
updateProgress(iterations, n);
System.out.println("number: " + j);
//Block the thread for a short time, but be sure
//to check the InterruptedException for cancellation
try {
Thread.sleep(100);
} catch (InterruptedException interrupted) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
}
}
}
return null;
}
};
}
}
There's a lot of code in the question, and I don't think you need it all to address the concepts you're actually asking about. So I'll just give a high-level answer here. If you want to edit your question to something much simpler that addresses the actual issue, then I can make this specific to that example.
I would probably try to do this without threads at all, but using the animation API. For example, you could use a Timeline, with the following basic outline:
public class Controller {
// #FXML-annotated UI elements...
// Other state....
private Timeline timeline ;
#FXML
public void initialize() {
timeline = new Timeline(new KeyFrame(Duration.seconds(100)), e -> {
if (moreStepsToDo()) {
doNextStep();
} else {
stopSimulation();
}
});
timeline.setCycleCount(Animation.INDEFINITE);
}
private boolean moreStepsToDo() {
// return true if there are more steps in the simulation,
// false otherwise
}
private void doNextStep() {
// do next step in the simulation
}
#FXML
private void stopSimulation() {
timeline.stop();
}
#FXML
private void pauseSimulation() {
timeline.pause();
}
#FXML
private void playSimulation() {
timeline.play();
}
#FXML
private void resetSimulation() {
timeline.jumpTo(Duration.ZERO);
}
}
The nice thing about this solution is that everything is single-threaded: the event handler for the key frame is executed on the FX Application Thread, which is the same thread that executes the event handlers. This means there is no need to worry about synchronizing data across threads. The predefined methods in the animation API pause(), play(), and stop() provide exactly the functionality you're looking for; you just have to update the application state appropriately.
Here's a simple complete example that uses this approach (it just moves a bunch of rectangles, one at a time, from one vbox to another).
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SimplePausableAnimation extends Application {
private VBox left;
private VBox right;
private Timeline timeline;
private Button pausePlay;
#Override
public void start(Stage primaryStage) {
left = new VBox(10);
left.setMinWidth(200);
right = new VBox(10);
right.setMinWidth(200);
HBox hbox = new HBox(10, left, right);
pausePlay = new Button();
Button reset = new Button("Reset");
reset.setOnAction(e -> reset());
reset();
BorderPane root = new BorderPane(hbox);
HBox buttons = new HBox(5, pausePlay, reset);
buttons.setAlignment(Pos.CENTER);
root.setBottom(buttons);
Scene scene = new Scene(root, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private void reset() {
if (timeline != null) {
timeline.stop();
}
left.getChildren().clear();
right.getChildren().clear();
for (int i = 0; i < 5; i++) {
left.getChildren().add(new Rectangle(100, 100, Color.CORNFLOWERBLUE));
}
timeline = new Timeline(new KeyFrame(Duration.seconds(1), e -> {
if (moreStepsToDo()) {
doNextStep();
} else {
timeline.stop();
}
}));
timeline.setCycleCount(Animation.INDEFINITE);
pausePlay.disableProperty().bind(Bindings.createBooleanBinding(() -> {
if (left.getChildren().isEmpty()) {
return true;
}
return false;
}, left.getChildren()));
pausePlay.textProperty().bind(Bindings.createStringBinding(() -> {
if (timeline.getStatus() == Animation.Status.RUNNING) {
return "Pause";
}
return "Play";
}, timeline.statusProperty()));
pausePlay.setOnAction(e -> {
if (timeline.getStatus() == Animation.Status.RUNNING) {
timeline.pause();
} else {
timeline.play();
}
});
}
private boolean moreStepsToDo() {
return !left.getChildren().isEmpty();
}
private void doNextStep() {
int n = left.getChildren().size();
Node node = left.getChildren().remove(n - 1);
right.getChildren().add(node);
}
public static void main(String[] args) {
launch(args);
}
}
If you do want to do this with threads, one approach to pausing a thread is to use a Semaphore with a single permit. This generally looks something like this:
Semaphore pauser = new Semaphore(1);
Thread simulationThread = new Thread(() -> {
try {
while (! Thread.currentThread().isInterrupted()) {
pauser.acquire();
// do simulation step
pauser.release();
Thread.sleep(100);
}
} catch (InterruptedException exc) {
// ignore and exit thread...
}
});
(Obviously the same idiom will work in your Task, which is executed on a background thread.)
Then calling pauser.acquire(); from the controller will pause the simulation (because the simulation thread will not be able to acquire the permit), and calling pauser.release() while it is paused will let it run again.
I am trying to populate a TableView from data in SQLite database but I am experiencing a very weird scenario that I cannot understand what is causing it.
The tableview only populates two columns and does not populate the rest. The Tablecolumns with 'NO' and 'Date Created' do not get populated when the TableView is finally displayed.
This code however displays data from SQLite database in 'Title' and 'Description' TableView columns.
Please someone with a hawk eye help me identify where I am going wrong on this code. I have spent the better part of the day trying to figure out where I am going wrong but I do not seem to figure out what it is that I am not doing it right. I will gladly appreciate any help on this.
Here is my code for
Main class
Blockquote
public class Notedb extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("ListNotesUI.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Blockquote
FXML
Blockquote
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<SplitPane dividerPositions="0.5" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" orientation="VERTICAL" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="notedb.test.ListNotesUIController">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<SplitPane dividerPositions="0.5" layoutX="186.0" layoutY="-2.0" orientation="VERTICAL" prefHeight="196.0" prefWidth="598.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Button alignment="TOP_CENTER" contentDisplay="TEXT_ONLY" layoutX="484.0" layoutY="22.0" mnemonicParsing="false" onAction="#newNote" prefHeight="54.0" prefWidth="66.0" text="New Note" textAlignment="CENTER" wrapText="true" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<GridPane layoutX="126.0" layoutY="2.0" prefHeight="94.0" prefWidth="596.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="441.0" minWidth="10.0" prefWidth="441.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="292.0" minWidth="10.0" prefWidth="155.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<TextField fx:id="m_search" onAction="#searchNotes" />
<Label fx:id="labelNOs" alignment="CENTER" prefHeight="17.0" prefWidth="94.0" text="4 Notes" GridPane.columnIndex="1" />
</children>
</GridPane>
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<GridPane layoutX="181.0" layoutY="98.0" prefHeight="196.0" prefWidth="598.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Pane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
<children>
<Button layoutX="95.0" layoutY="24.0" mnemonicParsing="false" prefHeight="54.0" prefWidth="100.0" text="Delete" />
<Button fx:id="btn_medit" layoutX="389.0" layoutY="24.0" mnemonicParsing="false" onAction="#editNoteRow" prefHeight="54.0" prefWidth="94.0" text="Edit" />
</children>
</Pane>
<TableView id="tableNotes" fx:id="tableNotes" editable="true" prefHeight="200.0" prefWidth="200.0">
<columns>
<TableColumn id="noCol" fx:id="noCol" text="NO">
</TableColumn>
<TableColumn id="titleCol" fx:id="titleCol" text="Title">
</TableColumn>
<TableColumn id="dateCreatedCol" fx:id="dateCreatedCol" text="Date Created">
</TableColumn>
<TableColumn id="descriptionCol" fx:id="descriptionCol" text="Description">
</TableColumn>
</columns>
</TableView>
</children>
</GridPane>
</children>
</AnchorPane>
</items>
</SplitPane>
Blockquote
Controller class
Blockquote
public class ListNotesUIController implements Initializable {
#FXML
private Label label;
#FXML
private Label labelNOs;
#FXML
private Button newNote;
#FXML
private Button btn_medit;
#FXML
private TextField m_search;
#FXML
private TableView tableNotes;
#FXML
private TableColumn titleCol;
#FXML
private TableColumn descriptionCol;
#FXML
private TableColumn dateCreatedCol;
#FXML
private TableColumn noCol;
//START | SQLITE
private static Connection con;
private static Statement stat;
private PreparedStatement prep;
//END | SQLITE
private ObservableList <Note> dataNotes;
DataBank dbank = new DataBank();
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}
#FXML
private void editNoteRow(ActionEvent event) {
}
#FXML
private void newNote(ActionEvent event) throws IOException {
}
#FXML
private void searchNotes(ActionEvent event){
}
#Override
public void initialize(URL url, ResourceBundle rb) {
dataNotes = FXCollections.observableArrayList();
noCol.setCellValueFactory(
new PropertyValueFactory<Note, String>("idno")
);
dateCreatedCol.setCellValueFactory(
new PropertyValueFactory<Note, String>("datecreated")
);
titleCol.setCellValueFactory(
new PropertyValueFactory<Note, String>("title")
);
descriptionCol.setCellValueFactory(
new PropertyValueFactory<Note, String>("description")
);
try {
SQLiteConfig config = new SQLiteConfig();
con = DriverManager.getConnection("jdbc:sqlite:Note.db");
stat = con.createStatement();
stat.executeUpdate("CREATE TABLE IF NOT EXISTS NotesDB (idno INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, Title VARCHAR(500), Description VARCHAR(1000), DateCreated DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL);");
ResultSet rs = con.createStatement().executeQuery("SELECT idno, Title, DateCreated, Description FROM NotesDB");
while (rs.next()) {
Note nt = new Note();
nt.idno.set(rs.getString("idno"));
nt.title.set(rs.getString("Title"));
nt.datecreated.set(rs.getString("DateCreated"));
nt.description.set(rs.getString("Description"));
dataNotes.add(nt);
}
tableNotes.setItems(dataNotes);
} catch (SQLException ex) {
Logger.getLogger(ListNotesUIController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Blockquote
DataModel class
Blockquote
public class Note {
public SimpleStringProperty title = new SimpleStringProperty();
public SimpleStringProperty description = new SimpleStringProperty();
public SimpleStringProperty datecreated = new SimpleStringProperty();
public SimpleStringProperty idno = new SimpleStringProperty();
public String getTitle() {
return title.get();
}
public void setTitle(String titleStr) {
title.set(titleStr);
}
public String getDescription() {
return description.get();
}
public void setDescription(String descriptionStr) {
description.set(descriptionStr);
}
public String getDateCreated() {
return datecreated.get();
}
public void setDateCreated(String datecreatedStr) {
datecreated.set(datecreatedStr);
}
public String getIdNO() {
return idno.get();
}
public void setIdNO(String idnoStr) {
idno.set(idnoStr);
}
}
Blockquote
There is a mistake regarding your property naming.
Your function for getDateCreated and IdNO don't correlate with
the naming convention.
Replace
public SimpleStringProperty datecreated = new SimpleStringProperty();
public SimpleStringProperty idno = new SimpleStringProperty();
with
public SimpleStringProperty dateCreated = new SimpleStringProperty();
public SimpleStringProperty idNO = new SimpleStringProperty();
And have a look at the naming conventions for properties
I am currently writing a poker game as an assignment for my finals. I have to use a combined view: a class with actual code and the Scenebuilder. I did everything i learned and the model is working just fine. I'm new to this so it must be an easy fix! The professors want us to get familiar with Scenebuilder but they didn't give much of an explanation.
As you can see i use a class called pokerView in which I load in every single image of the cards. In the beginning I use a strange forloop to automatically generate the names of the images, I printed it out and the url is okay!
I also use the scenebuilder. It has it's own controller/view class that is the FXMLpokerController
And to combine those two, I used a "super" view.
Funny thing is that java does not give me any error!
I really really need an answer. If the window show up empty I cannot show the app.
So the terminal gives me the following lines when using the printstacktrace
javafx.fxml.LoadException:
file:/Users/test/Documents/2%20aba/Informatica/Netbeans%20projecten/poker/dist/run1845271650/poker.jar!/poker/FXMLpoker.fxml:10
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at poker.ViewPlus.<init>(ViewPlus.java:30)
at poker.MAINpoker.start(MAINpoker.java:27)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$163(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$176(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$174(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Caused by: java.lang.IllegalArgumentException: Can not set javafx.scene.control.Button field poker.FXMLpokerController.deal to javafx.scene.layout.AnchorPane
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
at java.lang.reflect.Field.set(Field.java:764)
at javafx.fxml.FXMLLoader.injectFields(FXMLLoader.java:1163)
at javafx.fxml.FXMLLoader.access$1600(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$ValueElement.processValue(FXMLLoader.java:857)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:751)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
... 10 more
I don't know what this means
this is the pokerview
package poker;
import javafx.scene.layout.Region;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import java.util.ArrayList;
import java.net.URL;
public class PokerView extends Region{
private Game model;
private Image image;
private ImageView imv;
private ArrayList<ImageView> stapelView = new ArrayList<>();
public PokerView(Game model){
this.model=model;
}
public void configureerStapel(){
for(Kaart k:model.getRound().getStapel().getList()){
URL imageURL = getClass().getResource("/res/"+k.toString());
System.out.println(""+imageURL);
imv = new ImageView(imageURL.toExternalForm());
stapelView.add(imv);
}
}
public void turnHandCards(){
int index1 = model.getRound().wieIsAanDeBeurt().getHand().get(0).getIndex();
ImageView k = stapelView.get(index1);
System.out.println("de eerste hand card in de view ="+index1);
k.setLayoutX(166);
k.setLayoutY(200);
k.setFitHeight(141);
k.setFitWidth(95);
int index2 = model.getRound().wieIsAanDeBeurt().getHand().get(1).getIndex();
ImageView s = stapelView.get(index2);
s.setLayoutX(297);
s.setLayoutY(200);
s.setFitHeight(141);
s.setFitWidth(95);
getChildren().addAll(k, s);
}
public void turnThreeTableCards(){
int index1 = model.getRound().getTafel().getFirstCard().getIndex();
ImageView i = stapelView.get(index1);
i.setLayoutX(447);
i.setLayoutY(24);
i.setFitHeight(141);
i.setFitWidth(95);
int index2 = model.getRound().getTafel().getSecondCard().getIndex();
ImageView j = stapelView.get(index2);
j.setLayoutX(340);
j.setLayoutY(24);
j.setFitHeight(141);
j.setFitWidth(95);
int index3 = model.getRound().getTafel().getThirdCard().getIndex();
ImageView k = stapelView.get(index3);
k.setLayoutX(231);
k.setLayoutY(24);
k.setFitHeight(141);
k.setFitWidth(95);
getChildren().addAll(i, j, k);
}
public void turnLastTwoTableCards(){
int index1 = model.getRound().getTafel().getFourthCard().getIndex();
ImageView i = stapelView.get(index1);
i.setLayoutX(123);
i.setLayoutY(24);
i.setFitHeight(141);
i.setFitWidth(95);
int index2 = model.getRound().getTafel().getFifthCard().getIndex();
ImageView j = stapelView.get(index2);
j.setLayoutX(14);
j.setLayoutY(24);
j.setFitHeight(141);
j.setFitWidth(95);
getChildren().addAll(i, j);
}
}
this is the FXMLpokerController
package poker;
import javafx.fxml.FXML;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import java.lang.*;
public class FXMLpokerController {
#FXML
private Button raise;
#FXML
private Button check;
#FXML
private Button fold;
#FXML
private Button ready;
#FXML
private TextField stake;
#FXML
private TextArea creditsLeft;
#FXML
private TextArea pot;
#FXML
private TextArea minimumStake;
#FXML
private TextArea isAanDeBeurt;
#FXML
private Button deal;
#FXML
void initialize(){
raise.setOnAction(this::raise);
check.setOnAction(this::check);
fold.setOnAction(this::fold);
ready.setOnAction(this::ready);
deal.setOnAction(this::deal);
pot.setText(""+model.getPot());
creditsLeft.setText(""+model.getRound().wieIsAanDeBeurt().getCredit());
}
private Game model;
private ViewPlus view;
private int counter;
public void raise(ActionEvent e){
int cred = Integer.parseInt(stake.getText());
model.getRound().wieIsAanDeBeurt().setStake(cred);
model.getRound().wieIsAanDeBeurt().setCredit(model.getRound().wieIsAanDeBeurt().getCredit()-cred);
model.getRound().getTafel().setPot(model.getRound().getTafel().getPot()+cred);
model.getRound().volgendeSpeler();
minimumStake.setText(""+cred);
automaticFold();
}
public void check(ActionEvent e){
model.getRound().volgendeSpeler();
automaticFold();
}
public void fold(ActionEvent e){
model.getRound().wieIsAanDeBeurt().doetNietMeerMee(true);
automaticFold();
}
public void setModel(Game model){
this.model=model;
model = new Game();
}
public void setView(ViewPlus view){
this.view=view;
}
public void automaticFold(){
int cred = Integer.parseInt(minimumStake.getText());
if(model.getRound().wieIsAanDeBeurt().getCredit()<cred){
model.getRound().wieIsAanDeBeurt().doetNietMeerMee(true);
}
}
public void ready(ActionEvent e){
model.getRound().volgendeSpeler();
}
public void setName(){
isAanDeBeurt.setText(model.getRound().wieIsAanDeBeurt().getName());
String name = isAanDeBeurt.getText();
model.getRound().wieIsAanDeBeurt().setName(name);
}
public void deal(ActionEvent e){
model.startOver();
view.configureerKaarten();
view.turnHandCards();
counter++;
}
/**
* #return the counter
*/
public int getCounter() {
return counter;
}
}
this is the superview called viewplus
package poker;
import javafx.scene.Parent;
import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.AnchorPane;
public class ViewPlus extends AnchorPane {
private Game model;
private PokerView view;
private Parent fxmlView;
private FXMLpokerController fxmlController;
public ViewPlus(Game model) throws IOException{
this.model = model;
view = new PokerView(model);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("FXMLpoker.fxml"));
try{
fxmlView = loader.load();
fxmlController = loader.getController();
fxmlController.setModel(model);
fxmlController.setView(this);
getChildren().addAll(fxmlView,view);
} catch(IOException ex){ex.printStackTrace();}
}
public void configureerKaarten(){
view.configureerStapel();
}
public void turnHandCards(){
view.turnHandCards();
}
public void turnThreeTableCards(){
view.turnThreeTableCards();
}
}
this is the View controller
package poker;
public class Controller {
private Game model;
private ViewPlus view;
public Controller(Game model, ViewPlus view){
this.model=model;
this.view=view;
view.configureerKaarten();
view.turnHandCards();
if(model.getRound().getSpeler1().getStake() == model.getRound().getSpeler2().getStake()
&& model.getRound().getSpeler2().getStake() == model.getRound().getSpeler3().getStake()
&& model.getRound().getSpeler3().getStake() == model.getRound().getSpeler4().getStake()){
view.turnThreeTableCards();
}
}
}
this is my main class
package poker;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MAINpoker extends Application {
#Override
public void start(Stage stage) throws Exception {
Game model = new Game();
ViewPlus view = new ViewPlus (model);
Scene scene = new Scene(view);
stage.setScene(scene);
stage.show();
Controller c = new Controller(model, view);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
this is my FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.image.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" fx:id="deal" prefHeight="605.0" prefWidth="556.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="poker.FXMLpokerController">
<children>
<Button layoutX="484.0" layoutY="556.0" mnemonicParsing="false" text="ready" />
<Button layoutX="249.0" layoutY="495.0" mnemonicParsing="false" text="deal" />
<Label layoutX="393.0" layoutY="495.0" prefHeight="42.0" prefWidth="160.0" text="minimum stake">
<graphic>
<TextArea fx:id="minimumStake" prefHeight="28.0" prefWidth="28.0" />
</graphic>
</Label>
<Button fx:id="raise" layoutX="14.0" layoutY="405.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="69.0" text="raise" />
<Button fx:id="check" layoutX="251.0" layoutY="405.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="69.0" text="check" />
<Button fx:id="fold" layoutX="473.0" layoutY="405.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="69.0" text="fold" />
<Label layoutX="17.0" layoutY="548.0" prefHeight="42.0" prefWidth="148.0" text="name">
<graphic>
<TextArea fx:id="isAanDeBeurt" prefHeight="42.0" prefWidth="97.0" />
</graphic>
</Label>
<Label layoutX="17.0" layoutY="495.0" text="pot">
<graphic>
<TextArea fx:id="pot" prefHeight="36.0" prefWidth="47.0" />
</graphic>
</Label>
<Label fx:id="label" layoutX="409.0" layoutY="450.0" minHeight="16" minWidth="69" text="stake">
<graphic>
<TextField prefHeight="20.0" prefWidth="91.0" />
</graphic></Label>
<ImageView fx:id="tafel" fitHeight="391.0" fitWidth="556.0">
<image>
<Image url="#../afbeelding/dark_green_colour_background.jpg" />
</image>
</ImageView>
<Pane layoutX="14.0" layoutY="24.0">
<children>
<ImageView fx:id="tafel1" fitHeight="141.0" fitWidth="95.0">
<image>
<Image url="#../afbeelding/back.jpg" />
</image>
</ImageView>
</children>
</Pane>
<Label fx:id="label1" layoutX="17.0" layoutY="450.0" minHeight="16" minWidth="69" prefHeight="16.0" prefWidth="119.0" text="credits left">
<graphic>
<TextArea fx:id="creditsLeft" prefHeight="16.0" prefWidth="37.0" />
</graphic>
</Label>
<Pane layoutX="142.0" layoutY="246.0" />
<Pane layoutX="123.0" layoutY="24.0">
<children>
<ImageView fx:id="tafel2" fitHeight="141.0" fitWidth="95.0">
<image>
<Image url="#../afbeelding/back.jpg" />
</image>
</ImageView>
</children>
</Pane>
<Pane layoutX="231.0" layoutY="24.0">
<children>
<ImageView fx:id="tafel3" fitHeight="141.0" fitWidth="95.0">
<image>
<Image url="#../afbeelding/back.jpg" />
</image>
</ImageView>
</children>
</Pane>
<Pane layoutX="340.0" layoutY="24.0">
<children>
<ImageView fx:id="tafel4" fitHeight="141.0" fitWidth="95.0">
<image>
<Image url="#../afbeelding/back.jpg" />
</image>
</ImageView>
</children>
</Pane>
<Pane layoutX="447.0" layoutY="24.0">
<children>
<ImageView fx:id="tafel5" fitHeight="141.0" fitWidth="95.0">
<image>
<Image url="#../afbeelding/back.jpg" />
</image>
</ImageView>
</children>
</Pane>
<Pane layoutX="166.0" layoutY="200.0">
<children>
<ImageView fx:id="hand1" fitHeight="141.0" fitWidth="95.0">
<image>
<Image url="#../afbeelding/back.jpg" />
</image>
</ImageView>
</children>
</Pane>
<Pane layoutX="297.0" layoutY="200.0">
<children>
<ImageView fx:id="hand2" fitHeight="141.0" fitWidth="95.0">
<image>
<Image url="#../afbeelding/back.jpg" />
</image>
</ImageView>
</children>
</Pane>
</children>
You have named your AnchorPane "deal" in the FXML and your Button as "deal" in the controller. During initialization, the mapping is done by name. Since these objects are not the same type, you are getting a class exception.
If the button is really deal, move the id from the AnchorPane to the button in the FXML. Based on this:
deal.setOnAction(this::deal);
I assume the button should be called deal.
Change this line
<AnchorPane id="AnchorPane" prefHeight="605.0" prefWidth="556.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="poker.FXMLpokerController">
and this line
<Button fx:id="deal" layoutX="249.0" layoutY="495.0" mnemonicParsing="false" text="deal" />
Your AnchorPane has the fx:id "deal":
<AnchorPane id="AnchorPane" fx:id="deal" prefHeight="605.0" prefWidth="556.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="poker.FXMLpokerController">
In your controller class FXMLpokerController you define "deal" as a button:
#FXML
private Button deal;
The FXML injection cannot initialize a Button as an AnchorPane. Move the fx:id to the correct button and give your AnchorPane a different fx:id.
I'm a novice and would very like a to know how to make a column cell editable when using FXML.
Specifically, I have been following the two working examples provided by Oracle. The first one (http://docs.oracle.com/javafx/2/ui_controls/table-view.htm) allows editing.
The second example ( http://docs.oracle.com/javafx/2/fxml_get_started/fxml_tutorial_intermediate.htm ) suggests at the bottom of the tutorial that it can be edited but doesn't show how this is achieved.
I have read the answers to the related questions but they are beyond my current level ofknowledge.
Can anyone show me how it can be done in as simpler way as possible please?
To save you looking up the tutorial these are the files which I've copied directly from Oracle:
Thanks in advance.
First is FXMLTableView.java
/*
* 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 fxmltableview;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class FXMLTableView extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("FXML TableView Example");
Pane myPane = (Pane)FXMLLoader.load(getClass().getResource
("fxml_tableview.fxml"));
Scene myScene = new Scene(myPane);
primaryStage.setScene(myScene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The second one is the controller:
package fxmltableview;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
public class FXMLTableViewController {
#FXML private TableView<Person> tableView;
#FXML private TextField firstNameField;
#FXML private TextField lastNameField;
#FXML private TextField emailField;
#FXML
protected void addPerson(ActionEvent event) {
ObservableList<Person> data = tableView.getItems();
data.add(new Person(firstNameField.getText(),
lastNameField.getText(),
emailField.getText()
));
firstNameField.setText("");
lastNameField.setText("");
emailField.setText("");
}
}
The third file is FormattedTableCellFactory.java
package fxmltableview;
import java.text.Format;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.text.TextAlignment;
import javafx.util.Callback;
public class FormattedTableCellFactory<S, T>
implements Callback<TableColumn<S, T>, TableCell<S, T>> {
private TextAlignment alignment;
private Format format;
public TextAlignment getAlignment() {
return alignment;
}
public void setAlignment(TextAlignment alignment) {
this.alignment = alignment;
}
public Format getFormat() {
return format;
}
public void setFormat(Format format) {
this.format = format;
}
#Override
#SuppressWarnings("unchecked")
public TableCell<S, T> call(TableColumn<S, T> p) {
TableCell<S, T> cell = new TableCell<S, T>() {
#Override
public void updateItem(Object item, boolean empty) {
if (item == getItem()) {
return;
}
super.updateItem((T) item, empty);
if (item == null) {
super.setText(null);
super.setGraphic(null);
} else if (format != null) {
super.setText(format.format(item));
} else if (item instanceof Node) {
super.setText(null);
super.setGraphic((Node) item);
} else {
super.setText(item.toString());
super.setGraphic(null);
}
}
};
cell.setTextAlignment(alignment);
switch (alignment) {
case CENTER:
cell.setAlignment(Pos.CENTER);
break;
case RIGHT:
cell.setAlignment(Pos.CENTER_RIGHT);
break;
default:
cell.setAlignment(Pos.CENTER_LEFT);
break;
}
return cell;
}
}
The fourth file is the Person class:
package fxmltableview;
import javafx.beans.property.SimpleStringProperty;
public class Person {
private final SimpleStringProperty firstName = new SimpleStringProperty("");
private final SimpleStringProperty lastName = new SimpleStringProperty("");
private final SimpleStringProperty email = new SimpleStringProperty("");
public Person() {
this("", "", "");
}
public Person(String firstName, String lastName, String email) {
setFirstName(firstName);
setLastName(lastName);
setEmail(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
and the last file is the .fxml file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.cell.*?>
<?import javafx.collections.*?>
<?import fxmltableview.*?>
<GridPane alignment="CENTER" hgap="10.0" vgap="10.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="fxmltableview.FXMLTableViewController">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<children>
<Label style="-fx-font: NORMAL 20 Tahoma;" text="Address Book" GridPane.columnIndex="0" GridPane.rowIndex="0">
</Label>
<TableView fx:id="tableView" editable="true" GridPane.columnIndex="0" GridPane.rowIndex="1">
<columns>
<TableColumn fx:id="firstNameColumn" prefWidth="100" text="First Name">
<cellValueFactory>
<PropertyValueFactory property="firstName" />
</cellValueFactory>
<cellFactory>
<FormattedTableCellFactory alignment="left">
</FormattedTableCellFactory>
</cellFactory>
</TableColumn>
<TableColumn prefWidth="100" text="Last Name">
<cellValueFactory>
<PropertyValueFactory property="lastName" />
</cellValueFactory>
<cellFactory>
<FormattedTableCellFactory alignment="left">
</FormattedTableCellFactory>
</cellFactory>
</TableColumn>
<TableColumn prefWidth="200" text="Email Address">
<cellValueFactory>
<PropertyValueFactory property="email" />
</cellValueFactory>
<cellFactory>
<FormattedTableCellFactory alignment="left">
</FormattedTableCellFactory>
</cellFactory>
</TableColumn>
</columns>
<items>
<FXCollections fx:factory="observableArrayList">
<Person email="jacob.smith#example.com" firstName="Jacob" lastName="Smith" />
<Person email="isabella.johnson#example.com" firstName="Isabella" lastName="Johnson" />
<Person email="ethan.williams#example.com" firstName="Ethan" lastName="Williams" />
<Person email="emma.jones#example.com" firstName="Emma" lastName="Jones" />
<Person email="michael.brown#example.com" firstName="Michael" lastName="Brown" />
</FXCollections>
</items>
<sortOrder>
<fx:reference source="firstNameColumn" />
</sortOrder>
</TableView>
<HBox alignment="bottom_right" spacing="10" GridPane.columnIndex="0" GridPane.rowIndex="2">
<children>
<TextField fx:id="firstNameField" prefWidth="90" promptText="First Name" />
<TextField fx:id="lastNameField" prefWidth="90" promptText="Last Name" />
<TextField fx:id="emailField" prefWidth="150" promptText="email" />
<Button onAction="#addPerson" text="Add" />
</children>
</HBox>
</children>
<columnConstraints>
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
<RowConstraints />
<RowConstraints />
</rowConstraints>
</GridPane>