簡體   English   中英

在 JavaFX 中動態添加節點

[英]Dynamically adding nodes in JavaFX

我正在嘗試構建一個在 JavaFX 中實現群聊的聊天應用程序。 我想在邊界窗格內制作一個滾動窗格,該窗格將包含用戶所屬的所有組。 當用戶加入組圖標 (ImageViews) 時,需要將其動態添加(無法在 Scene Builder 中完成)到滾動窗格(在 HBox 內部)。

在此處輸入圖片說明

目前我正在使用負責所有舞台和場景更改的 SceneController 類。

package com.ong.Controllers;

import com.ong.Main;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;

import java.io.IOException;
import java.util.HashMap;

public class ScreenController {
    private static HashMap<String, Scene> screenMap = new HashMap<>();
    private static Stage main;

    public ScreenController(Stage _main){
        main = _main;
    }

    public static void addScreen(String name, FXMLLoader fxmlLoader){
        Scene scene = null;
        try {
            scene = new Scene(fxmlLoader.load());
        } catch (IOException e) {
            e.printStackTrace();
        }
        screenMap.put(name,scene);
    }

    public static void addScene(String name, Scene scene){
        screenMap.put(name,scene);
    }

    public static void removeScreen(String name){
        screenMap.remove(name);
    }

    public static void setMinimumDimensions(int width, int height){
        main.setMinWidth(width);
        main.setMinHeight(height);
    }

    public static void setMaximized(boolean full){
        main.setMaximized(full);
    }

    public static void activate(String name){
        main.setScene(screenMap.get(name));
        main.getIcons().add(new Image(Main.class.getResource("Images/not_logo.png").toString()));
        main.setTitle(name);
        main.show();
    }
}

我已經創建了一個 FXML 文件(使用場景構建器),其中包含邊框窗格和滾動窗格作為頂級子項。

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<BorderPane fx:id="borderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1080.0" prefWidth="1920.0" xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.ong.Controllers.HomepageController">
   <top>
      <ScrollPane fx:id="groupsMenuScrollPane" hbarPolicy="NEVER" prefHeight="62.0" prefWidth="1920.0" stylesheets="@../CSS/groups_menu.css" vbarPolicy="NEVER" BorderPane.alignment="CENTER" />
   </top>
</BorderPane>

我的計划是將所有組(初始化時)填充到頁面控制器中的滾動窗格。

package com.ong.Controllers;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.shape.Circle;

import java.net.URL;
import java.util.ResourceBundle;

public class HomepageController implements Initializable {

    @FXML
    private ScrollPane groupsMenuScrollPane;

    @FXML
    private BorderPane borderPane;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        final ImageView imageView = new ImageView("com/ong/Images/not_logo.png");
        final Circle clip = new Circle(300, 200, 200);
        imageView.setClip(clip);

        HBox hbox = new HBox();
        hbox.getChildren().add(imageView);

        groupsMenuScrollPane.setContent(hbox);
        borderPane.setTop(groupsMenuScrollPane);

        Scene scene = new Scene(borderPane);

        ScreenController.addScene("Homepage", scene);
        ScreenController.activate("Homepage");
    }
}

我已經嘗試使用更新的邊框窗格創建場景,但出現錯誤“邊框窗格已設置為另一個場景的根”。 我還嘗試直接更改現有場景的根,但在這種情況下我得到了 NullPointerException。

您能否建議將節點動態添加到滾動窗格的最佳方法。 我也將感謝有關項目結構的評論。

您能否建議將節點動態添加到滾動窗格的最佳方法。

您需要對ScrollPane的內容(在本例中為HBox )的引用,以及向其添加內容的方法:

public class HomepageController implements Initializable {

    @FXML
    private ScrollPane groupsMenuScrollPane;

    @FXML
    private BorderPane borderPane;

    private HBox groupContainer ;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        final ImageView imageView = new ImageView("com/ong/Images/not_logo.png");
        final Circle clip = new Circle(300, 200, 200);
        imageView.setClip(clip);

        groupContainer = new HBox();
        groupContainer.getChildren().add(imageView);

        groupsMenuScrollPane.setContent(groupContainer);

        // this is not needed since it's already done in FXML:
        // borderPane.setTop(groupsMenuScrollPane);

        // ...
    }

    public void addGroup(...) {
        // not sure exactly what you want to add, but for example,
        // to add a new image view you would do:
        ImageView imageView = new ImageView(...);
        groupContainer.getChildren().add(imageView);
    }
}

加載 FXML 時,請保留對控制器的引用:

FXMLLoader loader = new FXMLLoader(getClass().getResource(...));
Parent root = loader.load();
HomepageController controller = loader.getController();

然后您可以將內容添加到滾動窗格中

controller.addGroup(...);

正如另一個答案中提到的, ListView可能是更好的方法。

您可能還應該考慮 MVC 方法(例如,請參閱Applying MVC With JavaFx ),其中模型使用ObservableList<...>來存儲組列表。 控制器可以觀察該列表並在更改時修改滾動窗格內容。 然后你所要做的就是通過模型向列表中添加一些東西。

你的問題和問題是不同的問題。

對於你的問題。 動態添加您想要查看 ListView 的元素。 https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/ListView.html

任何像 javafx 的 recyclerview 或可重用視圖

至於你的問題。 場景只能有一個根節點。 在這個根目錄中,你應該有你的邊界窗格,其中應該是你的 ListView。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM