Ari
Ari

Reputation: 4969

JavaFX - Weird Behavior When Adding Node To Parent

I have created a simple app to simulate dynamic node creation with JAVAFX. This app has the ability to create a new window whenever user want it by clicking the "New" button. User can add a new node which is TitledPane to the window by clicking "Add Task" button and then clicking "Add" button on the dialog window.

There are an unexpected behavior which I want to fix. This app is only add new node (TitledPane in this case) to the last created window. And the all of the nodes on the previous window will vanish.

You can see the following video to better understand what I mean.

VIDEO

https://youtu.be/eaWmu3zuuhE


NETBEANS PROJECT

Just in case you want to play with it.

https://drive.google.com/file/d/0B4Sbb8Ym-lcZLUIyWHV5ZXRSZE0/view?usp=sharing


CODES:

TasksList.java

package taskslist;


import javafx.application.Application;
import javafx.scene.Parent;
import javafx.stage.Stage;

public class TasksList extends Application {

    DisplayWhich display = new DisplayWhich();
    Stage primaryStage;
    Parent startWindow;

    @Override
    public void start(Stage primaryStage) throws Exception {
        this.primaryStage = primaryStage;
        initStart();
    }

    private void initStart(){  
             display.showDialogWindow();
    }   

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

}

TheList.java

package taskslist.view;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import taskslist.DisplayWhich;

public class TheList extends BorderPane {
    public static VBox listWrapper;
    public static ScrollPane listScroller;
    public ObservableList<TitledPane> tasks;
    private List<String> titles = new ArrayList<>();

    public TheList(){
        tasks = FXCollections.observableArrayList();
        listWrapper = new VBox(5);
        listScroller = new ScrollPane(listWrapper);  
    }

    public void setTitles(String... title){
        titles = Arrays.asList(title);
    }

    public List<String> getTitles(){
        return titles;
    }

    public void loadSavedList(){                                                  
        for(int i=0; i<getTitles().size();i++){ 
            String ttlString = getTitles().get(i);
            this.createTask(ttlString);            
        }        
        // Display Tasks
        listWrapper.getChildren().addAll(this.tasks);
    }

    // Dialong for adding a new task and also editing a task
    private void addTaskDialog(){        
        GridPane container = new GridPane();
        Scene scene = new Scene(container, 150, 50);
        Stage addNewTask = new Stage();
        addNewTask.initModality(Modality.APPLICATION_MODAL);
        addNewTask.setTitle("Add Task");  

        TextField title = new TextField();                                                                                        

        Button confirm = new Button("Add");                                                      

        // Create Task
        confirm.setOnAction((ev) -> {
            String ttlString = title.getText();                   
            this.createTask(ttlString);             
            listWrapper.getChildren().clear();
            listWrapper.getChildren().addAll(this.tasks);           
            addNewTask.close();                     
        }); 

        container.add(title, 0, 1);       
        container.add(confirm, 0, 5);  

        addNewTask.setScene(scene);
        addNewTask.showAndWait();
    }


    // Assemble all this.tasks list components
    public void render(){       
        setCenter(listScroller);
        loadSavedList();
        Button newProject = new Button("New");                                                                    
        Button addTask = new Button("Add Task");

        BorderPane listBottom = new BorderPane();
        HBox bottomLeft = new HBox();
        bottomLeft.getChildren().add(newProject);
        listBottom.setLeft(bottomLeft);                
        HBox bottomRight = new HBox();
        bottomRight.getChildren().add(addTask);
        listBottom.setRight(bottomRight);  

        newProject.setOnAction((evt) -> {
            DisplayWhich display = new DisplayWhich();
            display.showDialogWindow();
        });

        addTask.setOnAction((e) -> {
            addTaskDialog();
        });    

        setBottom(listBottom);
    }

    // Cteate task from strings
    private void createTask(String... strings){
        String taskTitle = strings.length > 0 ? strings[0] : "";
        TitledPane task = new TitledPane();
        task.setPrefWidth(647);
        task.setExpanded(false);
        task.setText(taskTitle);        
        this.tasks.add(task);            
    }    
}

NewDialog.java

package taskslist.view;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import taskslist.DisplayWhich;

public class NewDialog {
    DisplayWhich display = new DisplayWhich();
    Stage stage = new Stage();
    Parent startWindow = new AnchorPane();

    @FXML
    private Button cancelNew;
    @FXML
    private Button confirmCreation;
    /**
     * Initializes the controller class.
     */
    @FXML
    private void initialize() {
    }  

    @FXML
    private void cancelNewCreation(ActionEvent event) {
       ((Stage)cancelNew.getScene().getWindow()).close();
    }

    @FXML
    private void confirmCreateNew(ActionEvent event) {
        ((Stage)confirmCreation.getScene().getWindow()).close();        
        TheList wrap = new TheList();
        TheWindow window = new TheWindow();
        window.makeWindow(wrap); 
        wrap.setTitles("one", "two", "three", "four");
        wrap.render();
    }          
}

DisplayWhich.java

package taskslist;

import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import taskslist.view.TheList;

public class DisplayWhich {
    Stage stage = new Stage();
    Parent startWindow = new AnchorPane(); 

    public DisplayWhich(){}

    public Stage showDialogWindow(){ 
        try {
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.setTitle("Create New Project");
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(getClass().getResource("/taskslist/view/newDialog.fxml"));        
            startWindow = loader.load();            
            Scene scene = new Scene(startWindow);            
            stage.setScene(scene);
            stage.setOnCloseRequest((event) -> {
                System.out.println("test");
            });
            stage.showAndWait();
        } catch (IOException ex) {
            ex.printStackTrace();
        }   
        return stage;
    }
}

TheWindow.java

package taskslist.view;

import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TheWindow {
    public TheWindow(){}

    public void makeWindow(BorderPane group) {
        Stage mainWindow = new Stage();
        Scene scene = new Scene(group, 650, 550);
        mainWindow.setScene(scene);
        mainWindow.setTitle("Task List");
        mainWindow.centerOnScreen();        
        mainWindow.show();
    }    
}

Why that weird behavior happening and how to fix it so it only adds new node to the same window where the clicked "Add Task" button is located?

Upvotes: 0

Views: 103

Answers (1)

Sergey Grinev
Sergey Grinev

Reputation: 34498

These fields should not be static:

public static VBox listWrapper;
public static ScrollPane listScroller;

Upvotes: 1

Related Questions