2017-07-29 104 views
0

我創建了一個簡單的應用程序來模擬使用JAVAFX創建動態節點。 這個應用程序可以創建一個新的窗口,每當用戶需要它通過點擊「新建」按鈕。 用戶可以通過單擊「添加任務」按鈕然後單擊對話框窗口上的「添加」按鈕來添加一個TitledPane節點。JavaFX - 向父節點添加節點時的奇怪行爲

有一個我想解決的意外行爲。這個應用程序只是添加新的節點(在這種情況下是TitledPane)到最後創建的窗口。 而前一個窗口中的所有節點都將消失。

你可以看到下面的視頻來更好地理解我的意思。

VIDEO

https://youtu.be/eaWmu3zuuhE


NetBeans項目

以防萬一你想用它玩。

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(); 
    }  
} 

爲什麼會發生奇怪的行爲以及如何修復它,因此它只會將新節點添加到單擊「添加任務」按鈕所在的同一窗口中?

回答

1

這些字段不應是靜態的:

public static VBox listWrapper; 
public static ScrollPane listScroller; 
+0

呵呵,沒注意到。多可惜.. – KeepMove