当前位置: 首页 > 知识库问答 >
问题:

JavaFX-向父节点添加节点时的奇怪行为

邓声
2023-03-14

我创建了一个简单的应用程序来模拟JAVAFX的动态节点创建。这个应用程序能够通过单击“新建”按钮在用户需要的时候创建一个新窗口。用户可以通过单击“添加任务”按钮,然后单击对话框窗口上的“添加”按钮,将标题窗格的新节点添加到窗口中。

我想修复一个意外行为。此应用程序仅将新节点(在本例中为TitledPane)添加到最后创建的窗口。并且上一个窗口上的所有节点都将消失。

你可以看下面的视频来更好地理解我的意思。

视频

https://youtu.be/eaWmu3zuuhE

NETBEANS项目

以防你想玩它。

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

代码:

任务列表。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);
    }

}

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

显示哪个。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;
    }
}

窗户。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个答案

纪畅
2023-03-14

这些字段不应是静态的:

public static VBox listWrapper;
public static ScrollPane listScroller;
 类似资料:
  • 我有一个具有必要字段的窗格扩展类。它将是“大门”。 调用控制器从FXML加载节点树,并将其作为子级附加到“gate”对象 然后创建并显示一个以“gate”为根节点的新场景。 新的窗口控制器有一个对FXML根节点(“gate”的直接子节点)的引用,他所需要做的就是在其上使用.getparent()来获取“gate”。 但管他呢!它返回null!我做错了什么?我应该通过FXMLLoader设置一个不同

  • 我在运行时无法将节点添加回。 我想做的是,当用户点击一个按钮时,当前节点存储在

  • 我需要在XML中保留很少的值,并且需要通过XSLT添加新的节点。 价值需要保留,新的选项需要添加。 如何实现这一点。下面是我的代码。 有人能帮忙吗? 谢谢

  • 我正在将XML导入Access数据库。在转换过程中,数据之间的所有关系都会丢失。使用XSLT,我通过子节点将ID永久化。使用它,其中Id是添加到子节点的父元素: 我使用这种方法遇到的问题是父节点之外还有其他元素也具有元素或其变体,例如或类似的东西。当我尝试在上面的代码之外使用它时,的一些实例在以前的节点中丢失了。 很抱歉,我不知道在这里使用合适的语言,因为我对XSLT/XML不太熟悉。。。但我试图

  • 如果我没弄错的话,树通常是一个列表,其中的元素按特定顺序排列。孩子们不在他们自己的子列表中,他们都在同一个列表中。 所以,我试图创建一个Tree类,其中包含TreeNodes(类)使用Tree类中的List。 我如何跟踪父母/孩子/叶子?如果父母“父母1”,有两个孩子“孩子A”和“孩子B”,我如何将他们联系在一起?

  • 我正在尝试构建一个在JavaFX中实现群聊的聊天应用程序。我想在边框窗格内创建一个滚动窗格,该窗格将包含用户所属的所有组。当用户加入时,需要将组图标(ImageViews)动态添加(在场景生成器中无法完成)到滚动窗格(在HBox内)。 目前,我正在使用一个SceneController类,该类负责所有阶段和场景更改。 我已经创建了一个FXML文件(使用场景生成器),其中包含一个边框窗格和一个滚动窗