javafx how to keep data on secondary window while its closed - java

question is simple i have created small program that have 2 stages the main and the secondary, the main window has a button to launch the secondary stage and the secondary stage has text field and button and label when i enter a text in the text field and pressed the button the text will be shown in the label , what i want to do is when i close the secondary stage and the program is still running i want the data to be same so when pressed button and launch the secondary stage again i will see the last result as if i never closed the secondary stage
here is the main class
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
private Stage primaryStage;
#Override
public void start(Stage primaryStage) throws Exception{
this.primaryStage=primaryStage;
mainWindow();
}
void mainWindow() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("FirstWindow.fxml"));
Parent root = loader.load();
Controller controller = loader.getController();
controller.setMain(this ,primaryStage);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}catch (IOException e){
e.printStackTrace();
}
}
public void secondaryWindow() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("SecondWindow.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root);
Stage secondaryStage=new Stage();
secondaryStage.initOwner(primaryStage);
secondaryStage.initModality(Modality.WINDOW_MODAL);
swController controller = loader.getController();
controller.setMain(this,secondaryStage);
secondaryStage.setScene(scene);
secondaryStage.show();
}catch (IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
and the secondstage control class
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import java.net.URL;
import java.util.ResourceBundle;
/**
* Created by ahmednageeb on 11/29/16.
*/
public class swController implements Initializable {
private Main main;
private Stage secondaryStage;
public void setMain(Main main, Stage secondaryStage) {
this.main = main;
this.secondaryStage = secondaryStage;}
#FXML
private Label label;
#FXML
private TextField text;
#FXML
private void change(ActionEvent event) {
String a=text.getText();
label.setText(a);
text.clear();
}
public void goBack() {
secondaryStage.close();
}
#Override
public void initialize(URL location, ResourceBundle resources) {
}
}
and finally the firststage controller
package sample;
import javafx.stage.Stage;
public class Controller {
private Main main;
private Stage primaryStage;
public void setMain(Main main,Stage primaryStage){
this.main=main;
this.primaryStage =primaryStage;
}
public void close(){
primaryStage.close();
}
public void changeWindow(){
main.secondaryWindow();
}
}

One solution could be to load the secondary window on start up but hide it. Then use the button to show it. When you close it, hide it again.
See if something like this works!
Main:
package hidepopup;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class HidePopup extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("first stage");
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
First FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="hidepopup.FXMLDocumentController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
First Controller:
package hidepopup;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
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.Label;
import javafx.stage.Stage;
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
FXMLLoader loader;
Parent root2;
Stage stage2;
#FXML
private void handleButtonAction(ActionEvent event) {
try
{
Scene scene2 = new Scene(root2);
stage2.setScene(scene2);
stage2.setTitle("second stage");
stage2.showAndWait();
}
catch(IllegalArgumentException ex)
{
stage2.show();
}
}
#Override
public void initialize(URL url, ResourceBundle rb) {
try
{
loader = new FXMLLoader(getClass().getResource("FXMLPopup.fxml"));
root2 = loader.load();
FXMLPopupController dac = (FXMLPopupController) loader.getController();
stage2 = new Stage();
}
catch (IOException ex)
{
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Second FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="hidepopup.FXMLPopupController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
Second Controller
package hidepopup;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
public class FXMLPopupController implements Initializable {
#FXML
public Label label;
#FXML
private void handleButtonAction(ActionEvent event){
label.getScene().getWindow().hide();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
The layout for both windows are exactly the same, so after you press the button you might want slide the top layout over. Also, I didn't test to see if the second stage held its data. Add a text box to the second stage and test it out. I hope this helps.

Related

How can I alter GUI elements of a stages owner?

I'm currently trying to figure out how to implement a feature in which the user clicks a button and a popup appears, and then the user enters data into that popup, clicks a confirm button, and the data becomes visible in the popups owner. I was able to make data from the owner stage carry over to the popup stage after follow Bro Code's tutorial on making controllers communicate, however getting it to work the other way around is proving troublesome. Below is a project in which I've isolated the issue to try and figure it out.
App.java
package org.example;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.util.Objects;
public class App extends Application {
public static Stage stage;
#Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(Objects.requireNonNull(getClass().getResource("primary.fxml")));
Scene scene = new Scene(root);
stage = new Stage();
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
PrimaryController.java
package org.example;
import java.io.IOException;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class PrimaryController {
#FXML
Label label;
#SuppressWarnings("unused")
public void login(ActionEvent event) throws IOException{
FXMLLoader loader = new FXMLLoader(getClass().getResource("secondary.fxml"));
Parent root = loader.load();
SecondaryController secondaryController = loader.getController();
secondaryController.stage = new Stage();
secondaryController.stage.initModality(Modality.APPLICATION_MODAL);
secondaryController.stage.initOwner(App.stage);
Scene scene = new Scene(root);
secondaryController.stage.setScene(scene);
secondaryController.stage.show();
}
public void displayMessage(String message){
label.setText(message);
}
}
SecondaryController.java
package org.example;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import java.io.IOException;
public class SecondaryController {
#FXML
TextField textField;
public Stage stage;
#SuppressWarnings("unused")
public void writeToOwner(ActionEvent event) throws IOException {
String message = textField.getText();
FXMLLoader loader = new FXMLLoader(getClass().getResource("primary.fxml"));
Parent root = loader.load();
PrimaryController primaryController = loader.getController();
primaryController.displayMessage(message);
stage.close();
}
}
primary.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.PrimaryController">
<children>
<Button layoutX="270.0" layoutY="230.0" mnemonicParsing="false" onAction="#login" text="Login" />
<Label fx:id="label" layoutX="280.0" layoutY="191.0" />
</children>
</AnchorPane>
secondary.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.SecondaryController">
<children>
<TextField fx:id="textField" layoutX="219.0" layoutY="187.0" onAction="#writeToOwner" />
</children>
</AnchorPane>
The current behavior that I get from this code is almost what I want, except when the user would submit the text, it closes the popup but doesn't change the popups owner.
In your SecondaryController, it looks like you're creating a second instance of PrimaryController, leaving the first unchanged when invoking writeToOwner().
One approach is to arrange for the controllers to see a common model, much as they share a common stage in your example. The simplest such model is a single ObservableValue, illustrated here. To see the effect,
Add a StringProperty named text to your SecondaryController and make it accessible. In writeToOwner(), simply update the text and the bound label will follow.
public class SecondaryController {
#FXML
TextField textField;
public Stage stage;
private final StringProperty text = new SimpleStringProperty();
public StringProperty textProperty() {
return text;
}
#SuppressWarnings("unused")
public void writeToOwner(ActionEvent event) throws IOException {
text.set(textField.getText());
stage.close();
}
}
In your PrimaryController, bind the label's textProperty() to the textProperty() of the SecondaryController.
public class PrimaryController {
#FXML
Label label;
public StringProperty text = new SimpleStringProperty();
#SuppressWarnings("unused")
public void login(ActionEvent event) throws IOException {
…
secondaryController.stage.initOwner(App.stage);
label.textProperty().bind(secondaryController.textProperty());
…
}
}
In practice, you'll want to avoid public access to class members.

How to transfer a container from one window to another in JavaFX

I got a Button called "Transfer" with the onclick method and a VBox with 3 Buttons in one window.
The second window only has a HBox container.
I wanna understand how to send the VBox to the HBox in the other window by pressing the transfer Button.
And what would also help is feedback regarding my code/file organization.
Main Class:
package testproject;
import javafx.application.Application;
import testproject.screen1.Screen1;
import testproject.screen2.Screen2;
import javafx.stage.Stage;
public class Main extends Application {
private Screen1 screen1;
private Screen2 screen2;
#Override
public void start(Stage primaryStage) throws Exception{
screen1 = new Screen1(this, new Stage());
screen2 = new Screen2(this, primaryStage);
}
public static void main(String[] args) {
Application.launch(args);
}
}
Screen1 Class:
package testproject.screen1;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import testproject.Main;
import java.io.IOException;
public class Screen1 {
public Screen1(Main main, Stage stage){
FXMLLoader loader = new FXMLLoader();
try {
Parent root =
loader.load(getClass().getResourceAsStream("/testproject/screen1/screen1.fxml"));
stage.setTitle("Screen 1");
stage.setScene(new Scene(root, 300, 275));
}
catch (IOException e) {
e.printStackTrace();
}
stage.show();
}
}
Screen2 Class:
package testproject.screen2;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import testproject.Main;
import java.io.IOException;
public class Screen2 {
public Screen2(Main main, Stage stage) {
FXMLLoader loader = new FXMLLoader();
try {
Parent root =
loader.load(getClass().getResourceAsStream("/testproject/screen2/screen2.fxml"));
stage.setTitle("Screen 2");
stage.setScene(new Scene(root, 300, 275));
}
catch (IOException e) {
e.printStackTrace();
}
stage.show();
}
}
Screen1Controller Class:
package testproject.screen1;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
public class Screen1Controller {
#FXML
private AnchorPane Pane1;
#FXML
private VBox VBoxScreen1;
#FXML
private Button TransferButton;
#FXML
void transferToScreen2(MouseEvent event){
}
}
Screen2Controller Class:
package testproject.screen2;
import javafx.fxml.FXML;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
public class Screen2Controller {
#FXML
private AnchorPane Pane2;
#FXML
private HBox HBoxScreen2;
}
One way I can think of is to pass a callback/consumer to the screen2 controller to let it know what to do with its node. Having said that, there can be many other approaches to this requirement.
As per my view, you dont need separate classes to load the screens. You can check the below working demo.
Main.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader2 = new FXMLLoader(getClass() .getResource("screen2.fxml"));
VBox screen2 = loader2.load();
Screen2Controller screen2Controller = loader2.getController();
Stage screen2Stage = new Stage();
Scene scene2 = new Scene(screen2);
screen2Stage.setScene(scene2);
screen2Stage.setTitle("Screen 2");
screen2Stage.setX(900);
screen2Stage.setY(100);
screen2Stage.show();
FXMLLoader loader1 = new FXMLLoader(getClass() .getResource("screen1.fxml"));
VBox screen1 = loader1.load();
Screen1Controller screen1Controller = loader1.getController();
// Set a consumer to the screen1 to let it know what to do
screen1Controller.setTransferer(screen2Controller::moveNode);
Scene scene1 = new Scene(screen1);
primaryStage.setScene(scene1);
primaryStage.setTitle("Screen 1");
primaryStage.setX(100);
primaryStage.setY(100);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
Screen1Controller.java
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import java.util.function.Consumer;
public class Screen1Controller {
#FXML
private VBox pane1;
#FXML
private VBox vBoxScreen1;
#FXML
private Button transferButton;
private Consumer<Node> transferer;
#FXML
void transferToScreen2(ActionEvent event) {
// First remove the node from the parent.
pane1.getChildren().remove(vBoxScreen1);
// Then send the node to do the other operation.
this.transferer.accept(vBoxScreen1);
}
public void setTransferer(Consumer<Node> transferer) {
this.transferer = transferer;
}
}
screen1.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<VBox fx:id="pane1" xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="com.stackoverflow.javafx.issue7.Screen1Controller"
prefHeight="400.0" prefWidth="600.0" spacing="10">
<children>
<VBox fx:id="vBoxScreen1" spacing="10" style="-fx-border-width:2px;-fx-border-color:red;-fx-background-color:yellow;" prefWidth="200" maxWidth="200" prefHeight="200">
<children>
<Button text="Button 1"/>
<Button text="Button 2"/>
<Button text="Button 3"/>
</children>
<padding>
<Insets topRightBottomLeft="10" />
</padding>
</VBox>
<Button fx:id="transferButton" text="Transfer" onAction="#transferToScreen2"/>
</children>
<padding>
<Insets topRightBottomLeft="10" />
</padding>
</VBox>
Screen2Controller.java
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
public class Screen2Controller {
#FXML
private VBox pane2;
#FXML
private HBox hBoxScreen2;
public void moveNode(Node node){
hBoxScreen2.getChildren().add(node);
}
}
screen2.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<VBox fx:id="pane2" xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="com.stackoverflow.javafx.issue7.Screen2Controller"
prefHeight="400.0" prefWidth="600.0" spacing="10">
<children>
<HBox fx:id="hBoxScreen2" spacing="10">
<padding>
<Insets topRightBottomLeft="10" />
</padding>
</HBox>
</children>
<padding>
<Insets topRightBottomLeft="10" />
</padding>
</VBox>

Why can't I see the changes in my project but I see them in the fxml file?

I have a problem with my project in JavaFX. I use SceneBuilder which saves all changes to fxml file, but when i run project I see only empty background, even the size of the working area does not change. I try to clean project and workspace but problem is the same. I have refresh project and all files and nothing, I choose "Refresh using native hooks or pooling" but i have all time this same problem. Does anyone have any other idea? I use java 13 and JavaFX 11
mainWindow.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Pane?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com /fxml/1" fx:controller="application.MainWindowController">
<children>
<Label fx:id="labelText" layoutX="286.0" layoutY="42.0" prefHeight="17.0" prefWidth="0.0" text="" />
<Button fx:id="button1" layoutX="270.0" layoutY="82.0" mnemonicParsing="false" text="OK" />
</children>
</Pane>
main.class
package application;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass()
.getResource("mainWindow.fxml").toExternalForm());
primaryStage.setTitle("Test");
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
MainWindowController class
package application;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class MainWindowController implements Initializable {
#FXML
Label labelText;
#FXML
Button button1;
#Override
public void initialize(URL location, ResourceBundle resources) {
labelText.setText("Start");
}
}
i think the problem is in your start method in main. Try this implementation instead.
#Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("mainWindow.fxml"));
primaryStage.setTitle("Test");
primaryStage.setScene(new Scene(root, 600, 400));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
This is what you expected?

JavaFX setCellValueFactory

I know, this question has been asked hundreds of times and I spent the last 3 hours reading all of them. I am writing a little Application with JavaFX (and I have done so before...). Everything is working besides putting content into my column:
#FXML public void initialize() {
exerciseColumn.setCellValueFactory(new PropertyValueFactory<Exercise, String>("name"));
}
This is my initialize method and this:
public StringProperty nameProperty() {
return name;
}
is the Property Getter for "StringProperty name". The really funny thing is, that the code is the exact copy of another project I made a while ago (I double and triple checked everything of course) that I compiled again today and that is working perfectly. I read the doc for, as it feels, half JavaFX to find a solution but it just does not make any sense. If you think you need more code to help me, then I can provide it, of course.
edit: another example with the same issue (at least I hope so)
Main:
package test;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import test.model.Exercise;
import test.view.Controller;
public class Main extends Application {
private Stage primaryStage;
private AnchorPane pane;
private ObservableList<Exercise> activeSession = FXCollections.observableArrayList();
public Main() {
activeSession.add(new Exercise("ednhzrd"));
}
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Test");
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/view.fxml"));
pane = (AnchorPane) loader.load();
Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.show();
Controller controller = new Controller();
controller.setMainApp(this);
} catch(Exception e) {
e.printStackTrace();
}
}
}
Controller:
package test.view;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import test.Main;
import test.model.Exercise;
public class Controller {
#FXML private TableView<Exercise> exerciseTable;
#FXML private TableColumn<Exercise, String> exerciseColumn;
private Main main;
public Controller() {}
#FXML
public void initialize() {
exerciseColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
}
public void setMainApp(Main main) {
this.main = main;
}
}
Exercise:
enter codepackage test.model;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Exercise {
private StringProperty name;
public Exercise(String name) {
this.name = new SimpleStringProperty(name);
}
public StringProperty nameProperty() {
return name;
}
}
fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane prefHeight="400.0" prefWidth="209.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="test.view.Controller">
<children>
<TableView fx:id="exerciseTable" layoutX="200.0" layoutY="100.0" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn fx:id="exerciseColumn" prefWidth="75.0" text="C1" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</children>
</AnchorPane>
There is no problem with your cellValueFactory. The only issue here is that you never put any items in the table. If you modify the controller to add a test item to the table:
package test.view;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import test.Main;
import test.model.Exercise;
public class Controller {
#FXML
private TableView<Exercise> exerciseTable;
#FXML
private TableColumn<Exercise, String> exerciseColumn;
private ObservableList<Exercise> activeSession = FXCollections.observableArrayList();
private Main main;
public Controller() {
}
#FXML
public void initialize() {
exerciseColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
activeSession.add(new Exercise("hrrykane"));
exerciseTable.setItems(activeSession);
}
public void setMainApp(Main main) {
this.main = main;
}
}
then you see the desired effect:

ControlsFX Border FXML wrapper not working

I am trying to create a wrapper for ControlsFX's Borders API that will work with FXML. When I run my application, I do not see any content. When I changed the TitledBorder to something else, like a Label, it worked as intended.
TitledBorder class:
package com.neonorb.commons.ui.gui.javafx;
import javafx.beans.NamedArg;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import org.controlsfx.tools.Borders;
/**
* Created by chris on 8/21/15.
*/
public class TitledBorder extends StackPane {
private StackPane contentStackPane = new StackPane();
private ObservableList<Node> children = contentStackPane.getChildren();
public TitledBorder(#NamedArg("text") String text) {
super.getChildren().add(Borders.wrap(contentStackPane).lineBorder().color(Color.BLACK).title(text).buildAll());
}
public ObservableList<Node> getChildren() {
return children;
}
}
Main fxml test:
<?import javafx.scene.layout.BorderPane?>
<?import com.neonorb.commons.ui.gui.javafx.TitledBorder?>
<?import javafx.scene.control.Label?>
<BorderPane xmlns:fx="http://javafx.com/fxml">
<center>
<TitledBorder text="hi">
<children>
<Label text="hello"/>
</children>
</TitledBorder>
</center>
</BorderPane>
Main class:
import com.neonorb.commons.Commons;
import com.neonorb.commons.MainClass;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
* Created by chris on 7/7/15.
*/
#MainClass
public class Main extends Application {
public static void main(String[] args) {
launch();
}
#Override
public void start(Stage stage) throws Exception {
Commons.init("");
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Main.fxml"));
Parent parent = fxmlLoader.load();
stage.setScene(new Scene(parent));
stage.sizeToScene();
stage.show();
}
}

Categories

Resources