gpt4 book ai didi

JavaFx:如何实现动态 Gridpane?

转载 作者:行者123 更新时间:2023-11-30 06:48:35 25 4
gpt4 key购买 nike

我正在使用 JavaFx 开发一个应用程序,其中有两个选项卡。

在第一个选项卡中,我有组合框:

enter image description here

在第二个选项卡中,我有这样的网格 Pane :

enter image description here

我想要的是当用户从选项卡 A 的组合框中选择 3 时,例如:

enter image description here

它应该在选项卡 B 的网格 Pane 中添加 3 行,每列都带有文本字段、复选框和日期选择器。 A 列具有文本字段,B 列具有复选框,C 列具有 DatePicker,如下所示:

enter image description here

请帮助我如何实现这一点,以及在实现之后如何访问每个文本字段、复选框和日期选择器的数据。

更新:尝试用 FXML 做@Yahya 解决方案

主.java

public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
TabPane root = (TabPane)FXMLLoader.load(getClass().getResource("Sample.fxml"));
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
launch(args);
}
}

示例 Controller .java

public class SampleController {

@FXML
private TabPane root ;
@FXML
private Tab tabA ;
@FXML
private Tab tabB ;
@FXML
private ComboBox<Integer> comboBox ;
@FXML
private static GridPane gridPane ;
@FXML
private AnchorPane anchB ;


public void initialize() {

// Create a comboBox, set its attributes and add it to container
comboBox.getItems().addAll(1,2,3,4,5,6,7,8,9,10);
comboBox.setValue(1);
comboBox.setEditable(false);
// anchA.getChildren().add(comboBox);

// add listener to tabPane
root.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>(){
@Override
public void changed(ObservableValue<? extends Tab> observable, Tab oldTab, Tab newTab){
if(newTab == tabB) { // when tabB is selected
System.out.println(anchB.getChildren().size());
if(anchB.getChildren().size()<=0){ // if already contains a table

anchB.getChildren().add(table(comboBox.getValue()));

table(comboBox.getValue());
System.out.println("hello");
}
else {
anchB.getChildren().remove(gridPane); // remove it
System.out.println("no");
}
}
}
});
}

//This static method shall create the table dynamically when it's called
// you can add, change and remove the attributes of the table components
// the colors and all other decoration(e.g. position) are for example
public static GridPane table(int rows){

for(int i=0; i<rows; i++){
TextField textField = new TextField();
textField.setAlignment(Pos.CENTER);
CheckBox checkBox = new CheckBox("Check Box");
checkBox.setTextFill(Color.WHITE);
checkBox.setAlignment(Pos.CENTER);
DatePicker datePicker = new DatePicker();

//add them to the GridPane
gridPane.add(textField, 0, i+1); // (child, columnIndex, rowIndex)
gridPane.add(checkBox , 1, i+1);
gridPane.add(datePicker,2, i+1);

// margins are up to your preference
GridPane.setMargin(textField, new Insets(5));
GridPane.setMargin(checkBox, new Insets(5));
GridPane.setMargin(datePicker, new Insets(5));
}

return gridPane;

}
}

示例.fxml

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

<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Text?>

<TabPane fx:id="root" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.SampleController">
<tabs>
<Tab fx:id="tabA" text="Tab A">
<content>
<AnchorPane fx:id="anchA" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<ComboBox fx:id="comboBox" layoutX="225.0" layoutY="82.0" prefWidth="150.0" />
</children>
</AnchorPane>
</content>
</Tab>
<Tab fx:id="tabB" text="Tab B">
<content>
<AnchorPane fx:id="anchB" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<GridPane fx:id="gridPane" gridLinesVisible="true" layoutX="150.0" layoutY="62.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="A" textAlignment="CENTER" wrappingWidth="91.67529296875" />
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="B" textAlignment="CENTER" wrappingWidth="93.5986328125" GridPane.columnIndex="1" />
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="C" textAlignment="CENTER" wrappingWidth="95.287109375" GridPane.columnIndex="2" />
</children>
</GridPane>
</children>
</AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>

最佳答案

你可以这样做:

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class DynamicTable extends Application{

@Override
public void start(Stage ps) throws Exception {

// Create a Tab A, create a container and add it
Tab tabA = new Tab("Tab A");
StackPane containerA = new StackPane();

// note that the colors are for example
containerA.setBackground(new Background(
new BackgroundFill(Color.MAROON,null,null)));
// Create a comboBox, set its attributes and add it to container
ComboBox<Integer> comboBox = new ComboBox<Integer>();
comboBox.getItems().addAll(1,2,3,4,5,6,7,8,9,10);
comboBox.setValue(1);
comboBox.setEditable(false);
containerA.getChildren().add(comboBox);

//add the container to the tabA
tabA.setContent(containerA);

// Create Tab B, create a container and add it
Tab tabB = new Tab("Tab B");
StackPane containerB = new StackPane();

containerB.setBackground(new Background(
new BackgroundFill(Color.DARKMAGENTA,null,null)));
tabB.setContent(containerB);
// create TabPane and add the Tabs to it
// all other values need manipulation (i.e. up to your preference)
TabPane tabPane = new TabPane();
tabPane.getTabs().addAll(tabA, tabB);
//set size and other attributes (if any), for example
tabPane.setMinWidth(500);
tabPane.setMinHeight(500);

// add listener to tabPane
tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>(){
@Override
public void changed(ObservableValue<? extends Tab> observable, Tab oldTab, Tab newTab){
if(newTab == tabB) { // when tabB is selected
if(containerB.getChildren().size()>0){ // if already contains a table
containerB.getChildren().remove(0); // remove it
}
containerB.getChildren().add(table(comboBox.getValue())); // create the table and add it
}
}
});

// simple root to test
Pane root = new Pane();
root.getChildren().add(tabPane);

Scene scene = new Scene(root, 500,500);
ps.setScene(scene);
ps.setTitle("Dynamic Table In Tab");
ps.show();
}


// This static method shall create the table dynamically when it's called
// you can add, change and remove the attributes of the table components
// the colors and all other decoration(e.g. position) are for example
public static GridPane table(int rows){
GridPane table = new GridPane();

for(int i=0; i<rows; i++){
TextField textField = new TextField();
textField.setAlignment(Pos.CENTER);
CheckBox checkBox = new CheckBox("Check Box");
checkBox.setTextFill(Color.WHITE);
checkBox.setAlignment(Pos.CENTER);
DatePicker datePicker = new DatePicker();

//add them to the GridPane
table.add(textField, 0, i); // (child, columnIndex, rowIndex)
table.add(checkBox , 1, i);
table.add(datePicker,2, i);

// margins are up to your preference
GridPane.setMargin(textField, new Insets(5));
GridPane.setMargin(checkBox, new Insets(5));
GridPane.setMargin(datePicker, new Insets(5));
}
table.setAlignment(Pos.CENTER);

return table;

}

public static void main(String[] args) {
launch();

}
}

测试

enter image description here

enter image description here

更新:如果你想从 TabB 中的表中获取值,你可以这样做:

// first create a method like this
// this static method to return a component from Table at specific row and column
public static Node getComponent (int row, int column, GridPane table) {
for (Node component : table.getChildren()) { // loop through every node in the table
if(GridPane.getRowIndex(component) == row &&
GridPane.getColumnIndex(component) == column) {
return component;
}
}

return null;
}

// Then use the method like this
// The textfield always at Column 0, check box column 1 and Date picker 2
// and the GridPane is in a StackPane(container) at index 0
// Note that you may NEED to add a button and wrap the following code with its Action Listener (i.e. button.setOnAction())
if(containerB.getChildren().size()>0){ // that means it contains a table
GridPane table = (GridPane) containerB.getChildren().get(0);
for(int i=0 ; i<comboBox.getValue(); i++){
String Text = ((TextField)getComponent (i, 0, table)).getText();
boolean selected = ((CheckBox)getComponent (i, 1, table)).isSelected();
LocalDate date = ((DatePicker)getComponent (i, 2, table)).getValue();

System.out.println(Text + " " + selected + " " + date);
System.out.println("Next Row");
}

}

更新:

如果您希望您的程序仅在用户更改ComboBox 中的值时删除/创建表(GridPane),那么您需要添加一个ChangeListener。到您的 ComboBox 以捕捉其中的变化,因此您需要例如一个 global booleantrue 变化当 ComboBox 值更改时为 false,反之亦然,并且要在 if 语句 中检查此 boolean检查该表是否已存在于 containerB 中(在您更新的问题 anchB 中),例如如下所示:

boolean valueChanged = false; // its scope should be global and to be added to the ComboBox ChangeListener
if(containerB.getChildren().size()>0 && valueChanged){ // if already contains a table
containerB.getChildren().remove(0); // remove it
}

关于JavaFx:如何实现动态 Gridpane?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44101807/

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