I wants to create 2 table view in scene builder and first table will retrieve data from a mysql table and after which the use choose one of the rows from the first table to view more data of that particular row. How should I do it?
Edit: the closest example i got from google is http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/
But the data is not retrieve from database. I had added my codes below and the error message that i gotten from eclipse.
public class MainApp extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
private ObservableList<Food> foodData = FXCollections.observableArrayList();
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Canteen Management System");
try {
// Load the root layout from the fxml file
FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
// Exception gets thrown if the fxml file could not be loaded
e.printStackTrace();
}
showPersonOverview();
}
public void showPersonOverview() {
try {
// Load the fxml file and set into the center of the main layout
// FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("cams/order/view/OrderMenu.fxml"));
// AnchorPane overviewPage = (AnchorPane) loader.load();
// rootLayout.setCenter(overviewPage);
// FoodController controller = loader.getController();
FoodController controller = (FoodController) replaceSceneContent("cams/order/view/OrderMenu.fxml");
controller.setMainApp(this);
} catch (Exception ex) {//IOException e
Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
// Exception gets thrown if the fxml file could not be loaded
//e.printStackTrace();
}
}
private Initializable replaceSceneContent(String fxml) throws Exception {
FXMLLoader loader = new FXMLLoader();
InputStream in = MainApp.class.getResourceAsStream(fxml);
loader.setBuilderFactory(new JavaFXBuilderFactory());
loader.setLocation(MainApp.class.getResource(fxml));
AnchorPane page;
try {
page = (AnchorPane) loader.load(in);
} finally {
in.close();
}
Scene scene = new Scene(page, 1280, 800);
primaryStage.setScene(scene);
primaryStage.sizeToScene();
return (Initializable) loader.getController();
}
public ObservableList<Food> getPersonData() {
return foodData;
}
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
}
public class FoodController implements Initializable{
#FXML
private TableView<Food> tblViewer = new TableView<Food>();
#FXML
private TableColumn<Food, String> foodPicture;
#FXML
private TableColumn<Food, String> foodName;
#FXML
private TableColumn<Food, Integer> foodPrice;
#FXML
private TableColumn<Food, Integer> foodID;
private MainApp mainApp;
#Override
public void initialize(URL url, ResourceBundle rb) {
// foodID.setCellValueFactory(new PropertyValueFactory<Food, Integer> ("id"));
// foodPrice.setCellValueFactory(new PropertyValueFactory<Food, Integer>("price"));
foodName.setCellValueFactory(new PropertyValueFactory<Food, String>("name"));
foodPicture.setCellValueFactory(new PropertyValueFactory<Food, String>("picture"));
tblViewer.getItems().setAll(getAllFoodInfo());
}
public List<Food> getAllFoodInfo(){
Connection conn;
List ll = new LinkedList();
Statement st;
ResultSet rs;
String url = "jdbc:mysql://localhost/cams";
String user = "root";
String pass = "admin";
String driver = "com.mysql.jdbc.Driver";
try{
Class.forName(driver);
conn = DriverManager.getConnection(url, user, pass);
st = conn.createStatement();
String recordQuery = ("Select * from food");
rs = st.executeQuery(recordQuery);
while(rs.next()){
Integer id = rs.getInt("id");
double price = rs.getDouble("price");
String name = rs.getString("name");
String picture = rs.getString("picture");
ll.add(new Food(id, price, name, picture));
System.out.println(id +","+ price +","+ name +","+ picture +" "+"added.");
}
}catch(ClassNotFoundException | SQLException ex){
Logger.getLogger(FoodController.class.getName()).log(Level.SEVERE, null, ex);
}
return ll;
}
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
// Add observable list data to the table
tblViewer.setItems(mainApp.getPersonData());
}
}
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start >method
at >com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:403)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: Location is not set.
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2021)
at cams.order.main.MainApp.start(MainApp.java:37)
at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:319)
at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:215)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:176)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:176)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
... 1 more
Related
I'm trying to get the username that somebody uses to Login, then insert it into a db when somebody makes an apointment
This is the "Programaritest" table
ID_programare | Nume | Prenume | Data | Ora | Departament | Doctor | Username | Nr_telefon
This is the accounts table where the username is saved as Unique
ID_account | Username | Password | Email | Nume | Prenume | Admin
The input of the username is gotten from fxml via a textfield, in GetUsername method, I've pointed it out below
package LicentaApp;
public class LogareController implements Initializable {
public LoginVerifier loginVerifier = new LoginVerifier();
#FXML
private TextField Numeutilzator; Numeutilziator is the username that I am talking about
#FXML
private PasswordField Parola;
#FXML
private Label Stare;
#Override
public void initialize(URL location, ResourceBundle resources) {
if (loginVerifier.Conexiune()) {
Stare.setText("");
} else {
Stare.setText("Conexiune nereusita!");
}
}
public void Autentificare (ActionEvent event) {
try {
if(loginVerifier.testaredate(Numeutilzator.getText(), Parola.getText())) {
Stare.setText("Autentificare reusita !");
((Node)event.getSource()).getScene().getWindow().hide();
Stage StagePrincipala= new Stage();
FXMLLoader incarcator= new FXMLLoader();
Pane parinte = incarcator.load(getClass().getResource("/LicentaApp/Meniu.fxml").openStream());
Scene scene = new Scene(parinte);
scene.getStylesheets().add(getClass().getResource("Style1212.css").toExternalForm());
StagePrincipala.setScene(scene);
StagePrincipala.show();
}
else {
Stare.setText("Nume de utilizator sau parola incorect");
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#FXML
public void Inregistrare(ActionEvent event) {
try {
((Node)event.getSource()).getScene().getWindow().hide();
Stage PS= new Stage();
FXMLLoader incarcator= new FXMLLoader();
Pane parinte = incarcator.load(getClass().getResource("/LicentaApp/InregistrareUser.fxml").openStream());
Scene scena = new Scene(parinte);
scena.getStylesheets().add(getClass().getResource("Style1212.css").toExternalForm());
PS.setScene(scena);
PS.show();
} catch (Exception e) {
}
*Here I m calling the function that I made in AddProgramareController and
passing it the username located in Numeutilzator*
#FXML
public void GetUsername() {
try {
FXMLLoader loader=new FXMLLoader(getClass().getResource("/LicentaApp/AddProgramare.fxml"));
Parent root = (Parent) loader.load();
AddProgramareController AddPr=loader.getController();
AddPr.MyUsername(Numeutilzator.getText());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Here is the class that adds the apointment to the db, I've pointed out whre the function for the username is, in the code below (I've added all the code so you can understand better what's going on)
package LicentaApp;
public class AddProgramareController implements Initializable {
ObservableList Timestamp=FXCollections.observableArrayList();
#FXML
private TextField Nume;
#FXML
private TextField Prenume;
#FXML
private TextField Ora;
#FXML
private DatePicker Data;
#FXML
private TextField Departament;
#FXML
private TextField Doctor;
#FXML
private TextField Nr_telefon;
#FXML
private TextField Numeutilizator;
public void initialize(URL location, ResourceBundle resources) {
}
*This is the function that I'll call in GetUsername from LogareController
public void MyUsername(String Numeutilizator) {
this.Numeutilizator.setText(Numeutilizator);
}
#FXML
private void AddProgramare(ActionEvent event) throws SQLException, IOException {
String Interogare1= "INSERT INTO programaritest(Nume,Prenume,Data,Ora,Departament,Doctor,Nr_telefon,Numeutilizator) VALUES(?,?,?,?,?,?,?,?)";
String nume=Nume.getText();
String prenume=Prenume.getText();
LocalDate data=Data.getValue();
String ora=Ora.getText();
String departament=Departament.getText();
String doctor=Doctor.getText();
String nr_telefon=Nr_telefon.getText();
String numeutilizator=Numeutilizator.getText();
try {
ConectaredB ConectaredB=new ConectaredB();
Connection conexiune=ConectaredB.logareDB();
PreparedStatement MG = conexiune.prepareStatement(Interogare1);
MG.setString(1, nume);
MG.setString(2, prenume);
MG.setDate(3, Date.valueOf(data));
MG.setString(4, ora);
MG.setString(5, departament);
MG.setString(6, doctor);
MG.setString(7, nr_telefon);
MG.setString(8, numeutilizator);
MG.executeUpdate();
// ...
} catch (SQLException exceptie1) {
exceptie1.printStackTrace();
}
}
}
The error message that I am getting when trying to add a new appointment is:
Caused by: java.lang.NullPointerException
at LicentaApp.AddProgramareController.AddProgramare(AddProgramareController.java:103)
At line 103: String numeutilizator=Numeutilizator.getText();
So the data from numeutilizator is not what the input is putting out, that means i failed passing the parameter from a controller to another.
P.S I have followed this Passing Parameters JavaFX FXML, couldn't figure it out.
There are multiple reasons this exception could happen:
The controller instance is not used with a fxml
the fxml the controller instance is used with does not contain a element with fx:id="Numeutilizator"
Therefore I'll post a simple example that gets a single string from a scene designed using fxml:
Application class
#Override
public void start(Stage primaryStage) {
Button btn = new Button("Get input");
btn.setOnAction((ActionEvent event) -> {
FXMLLoader loader = new FXMLLoader(getClass().getResource("dialog.fxml"));
Parent p;
try {
p = loader.load();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
DialogController controller = loader.getController();
Stage stage = new Stage(StageStyle.UTILITY);
stage.initOwner(primaryStage);
stage.setScene(new Scene(p, 100, 100));
stage.showAndWait(); // display window and wait for close
if (controller.isCanceled()) {
System.out.println("canceled");
} else {
System.out.println("input submitted: " + controller.getText());
}
});
StackPane root = new StackPane(btn);
Scene scene = new Scene(root, 300, 300);
primaryStage.setScene(scene);
primaryStage.show();
}
dialog.fxml
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="fxml.DialogController">
<children>
<TextField fx:id="input"/>
<Button text="submit" onAction="#submit"/>
<Button text="cancel" onAction="#cancel"/>
</children>
</VBox>
fxml.DialogController
public class DialogController {
#FXML
private TextField input;
private boolean canceled = true;
public boolean isCanceled() {
return canceled;
}
public final String getText() {
return input.getText();
}
private void close(boolean canceled) {
this.canceled = canceled;
input.getScene().getWindow().hide();
}
#FXML
private void submit() {
close(false);
}
#FXML
private void cancel() {
close(true);
}
}
Instead of retrieving the info you could also pass a object containing logic to handle certain events to the controller before showing the fxml's content.
I guess it's a simple question but it was a long day at work and I cant figure the right way out right now.
I have 3 FXML files.
Menge.fxml
Start.fxml
Suche.fxml
I'm starting from Main.java as usual
#Override
public void start(Stage primaryStage) {
try {
AnchorPane root = (AnchorPane)FXMLLoader.load(getClass().getResource("Start.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
Inside the MainController I've got the following ActionListener
#FXML
void actionListenerMenge(ActionEvent event) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Menge.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.setScene(new Scene(root1));
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
So I'm opening the Suche.fxml via the FXMLLoader.
Now there is a button inside my Suche-View which opens another scene for where the user should search the specific data record.
#FXML
void actionListenerSuche(ActionEvent event) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Suche.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.setScene(new Scene(root1));
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
SucheController where I'm loading the MengeController again via FXMLLoader
FXMLLoader loader = new FXMLLoader(getClass().getResource("Menge.fxml"));
try {
Parent root = loader.load();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MengeController controller = (MengeController)loader.getController();
I want to edit the value inside a TextField # the MengeController to update the View from my Menge.fxml. But if I do
controller.setTextFieldValue("abc") it's not updating. I know it must be because I've loaded the MengeController twice and so there are two instances. But I don't figure out how to load it only once or inject it to update my TextField inside MengeController.
Option 1: Observe a property in the SucheController:
Define a property in the SucheController. Instead of trying to get a reference back to the MengeController, just set the property:
public class SucheController {
private final ObjectProperty<Foo> foo = new SimpleObjectProperty<>();
public ObjectProperty<Foo> fooProperty() {
return foo() ;
}
public final Foo getFoo() {
return fooProperty().get();
}
public final void setFoo(Foo foo) {
fooProperty().set(foo);
}
// ...
#FXML
private void someHandlerMethod() {
// FXMLLoader loader = new FXMLLoader(getClass().getResource("Menge.fxml"));
// try {
// Parent root = loader.load();
// } catch (IOException e) {
// e.printStackTrace();
// }
// MengeController controller = (MengeController)loader.getController();
setFoo(...);
}
}
Obviously replace Foo with a type that represents whatever data the user is providing here, and name the property and methods accordingly...
Now when you load Suche.fxml, just get a reference to the controller and observe the property. Then you can just update the text field directly in MengeController itself:
#FXML
void actionListenerSuche(ActionEvent event) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Suche.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
SucheController sucheController = loader.getController();
sucheController.fooProperty().addListener((obs, oldFoo, newFoo) -> {
someTextField.setText(newFoo.getSomeValue());
// ...
});
Stage stage = new Stage();
stage.setScene(new Scene(root1));
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
Option 2: Pass a reference to the MengeController directly to the SucheController:
Another option, which I don't like as much as it involves more coupling between the controllers, is simply to pass a reference to the MengeController to the SucheController:
public class SucheController {
private MengeController mengeController ;
public void setMengeController(MengeController mengeController) {
this.mengeController = mengeController ;
}
// ...
#FXML
private void someHandlerMethod() {
mengeController.setTextFieldValue("abc");
}
}
and then the code in your MengeController that loads Suche.fxml looks like
#FXML
void actionListenerSuche(ActionEvent event) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Suche.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
SucheController sucheController = fxmlLoader.getController();
sucheController.setMengeController(this);
Stage stage = new Stage();
stage.setScene(new Scene(root1));
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
How can i add an item to an already existing ListView from a different Stage (Window).
Basically i just want to add Text to the ListView from Window 2 to the ListView in Window 1.
Thanks in advance.
Sorry i forgot this is what i've got so far in my controller class: (im a beginner in javafx ..)
(below i try to add a String to the ListView but this doesnt work...and i dont know why )
public class ClientGUIController implements Initializable {
#FXML private Text usernameText;
#FXML private Button cancelButtonNewDate;
#FXML private TextField newDateTitel,newDateJahr;
#FXML private TextArea newDateNotiz;
#FXML private ComboBox<String> newDateTag,newDateMonat,newDateStunde,newDateMinute;
#FXML private ListView<String> terminListView;
private ObservableList<String> termine =
FXCollections.observableArrayList();
private ObservableList<String> listItems = FXCollections.observableArrayList("Add Items here");
#Override
public void initialize(URL location, ResourceBundle resources) {
}
public Text getUsernameText() {
return usernameText;
}
public void setUsernameText(String username ) {
this.usernameText.setText(username);
terminListView.setItems(listItems);
listItems.add("test");
}
public void newDate() {
Stage newDate = new Stage();
Parent root;
try {
root = FXMLLoader.load(getClass().getResource("newDate.fxml"));
// FXMLLoader loader = new FXMLLoader();
// root = (Parent) loader.load(getClass().getResource("NewDate.fxml").openStream());
} catch (IOException e) {
e.printStackTrace();
return;
}
Scene sceneNewDate = new Scene(root);
// sceneNewDate.getStylesheets().add(getClass().getResource("Style.css").toExternalForm());
newDate.setTitle("Neuer Termin");
newDate.setScene(sceneNewDate);
newDate.show();
}
public void createNewDate() throws IOException {
// Termine meinTermin = new Termine(Integer.parseInt(newDateTag.getValue()), Integer.parseInt(newDateMonat.getValue()), Integer.parseInt(newDateJahr.getText()), newDateTitel.getText(), newDateNotiz.getText(),
// Integer.parseInt(newDateStunde.getValue()), Integer.parseInt(newDateMinute.getValue()));
//Add item to ListView
listItems.add("test"); <- this doesnt work
}
public void closeDialogue(){
Stage stage = (Stage) cancelButtonNewDate.getScene().getWindow();
stage.close();
}
}
One way to do this is to pass listItems to the controller for newDate.fxml, so it can just add to that list. So, assuming the controller class for newDate.fxml is NewDateController, you would do something like:
public class NewDateController {
private ObservableList<String> data ;
public void setData(ObservableList<String> data) {
this.data = data ;
}
// other code as before...
// button handler:
#FXML
private void handleButtonPress() {
data.addItem("test");
}
}
Then in your ClientGUIController, load the fxml like this:
public void newDate() {
Stage newDate = new Stage();
Parent root;
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("newDate.fxml"));
root = loader.load();
NewDateController controller = loader.getController();
controller.setData(listItems);
} catch (IOException e) {
e.printStackTrace();
return;
}
Scene sceneNewDate = new Scene(root);
newDate.setTitle("Neuer Termin");
newDate.setScene(sceneNewDate);
newDate.show();
}
Working with SceneBuilder. I have 2 stages, each one with a controller: stage1Controller,stage2Controller.
Stage1Controller :
public class Stage1Controller {
#FXML
private MenuItem translate;
#FXML
private Menu file;
#FXML
private Menu edit;
#FXML
private Menu help;
#FXML
private void handleTranslate (ActionEvent event){
translateFirstStage();
//HOW TO ACCESS THE stage2Controller setLabel()??
}
private void translateFirstStage(){
file.setText("Fichier");
edit.setText("Modifier");
help.setText("Aide");
}
}
Stage2Controller:
public class Stage2Controller {
#FXML
private Label lb;
private void setLabel(String string){
lb.setText("string");
}
}
Here is how both fxml files are loaded in Main.java class using 2 methods (called in Start(Stage primaryStage) method):
public void firstStage() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/stage1.fxml"));
rootLayout = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public void secondStage() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/stage2.fxml"));
XD = (AnchorPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(XD);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
The handleTranslate(ActionEvent event) method is used as an OnAction method for the MenuItem translate in the first Stage, it translates the view in both stages.
How Can i put setLabel in handleTranslate Method ? Thanks
The "quick and dirty" way is to give the Stage1Controller a reference to the Stage2Controller:
public class Stage1Controller {
private final Stage2Controller stage2Controller ;
public void setStage2Controller(Stage2Controller stage2Controller) {
this.stage2Controller = stage2Controller ;
}
// ...
#FXML
private void handleTranslate (ActionEvent event){
translateFirstStage();
stage2Controller.setLabel(...);
}
// other code as before ...
}
Now in your main app:
public class MainApp extends Application {
private Stage1Controller stage1Controller ;
private Stage2Controller stage2Controller ;
#Override
public void start(Stage primaryStage) {
firstStage();
secondStage();
stage1Controller.setStage2Controller(stage2Controller);
// ...
}
public void firstStage() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/stage1.fxml"));
rootLayout = (BorderPane) loader.load();
stage1Controller = loader.getController();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public void secondStage() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/stage2.fxml"));
XD = (AnchorPane) loader.load();
stage2Controller = loader.getController();
// Show the scene containing the root layout.
Scene scene = new Scene(XD);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
// ...
}
A more robust approach to this, though, is to let both controllers access a shared model class, storing the data. If you represent the data using JavaFX observable properties, the controllers can listen for changes on the properties they care about. For example:
public class Model {
private final StringProperty text = new SimpleStringProperty("Initial text...");
public StringProperty textProperty() {
return text ;
}
public final void setText(String text) {
textProperty().set(text);
}
public final String getText() {
return textProperty().get();
}
// other properties as needed...
}
Now your controllers will look like this:
public class Stage1Controller {
private Model model ;
public void setModel(Model model) {
this.model = model ;
}
#FXML
private void handleTranslate (ActionEvent event){
translateFirstStage();
model.setText(...); // value will appear in stage2 controller's label!
}
// ...
}
and
public class Stage2Controller {
#FXML
private Label lb ;
private Model model ;
public void setModel(Model model) {
lb.textProperty().unbind();
this.model = model ;
lb.textProperty().bind(model.textProperty());
}
// ...
}
And in this case your main app looks like:
public class MainApp extends Application {
private final Model = new Model();
#Override
public void start(Stage primaryStage) {
// ...
}
public void firstStage() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/stage1.fxml"));
rootLayout = (BorderPane) loader.load();
Stage1Controller controller = loader.getController();
controller.setModel(model);
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public void secondStage() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/stage2.fxml"));
XD = (AnchorPane) loader.load();
Stage2Controller controller = loader.getController();
controller.setModel(model);
// Show the scene containing the root layout.
Scene scene = new Scene(XD);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
After updating to Java 8, i got problems displaying content of list view
public class TestController extends AnchorPane implements Initializable {
#FXML
private ListView<String> listView;
#Override
public void initialize(URL url, ResourceBundle rb) {
}
public void setApp() {
setContent();
}
/**
* Set content in list
*/
private void setContent() {
ObservableList<String> items = FXCollections.observableArrayList();
items.add("1");
items.add("2");
listView.setItems(items);
}
}
With Java 7 this gives me a list with values. After update to java 8, it gives me a empty frame.
Thanks James_D, here is the code you asked for
public void goToTest() {
try {
TestController test = (TestController) replaceSceneContent("/fxml/test.fxml");
test.setApp();
} catch (Exception ex) {
System.out.println("Error loading: " + ex + " - " + ex.getMessage());
}
}
private Initializable replaceSceneContent(String fxml) throws Exception {
FXMLLoader loader = new FXMLLoader();
InputStream in = MainApp.class.getResourceAsStream(fxml);
loader.setBuilderFactory(new JavaFXBuilderFactory());
loader.setLocation(MainApp.class.getResource(fxml));
AnchorPane page;
try {
page = (AnchorPane) loader.load(in);
} finally {
in.close();
}
Scene scene = new Scene(page);
stage.setScene(scene);
stage.sizeToScene();
stage.setResizable(resizable);
return (Initializable) loader.getController();
}
listView = new ListView<>(items);
will not work; it will create a new ListView and populate it, whereas what you want to do is populate the ListView you created in your FXML.
listView.setItems(items);
is the correct code.
(I assume you really have public class TestController implements Initializable, not public class test implements Initializable.)
So the following should work:
private void setContent() {
ObservableList<String> items = FXCollections.observableArrayList();
items.add("1");
items.add("2");
listView.setItems(items);
}
Your FXMLLoader code is a little unusual in that you set a location (URL) but then use the load(InputStream) method to load. I'd be surprised if this fixed it, but the usual way would be:
private Initializable replaceSceneContent(String fxml) throws Exception {
FXMLLoader loader = new FXMLLoader();
// not needed:
// InputStream in = MainApp.class.getResourceAsStream(fxml);
// Not really needed, this is the default:
loader.setBuilderFactory(new JavaFXBuilderFactory());
loader.setLocation(MainApp.class.getResource(fxml));
AnchorPane page;
// instead of this:
// try {
// page = (AnchorPane) loader.load(in);
// } finally {
// in.close();
// }
// just this (since you have set the location):
page = loader.load();
Scene scene = new Scene(page);
stage.setScene(scene);
stage.sizeToScene();
stage.setResizable(resizable);
return (Initializable) loader.getController();
}
(Random guess: did you accidentally make listView static in the Controller?)