- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 JavaFx 开发一个应用程序,其中有两个选项卡。
在第一个选项卡中,我有组合框:
在第二个选项卡中,我有这样的网格 Pane :
我想要的是当用户从选项卡 A 的组合框中选择 3 时,例如:
它应该在选项卡 B 的网格 Pane 中添加 3 行,每列都带有文本字段、复选框和日期选择器。 A 列具有文本字段,B 列具有复选框,C 列具有 DatePicker,如下所示:
请帮助我如何实现这一点,以及在实现之后如何访问每个文本字段、复选框和日期选择器的数据。
更新:尝试用 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();
}
}
测试
更新:如果你想从 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 boolean
从 true
变化当 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/
我正在阅读一些有关 JavaFX 2.0 的教程,我对 GridPane 布局组件的两种方法有点困惑。 基本上,我会使用 GridPane.add(new Label("My Label"), 0,
我正在使用 JavaFX 8 创建一个应用程序。我使用拖/放动态更改网格 Pane 的内容。我希望每行或每行/列迭代 GridPane 内容。JavaFX 允许通过指定行和列在 GridPane 中添
我想检索网格 Pane 中一个特定单元格的内容。我在单元格中放置了按钮 setConstraints(btt , 0 ,1 ) setConstraints(btt , 0 ,2 ) getChild
基本上,我只想将图像插入网格 Pane 内的单元格中。 GridPane gridpane = new GridPane(); gridpane.add(new Image("File:image/m
我已经使用了GridPane.getChildren().clear(),但是它不起作用。 最佳答案 请注意,gridLinesVisible 属性是一项调试功能,不应依赖它来创建特定的外观。 话虽这
所以我有一个登录页面。如果您点击“还不是用户?立即注册!”它应该在同一窗口中打开一个新页面。现在我正在打开第二页,但它位于单独的窗口中。它还会在打开注册页面时创建错误消息。这是代码: 主要 publi
我正在使用数字键盘制作登录屏幕,但我似乎无法将 Pane 中按钮的网格 Pane 居中对齐。我做错了什么? Main.java import javafx.application.Applicatio
我正在尝试使用 JavaFX 创建一个场景,其中程序的标题位于顶部中心,按钮位于场景左侧的垂直线上。然而,这两个元素都聚集在场景的右上角,而不是我想要的位置。 如何让这些元素显示在我想要的位置? 以下
我对 JavaFX 比较陌生,并且我一直很困惑为什么下面的代码没有产生添加到网格的标签的预期结果。 我想做的是运行一个测试,将 JavaFX 标签添加到我的 FXML GridPane 中,因为我想在
作为一项作业,我正在 JavaFX 中制作一个老虎机程序。 如果我这样做: GridPane grid = new GridPane(); grid.add(new Rectangle(20, 20)
我正在尝试使用 2 列创建一个具有特定布局的窗口,但我无法完全让它按照我想要的方式工作。 首先,一些简化的示例代码: import javafx.application.Application; im
我是 JavaFX 新手,目前我尝试构建一个小型聊天窗口。为此,我为 ListView 设置了以下自定义单元格布局。 Grid 我使用外部 HBox,因此我可以像 Whatsapp... 那样对齐消息
我正在从数据库加载数据并在 GridPane 中动态创建按钮!但数据量很大时,要花很长时间才能看到按钮!我正在使用线程从数据库加载数据,但似乎创建每个按钮并填充 GridPane 花费的时间太长! *
您好,我目前正在使用 JavaFX 中的 GridPane,偶然发现了一个问题...我想创建一个包含三行的布局,其中中间一行会增长并占用所有可用空间,但我无法得到它工作。中间的行变得太大,并将窗口下方
对于 GUI,我必须将多个按钮设置为 GridPane。为此,我想问一下是否有一种方法可以比我更优雅地在网格中添加多个按钮。这是我的代码的摘录。 Button button0 =new Button(
我正在编写一个生成随机颜色网格的 JavaFX 程序。调整窗口大小时,网格应调整为尽可能大,同时仍保持正方形并在底部为文本留出空间。 一切正常,但我遇到的问题是调整大小时 GridPane 中留下的间
我正在使用 JavaFX 8。尝试使用 GridPage 来显示一组属性和值。有些值可能太长,无法放在一行中。我想包装这些值,但似乎无法弄清楚如何使网格 Pane 垂直扩展以容纳包装的文本。我基本上想
我正在尝试使用 GridPane 创建登录 UI。我的窗口以 300 x 300 打开,并且我已将行和列索引设置为某些值,以便我的文本“用户 ID”和“密码”出现在窗口的中心(与所有四个边的距离相等)
我有这个构造函数,我正在尝试用标签填充网格 Pane 。我碰壁了,不知道出了什么问题。我需要在 1 行中创建 13 个标签。 构造函数: public class Labels { @FXML
我已经在我的游戏中实现了拖放功能,但到目前为止我只能“拖放”到硬编码位置。如图所示: 我想要的是: 当飞船被放下时,它的 x,y 值(相对于 GridPane)被保存,或者 保存飞船掉落的单元格。 我
我是一名优秀的程序员,十分优秀!