gpt4 book ai didi

java - 从父 Pane 加载现有 FXML

转载 作者:行者123 更新时间:2023-12-02 10:55:32 27 4
gpt4 key购买 nike

我一直在开发一个具有 mainPane Pane 的应用程序,其中存储了多个较小的 Pane 。

我最初是通过为每个按下的按钮添加一个监听器开始的,在按下特定按钮时,应该会出现一个相关 Pane 。这工作得很好,直到我意识到每次按下按钮时我都会添加一个新的 Pane 实例,最终会在后台某处丢失最初选择的 Pane 的进度。

此后,我尝试尝试从主父 Pane 的 getChildren() 方法加载现有 Pane ,但是我在这方面没有取得太大成功。我试图在这里到处寻找解决方案,但我找不到与我的问题相关的任何内容,或者如果我发现了一些东西,我可能根本不理解它。

我的问题如下:如果我可以向父 Pane 添加一个子 Pane ,首先使用mainPane.getChildren().add(root) ,然后我添加了一个简单的 boolean 开关,如果添加了 Pane 并且已经添加了这种类型的 Pane - 尝试让它显示 mainPane.getChildren().get(intArray[0]).toFront(); 。但是,当将此添加到所有其他按钮处理程序时,.toFront()方法似乎按照添加的顺序显示 Pane 。

所以,如果我最初按下按钮 trackerButton , progressButton , communityButton , blockerButton - 然后我按trackerButton Pane 将显示 4 次 -> trackerPane , progressPane , communityPane , blockerPane如果我继续按下它,然后再次循环这些。

是否有一种更清晰的方法可以实现此目的,这样如果我多次按下按钮,它只会加载关联 Pane ,但不会使用 mainPane.getChildren().add(root); 添加它的新实例。 ?

任何帮助将不胜感激,我已将我的代码粘贴在下面:

public class MainController {

private Client client;

@FXML
TrackerPaneController trackerPaneController;

@FXML
ProgressController progressController;

@FXML
CommunityController communityController;

@FXML
BlockerController blockerController;

@FXML
SettingsController settingsController;

@FXML
Label userLabel;

@FXML
Button logoutButton;

@FXML
Button trackerButton;

@FXML
Button progressButton;

@FXML
Button communityButton;

@FXML
Button blockerButton;

@FXML
Button settingsButton;

@FXML
Pane mainPane;

Integer[] intArray = new Integer[4];
final Boolean[] booleanArray = {true,true,true,true,true};


@FXML
private void handlePanelButtonAction(ActionEvent event) throws IOException {


if(event.getSource() == trackerButton) {

if(booleanArray[0]) {


FXMLLoader trackerLoader = new FXMLLoader(getClass().getResource("/view/TrackerPane.fxml"));
Parent root = (Parent) trackerLoader.load();

trackerPaneController = trackerLoader.getController();
trackerPaneController.setClient(client);
mainPane.getChildren().add(root);

intArray[0] = mainPane.getChildren().indexOf(root);

}

mainPane.getChildren().get(intArray[0]).toFront();
booleanArray[0]=false;

} else if(event.getSource() == progressButton) {

if(booleanArray[1]) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/ProgressPane.fxml"));
Parent root = (Parent) loader.load();
progressController = loader.getController();
progressController.setClient(client);
mainPane.getChildren().add(root);
intArray[1] = mainPane.getChildren().indexOf(root);

}

mainPane.getChildren().get(intArray[1]).toFront();
booleanArray[1]=false;

} else if(event.getSource() == communityButton) {

if(booleanArray[2]) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/CommunityPane.fxml"));
Parent root = (Parent) loader.load();
communityController = loader.getController();
communityController.setClient(client);
mainPane.getChildren().add(root);
intArray[2] = mainPane.getChildren().indexOf(root);

}

mainPane.getChildren().get(intArray[2]).toFront();
booleanArray[2]=false;

} else if(event.getSource() == blockerButton) {

if(booleanArray[3]) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/BlockerPane.fxml"));
Parent root = (Parent) loader.load();
blockerController = loader.getController();
blockerController.setClient(client);
mainPane.getChildren().add(root);
intArray[3] = mainPane.getChildren().indexOf(root);

}

mainPane.getChildren().get(intArray[3]).toFront();
booleanArray[3]=false;

} else if(event.getSource() == settingsButton) {

if(booleanArray[4]) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/SettingsPane.fxml"));
Parent root = (Parent) loader.load();
settingsController = loader.getController();
settingsController.setClient(client);
mainPane.getChildren().add(root);
intArray[4] = mainPane.getChildren().indexOf(root);

}

mainPane.getChildren().get(intArray[4]).toFront();
booleanArray[4]=false;

} else if(event.getSource() == logoutButton) {

client.logout();
Platform.exit();
}
}

}

我觉得这个解决方案对于拥有合适技能的人来说非常简单,但我对 JavaFX 仍然很陌生,任何帮助将不胜感激。

亲切的问候

最佳答案

问题在于,在 Node 上调用 toFront 会导致节点移动到父布局的最后一个索引。这会导致某些指数在某些情况下变得错误。要解决此问题,只需在数据结构中存储节点,而不是索引。

另请注意,除了一些细微的差异外,基本上所有加载代码看起来都相同。您应该避免重复代码,因为它会使您的代码更难以维护。通过向 Controller 添加接口(interface)可以轻松删除重复的代码。

@FXML
private void handlePanelButtonAction(ActionEvent event) throws IOException {
if(event.getSource() == trackerButton) {
...
} else if(event.getSource() == progressButton) {
...
} else if(event.getSource() == communityButton) {
...
} else if(event.getSource() == blockerButton) {
...
} else if(event.getSource() == settingsButton) {
...
} else if(event.getSource() == logoutButton) {
...
}
}

不要做这样的事情。如果逻辑完全不同,Button 应该接收它自己的事件处理程序方法。即使代码足够相似,您也应该避免检查源与某些节点的引用相等性。相反,您可以将信息存储在 NodeuserDataproperties 中。

推荐

使用您的 Controller 实现以下接口(interface):

public interface ClientContainer {
void setClient(Client client);
}

使用 URL 初始化按钮的 userData:

public class MainController {

...

private void setResource(Node node, String resource) {
URL url = getClass().getResource(resource);
if (url == null) {
throw new IllegalArgumentException("Resource not available: " + resource);
}
node.setUserData(url);
}

private static URL getResource(Object source) {
return (URL) ((Node) source).getUserData();
}

@FXML
private void initialize() {
setResource(trackerButton, "/view/TrackerPane.fxml");
setResource(progressButton, "/view/ProgressPane.fxml");
setResource(communityButton, "/view/CommunityPane.fxml");
setResource(blockerButton, "/view/BlockerPane.fxml");
setResource(settingsButton, "/view/SettingsPane.fxml");
}
}

使用此数据和 map 以避免重新加载场景。 (您还需要将处理 logoutButton 单击的代码移至不同的方法。)

private final Map<URL, Node> loadedContent = new HashMap<>();

@FXML
private void handlePanelButtonAction(ActionEvent event) {
loadedContent.computeIfAbsent(getResource(event.getSource()), url -> {
try {
FXMLLoader loader = new FXMLLoader(url);
Node result = loader.load();
ClientContainer controller = loader.getController();
controller.setClient(client);
mainPane.getChildren().add(result);
return result;
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}).toFront();
}

关于java - 从父 Pane 加载现有 FXML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51776539/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com