gpt4 book ai didi

JavaFX切换BorderPane的中心: Buttons only work once

转载 作者:行者123 更新时间:2023-12-02 13:25:34 28 4
gpt4 key购买 nike

我现在对 JavaFX 有点困惑。基本上,当我运行代码时,我只能单击应用程序侧栏上的按钮一次,然后它将把中心 Pane 交换为我想要显示的 Pane 。但在那之后,ActionEvent 似乎没有触发...我尝试在处理后重新附加它们,但它不起作用,而且我不知道出了什么问题。

我花了 2 天的时间试图破解这个问题,我确信它是非常简单的事情。

Controller :

@FXML private Button fooButton, barButton;
@FXML private Pane fooPane, barPane;
@FXML private BorderPane mainWindow;
@FXML private TabPane tabPane;
@FXML private VBox buttonBar;
@FXML private AnchorPane centerAP;
private HashMap<Button, Pane> buttonsPaneHMap = new HashMap<>(); //storing the data in a HashMap to create a link between buttons and their panes.

@Override
public void initialize(URL arg0, ResourceBundle arg1) {
putNodesInHashmap();
assertControlsExist();
mainWindow.setCenter(welcomePane);
setOnActions(buttonsPaneHMap);
}

public final void handleButton(ActionEvent event) throws IOException {
Node newCenter = new AnchorPane();

if (event.getSource() == fooButton){
newCenter = FXMLLoader.load(getClass().getResource("/FXML/fooPane.fxml"));
}
if (event.getSource() == barButton){
newCenter = FXMLLoader.load(getClass().getResource("/FXML/barPane.fxml"));
}

try{
this.mainWindow.setCenter(newCenter);
}
catch (NullPointerException e){
e.printStackTrace();
}
}

public final void setOnActions(HashMap<Button, Pane> hMap){
for (Button button : hMap.keySet()){
((ButtonBase) button).setOnAction(arg0 -> {
try {
handleButton(arg0);
}
catch (Exception e) {
e.printStackTrace();
}
});
}
}
public final void putNodesInHashMap(){
buttonsPaneHMap.put(fooButton, fooPane);
buttonsPaneHMap.put(barButton, barPane);

}

FXML

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

<?import java.net.URL?>
<?import javafx.scene.Cursor?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>

<BorderPane fx:id="mainWindow" prefHeight="461.0" prefWidth="760.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="guiControllers.MainController">
<top>
<Pane id="body" prefHeight="96.0" prefWidth="658.0" style="-fx-background-color: #243242; -fx-border-color: #0E141B; -fx-border-radius: 3;" stylesheets="@application.css" BorderPane.alignment="CENTER">
<children>
<Label layoutX="103.0" layoutY="25.0" prefHeight="48.0" prefWidth="394.0" text="Title Here" textFill="WHITE">
<font>
<Font name="Calibri Bold" size="41.0" />
</font>
</Label>
<ImageView fitHeight="55.0" fitWidth="61.0" layoutX="25.0" layoutY="20.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../Res/mhlogo.png" />
</image>
</ImageView>
</children>
</Pane>
</top>
<left>
<VBox id="buttonBar" fx:id="buttonBar" alignment="TOP_CENTER" prefHeight="365.0" prefWidth="168.0" style="-fx-background-color: #2E4055; -fx-border-radius: 3; -fx-border-color: #0E141B;" BorderPane.alignment="CENTER">
<children>
<Pane prefHeight="31.0" prefWidth="98.0">
<children>
<Pane layoutX="-1.0" layoutY="-2.0" prefHeight="33.0" prefWidth="169.0" style="-fx-background-color: #565656; -fx-border-color: #000000; -fx-border-radius: 20; -fx-background-radius: 20;">
<children>
<ImageView fitHeight="19.0" fitWidth="18.0" layoutX="7.0" layoutY="7.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../Res/magnifying-glass.png" />
</image>
</ImageView>
<TextField layoutX="29.0" layoutY="2.0" prefHeight="0.0" prefWidth="134.0" style="-fx-border-radius: 1; -fx-border-color: #111111; -fx-border-width: 2; -fx-background-color: #FFFFFF; -fx-background-radius: 20; -fx-border-radius: 20;" styleClass="stop-color-leaking" stylesheets="@../cSS/application.css" />
</children>
</Pane>
</children>
</Pane>
<Button id="fooButton" fx:id="fooButton" mnemonicParsing="false" onAction="#handleButton" prefHeight="31.0" prefWidth="171.0" style="-fx-background-color: #CDCDCD; -fx-border-color: #0E141B; -fx-border-radius: 3;" text="foo" />
<Button id="barButton" fx:id="barButton" mnemonicParsing="false" onAction="#handleButton" prefHeight="31.0" prefWidth="202.0" style="-fx-background-color: #CDCDCD; -fx-border-color: #0E141B; -fx-border-radius: 3;" text="bar" />

<children>
<ImageView id="settingsButton" fitHeight="38.0" fitWidth="48.0" layoutX="64.0" layoutY="130.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../Res/settings.png" />
</image>
</ImageView>
</children>
</AnchorPane>
</children>
</VBox>
</left>
<right>
<TabPane id="tabPane" fx:id="tabPane" focusTraversable="false" prefHeight="365.0" prefWidth="166.0" rotateGraphic="true" style="-fx-background-color: # #414760;" styleClass="tab-header-background" tabClosingPolicy="UNAVAILABLE" BorderPane.alignment="CENTER">
<tabs>
<Tab fx:id="notesTab" text="Notes">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="336.0" prefWidth="216.0" style="-fx-border-color: #414760; -fx-background-radius: 3;" styleClass="tab-header-background" stylesheets="@../application/CSS/application.css" />
</content>
</Tab>
<Tab fx:id="diagramTab" closable="false" text="Diagram" />
</tabs>
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
<stylesheets>
<URL value="@application.css" />
<URL value="@../application/CSS/application.css" />
</stylesheets>
</TabPane>
</right>
<center>
<AnchorPane fx:id="centerAP" style="-fx-background-color: #414760;" BorderPane.alignment="CENTER">
<children>
<VBox fx:id="welcomePane" prefHeight="304.0" prefWidth="391.0" style="-fx-background-color: #414760;">
<children>
<Pane fx:id="welcomePane" prefHeight="313.0" prefWidth="428.0" style="-fx-background-color: #414760;">
<children>
<ImageView fitHeight="183.0" fitWidth="296.0" layoutX="14.0" layoutY="65.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../Res/welcomepane.png" />
</image>
</ImageView>
<Label layoutX="141.0" layoutY="14.0" text="Welcome" textFill="WHITE">
<font>
<Font name="Calibri Bold" size="33.0" />
</font>
</Label>
<Label layoutX="82.0" layoutY="53.0" prefHeight="68.0" prefWidth="346.0" text="To start, please select an" textFill="WHITE" textOverrun="CLIP">
<font>
<Font name="Calibri" size="24.0" />
</font>
</Label>
<Label layoutX="82.0" layoutY="80.0" prefHeight="68.0" prefWidth="346.0" text="option from the left." textFill="WHITE" textOverrun="CLIP">
<font>
<Font name="Calibri" size="24.0" />
</font>
</Label>
</children>
</Pane>
</children>
</VBox>
</children>
</AnchorPane>
</center>
</BorderPane>

据我所知,所有对象都从 FXML 正确注入(inject),但是一旦中心面板切换,侧面按钮就不再起作用(尽管我最初可以单击任何对象,它都会加载。

脚注:为了便于阅读,上面的代码被稍微删减和更改。

最佳答案

我从 Android 的剧本中得到了一个想法。如果您知道如何访问节点的父节点并且知道节点的 fx:id,则可以使用此方法。

完整代码根据按下的按钮将不同的 Pane 加载到场景的中心。下面的代码是一个示例,显示如何加载一个 Pane 。如果您知道节点的父节点、节点的 fx:id 和用于转换的节点类型,则可以使用此想法获取任何节点。

Controller code

private void showSetupAccountScreen()
{
try
{
spCenterDisplay.getChildren().remove(0);//remove old display
BorderPane root = FXMLLoader.load(getClass().getResource("SubSetupAccount.fxml"));
spCenterDisplay.getChildren().add(root);//add new display
GridPane tempDisplay = (GridPane)root.getChildren().get(1);//get Parent of the nodes I will be using in this controller
loadQWERTYKeyboard();

TextField tfFirstName = (TextField)findNodeByID("tfFirstName", tempDisplay.getChildren());
TextField tfLastName = (TextField)findNodeByID("tfLastName", tempDisplay.getChildren());
TextField tfStreetAddress = (TextField)findNodeByID("tfStreetAddress", tempDisplay.getChildren());
TextField tfCity = (TextField)findNodeByID("tfCity", tempDisplay.getChildren());
TextField tfState = (TextField)findNodeByID("tfState", tempDisplay.getChildren());
TextField tfZip = (TextField)findNodeByID("tfZip", tempDisplay.getChildren());
TextField tfInitialDepositChecking = (TextField)findNodeByID("tfInitialDepositChecking", tempDisplay.getChildren());
TextField tfInitialDepositSavings = (TextField)findNodeByID("tfInitialDepositSavings", tempDisplay.getChildren());
ChoiceBox cbChecking = (ChoiceBox)findNodeByID("cbChecking", tempDisplay.getChildren());
cbChecking.getItems().addAll("No", "Yes");
cbChecking.setValue("No");
ChoiceBox cbSavings = (ChoiceBox)findNodeByID("cbSavings", tempDisplay.getChildren());
cbSavings.getItems().addAll("No", "Yes");
cbSavings.setValue("No");

if(true)//come back and check to make sure all info is in textfields
{
btnLeftOne.setOnAction((event) -> {

boolean createChecking = cbChecking.getValue().equals("Yes");
boolean createSavings = cbSavings.getValue().equals("Yes");

dbh.createNewAccount(tfFirstName.getText(), tfLastName.getText(), tfStreetAddress.getText(), tfCity.getText(),
tfState.getText(), tfZip.getText(), createChecking, Double.parseDouble(tfInitialDepositChecking.getText()),
createSavings, Double.parseDouble(tfInitialDepositSavings.getText()));
});
}
else
{
//create Alert
}

btnRightOne.setOnAction((event) -> {
cancelAccountCreation();
});

btnLeftTwo.setOnAction(null);
btnLeftThree.setOnAction(null);
btnLeftFour.setOnAction(null);
btnRightTwo.setOnAction(null);
btnRightThree.setOnAction(null);
btnRightFour.setOnAction(null);
}
catch (IOException ex)
{
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}

private void loadQWERTYKeyboard()
{
try
{
AnchorPane keyboardRoot = FXMLLoader.load(getClass().getResource("KeyboardQWERTY.fxml"));
System.out.println(keyboardRoot.getId());
spBottomDisplay.getChildren().add(keyboardRoot);

GridPane tempKeyboard = (GridPane)keyboardRoot.getChildren().get(0);

tempKeyboard.getChildren().stream().filter((tempNode)
-> (tempNode instanceof Button)).map((
tempNode) -> (Button) tempNode).forEachOrdered((tempButton) -> {
buttons.put(tempButton.getText().toLowerCase(), tempButton);
});

apMain.setOnKeyPressed((event) -> {
Button tempButton = buttons.get(event.getText());
if (tempButton != null) {
tempButton.arm();
tempButton.setStyle("-fx-background-color: blue");
}
else if (event.getCode().equals(KeyCode.ENTER)) {
tempButton = buttons.get("enter");
tempButton.arm();
tempButton.setStyle("-fx-background-color: blue");
}
else if (event.getCode().equals(KeyCode.BACK_SPACE)) {
tempButton = buttons.get("backspace");
tempButton.arm();
tempButton.setStyle("-fx-background-color: blue");
}
else if (event.getCode().equals(KeyCode.SPACE)) {
tempButton = buttons.get("space");
tempButton.arm();
tempButton.setStyle("-fx-background-color: blue");
}
});

apMain.setOnKeyReleased((event) -> {
System.out.println();
Button tempButton = buttons.get(event.getText());
System.out.println("Released key text: " + event.getText());
System.out.println("Released key code: " + event.getCode());

if (tempButton != null) {
tempButton.disarm();
tempButton.setStyle("");
}
else if (event.getCode().equals(KeyCode.ENTER)) {
tempButton = buttons.get("enter");
tempButton.disarm();
tempButton.setStyle("");
}
else if (event.getCode().equals(KeyCode.BACK_SPACE)) {
tempButton = buttons.get("backspace");
tempButton.disarm();
tempButton.setStyle("");
}
else if (event.getCode().equals(KeyCode.SPACE)) {
tempButton = buttons.get("space");
tempButton.disarm();
tempButton.setStyle("");
}
});
}
catch (IOException ex)
{
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}

private Node findNodeByID(String id, ObservableList<Node> observableList)
{
for(Node node : observableList)
{
if(node.getId().equals(id))
{
System.out.println("node found!");
return node;
}
else
{
System.out.println("node not found yet!");
}
}

return null;
}

在这段代码中,我使用了两种不同的方法。在loadQWERTYKeyboard 方法中是一种方法。 findNodeByID 是第二种方法。完整代码见here 。正在工作,但项目尚未完成。

关于JavaFX切换BorderPane的中心: Buttons only work once,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43399207/

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