[英]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.