JAVAFX:在BorderPane中切换面板

huangapple go评论91阅读模式
英文:

JAVAFX: Switching Between Panes in BorderPane

问题

我有一个桌面应用程序,包含以下内容:

主类:加载第一个FXML文件 -> SideBar.fxml

SideBar.fxml:包含BorderPane -> 在其左侧,我创建了2个按钮:

         - 第一个按钮:加载示例FXML文件
         - 第二个按钮:加载secondFxml文件

sample.fxml:包含一个tableView和一个Button
secondFxml.fxml:包含一个标签

控制器:控制sample.fxml -> 将随机双精度值加载到tableView中

问题是:

当我按下Pane 1中的按钮(填充表格)时,它将数据加载到tableView中,到目前为止一切都进行得很好。

当我切换到第二个窗格,然后返回到第一个窗格时,中央边框窗格会重新加载,因此tableView的数据消失了。

我想要的是,当我返回到第一个窗格时,tableView保持原样,不会重新加载。

我尝试隐藏borderpane的中央部分,但对我没有效果。

我已经对问题进行了截图:JAVAFX:在BorderPane中切换面板

Main类:

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("SideBar.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 700, 500));
        primaryStage.show();
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

SideBarController类:

public class SideBarController implements Initializable {

    @FXML BorderPane borderPane;

    public void openPane1(ActionEvent event) throws Exception {
        loadScene("Sample.fxml");
    }

    public void openPane2(ActionEvent event) throws Exception {
        loadScene("secondFxml.fxml");
    }

    private void loadScene(String sc) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource(sc));

        borderPane.setCenter(root);
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) { }
}

Controller类:

public class Controller implements Initializable {

    double[][] data = new double[5][5];
    Random random = new Random();

    ObservableList<double[]> observableLists = FXCollections.observableArrayList();

    @FXML
    TableView<double[]> tableView = new TableView<>(observableLists);

    @FXML
    public void fillTable(ActionEvent event) throws IOException {
        //Random Values
        for (int i = 0; i < data.length ; i++) {
            for (int j = 0; j < data[0].length ; j++) {
                data[i][j]= random.nextDouble();
            }
        }

        //Add data to ObservableLists
        for (int i = 0; i < data.length ; i++) {
            observableLists.add(data[i]);
        }

        //Create Columns
        for (int i = 0; i < data[0].length ; i++) {
            TableColumn<double[], Double> column= null;
            column = new TableColumn<>("column "+i);
            int finalI = i;
            column.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue()[finalI]));
            tableView.getColumns().add(column);
        }

        // Fill TableView
        tableView.setItems(observableLists);
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {

    }
}

SideBar.fxml:

<BorderPane fx:id="borderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.SideBarController">
   <left>
      <VBox prefHeight="400.0" prefWidth="173.0" style="-fx-background-color: black;" BorderPane.alignment="CENTER">
         <children>
            <Button mnemonicParsing="false" onAction="#openPane1" prefHeight="25.0" prefWidth="177.0" style="-fx-background-color: blue; -fx-border-color: white;" text="Pane 1" textFill="WHITE">
               <VBox.margin>
                  <Insets top="50.0" />
               </VBox.margin>
               <font>
                  <Font name="System Bold" size="17.0" />
               </font>
            </Button>
            <Button mnemonicParsing="false" onAction="#openPane2" prefHeight="25.0" prefWidth="176.0" style="-fx-background-color: blue; -fx-border-color: white;" text="Pane 2" textFill="WHITE">
               <VBox.margin>
                  <Insets top="10.0" />
               </VBox.margin>
               <font>
                  <Font name="System Bold" size="17.0" />
               </font>
            </Button>
         </children>
      </VBox>
   </left>
   <center>
      <Pane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
         <children>
            <Label layoutX="163.0" layoutY="152.0" prefHeight="68.0" prefWidth="131.0" text="Home">
               <font>
                  <Font size="46.0" />
               </font>
            </Label>
         </children>
      </Pane>
   </center>
</BorderPane>

Sample.fxml:

<Pane prefHeight="395.0" prefWidth="597.0" style="-fx-background-color: white;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <TableView fx:id="tableView" layoutX="77.0" layoutY="47.0" prefHeight="266.0" prefWidth="461.0" />
      <Button layoutX="257.0" layoutY="329.0" mnemonicParsing="false" onAction="#fillTable" text="fill Table" />
   </children>
</Pane>

SecondFxml.fxml:

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label layoutX="232.0" layoutY="153.0" text="Pane 2">
         <font>
            <Font size="46.0" />
         </font>
      </Label>
   </children>
</Pane>
英文:

I have a desktop app that contains:

Main Class: that load the first fxml file -> SideBar.fxml

SideBar.fxml: contains BorderPane -> at the left of it, i create 2 buttons:

         - the fist button: load  sample fxml file
- the second button: load secondFxml file

sample.fxml: contains a tableView and a Button
secondFxml.fxml: contains a label

Controller: a class that control sample.fxml -> load random double values to a tableView

the issue is :

when i press the button (fill Table) in Pane 1 : it load the data to the tableView, untill now everything is going well

when i switch to the second pane and i return to the first pane the center border pane is reloaded again so the data of the tableView disappeared

what i want is when i return to the first pane the the table view stay as it was first
i try to hide the borderpane center but it doesn't work for me

i screenShot the issue: JAVAFX:在BorderPane中切换面板

Main:

public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource(&quot;SideBar.fxml&quot;));
primaryStage.setTitle(&quot;Hello World&quot;);
primaryStage.setScene(new Scene(root, 700, 500));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

SideBarController:

public class SideBarController implements Initializable {
@FXML BorderPane borderPane;
public void openPane1(ActionEvent event) throws Exception {
loadScene(&quot;Sample.fxml&quot;);
}
public void openPane2(ActionEvent event) throws Exception {
loadScene(&quot;secondFxml.fxml&quot;);
}
private void loadScene(String sc) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource(sc));
borderPane.setCenter(root);
}
@Override
public void initialize(URL location, ResourceBundle resources) { }
}

Controller:

public class Controller implements Initializable {
double[][] data = new double[5][5];
Random random = new Random();
ObservableList&lt;double[]&gt; observableLists = FXCollections.observableArrayList();
@FXML
TableView&lt;double []&gt; tableView = new TableView&lt;&gt;(observableLists);
@FXML
public void fillTable(ActionEvent event) throws IOException {
//Random Values
for (int i = 0; i &lt;data.length ; i++) {
for (int j = 0; j &lt;data[0].length ; j++) {
data[i][j]= random.nextDouble();
}
}
//Add data to ObservableLists
for (int i = 0; i &lt;data.length ; i++) {
observableLists.add(data[i]);
}
//Create Columns
for (int i = 0; i &lt;data[0].length ; i++) {
TableColumn&lt;double[], Double&gt; column= null;
column = new TableColumn&lt;&gt;(&quot;column &quot;+i);
int finalI = i;
column.setCellValueFactory(param -&gt; new ReadOnlyObjectWrapper&lt;&gt;(param.getValue()[finalI]));
tableView.getColumns().add(column);
}
// Fill TableView
tableView.setItems(observableLists);
}
@Override
public void initialize(URL location, ResourceBundle resources) {
}
}

SideBar.fxml


&lt;BorderPane fx:id=&quot;borderPane&quot; maxHeight=&quot;-Infinity&quot; maxWidth=&quot;-Infinity&quot; minHeight=&quot;-Infinity&quot; minWidth=&quot;-Infinity&quot; prefHeight=&quot;400.0&quot; prefWidth=&quot;600.0&quot; xmlns=&quot;http://javafx.com/javafx/11.0.1&quot; xmlns:fx=&quot;http://javafx.com/fxml/1&quot; fx:controller=&quot;sample.SideBarController&quot;&gt;
&lt;left&gt;
&lt;VBox prefHeight=&quot;400.0&quot; prefWidth=&quot;173.0&quot; style=&quot;-fx-background-color: black;&quot; BorderPane.alignment=&quot;CENTER&quot;&gt;
&lt;children&gt;
&lt;Button mnemonicParsing=&quot;false&quot; onAction=&quot;#openPane1&quot; prefHeight=&quot;25.0&quot; prefWidth=&quot;177.0&quot; style=&quot;-fx-background-color: blue; -fx-border-color: white;&quot; text=&quot;Pane 1&quot; textFill=&quot;WHITE&quot;&gt;
&lt;VBox.margin&gt;
&lt;Insets top=&quot;50.0&quot; /&gt;
&lt;/VBox.margin&gt;
&lt;font&gt;
&lt;Font name=&quot;System Bold&quot; size=&quot;17.0&quot; /&gt;
&lt;/font&gt;
&lt;/Button&gt;
&lt;Button mnemonicParsing=&quot;false&quot; onAction=&quot;#openPane2&quot; prefHeight=&quot;25.0&quot; prefWidth=&quot;176.0&quot; style=&quot;-fx-background-color: blue; -fx-border-color: white;&quot; text=&quot;Pane 2&quot; textFill=&quot;WHITE&quot;&gt;
&lt;VBox.margin&gt;
&lt;Insets top=&quot;10.0&quot; /&gt;
&lt;/VBox.margin&gt;
&lt;font&gt;
&lt;Font name=&quot;System Bold&quot; size=&quot;17.0&quot; /&gt;
&lt;/font&gt;
&lt;/Button&gt;
&lt;/children&gt;
&lt;/VBox&gt;
&lt;/left&gt;
&lt;center&gt;
&lt;Pane prefHeight=&quot;200.0&quot; prefWidth=&quot;200.0&quot; BorderPane.alignment=&quot;CENTER&quot;&gt;
&lt;children&gt;
&lt;Label layoutX=&quot;163.0&quot; layoutY=&quot;152.0&quot; prefHeight=&quot;68.0&quot; prefWidth=&quot;131.0&quot; text=&quot;Home&quot;&gt;
&lt;font&gt;
&lt;Font size=&quot;46.0&quot; /&gt;
&lt;/font&gt;
&lt;/Label&gt;
&lt;/children&gt;
&lt;/Pane&gt;
&lt;/center&gt;
&lt;/BorderPane&gt;

Sample.fxml


&lt;Pane prefHeight=&quot;395.0&quot; prefWidth=&quot;597.0&quot; style=&quot;-fx-background-color: white;&quot; xmlns=&quot;http://javafx.com/javafx/11.0.1&quot; xmlns:fx=&quot;http://javafx.com/fxml/1&quot; fx:controller=&quot;sample.Controller&quot;&gt;
&lt;children&gt;
&lt;TableView fx:id=&quot;tableView&quot; layoutX=&quot;77.0&quot; layoutY=&quot;47.0&quot; prefHeight=&quot;266.0&quot; prefWidth=&quot;461.0&quot; /&gt;
&lt;Button layoutX=&quot;257.0&quot; layoutY=&quot;329.0&quot; mnemonicParsing=&quot;false&quot; onAction=&quot;#fillTable&quot; text=&quot;fill Table&quot; /&gt;
&lt;/children&gt;
&lt;/Pane&gt;

SecondFxml.fxml


&lt;Pane maxHeight=&quot;-Infinity&quot; maxWidth=&quot;-Infinity&quot; minHeight=&quot;-Infinity&quot; minWidth=&quot;-Infinity&quot; prefHeight=&quot;400.0&quot; prefWidth=&quot;600.0&quot; xmlns=&quot;http://javafx.com/javafx/11.0.1&quot; xmlns:fx=&quot;http://javafx.com/fxml/1&quot;&gt;
&lt;children&gt;
&lt;Label layoutX=&quot;232.0&quot; layoutY=&quot;153.0&quot; text=&quot;Pane 2&quot;&gt;
&lt;font&gt;
&lt;Font size=&quot;46.0&quot; /&gt;
&lt;/font&gt;
&lt;/Label&gt;
&lt;/children&gt;
&lt;/Pane&gt;

答案1

得分: 1

不要在按钮点击时从FXML重新加载。请在initialize方法中执行一次:

public class SideBarController implements Initializable {

    @FXML BorderPane borderPane;
    private Parent sample, secondFxml;

    public void openPane1(ActionEvent event) throws Exception {
        borderPane.setCenter(sample);
    }

    public void openPane2(ActionEvent event) throws Exception {
        borderPane.setCenter(secondFxml);
    }

    private Parent loadScene(String sc) throws IOException {
        return FXMLLoader.load(getClass().getResource(sc));
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        try {
            sample = loadScene("Sample.fxml");
            secondFxml =  loadScene("secondFxml.fxml");
        } catch (IOException ex) {
            ex.printStackTrace();
        };
    }
}
英文:

Do not reload from fxml when button is clicked. Do it once in initialize:

public class SideBarController implements Initializable {
@FXML BorderPane borderPane;
private Parent sample, secondFxml;
public void openPane1(ActionEvent event) throws Exception {
borderPane.setCenter(sample);
}
public void openPane2(ActionEvent event) throws Exception {
borderPane.setCenter(secondFxml);
}
private Parent loadScene(String sc) throws IOException {
return FXMLLoader.load(getClass().getResource(sc));
}
@Override
public void initialize(URL location, ResourceBundle resources) {
try {
sample = loadScene(&quot;Sample.fxml&quot;);
secondFxml =  loadScene(&quot;secondFxml.fxml&quot;);
} catch (IOException ex) {
ex.printStackTrace();
};
}
}

huangapple
  • 本文由 发表于 2020年4月4日 04:51:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/61020215.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定