【问题标题】:JavaFX Change text for multiple buttons in one operationJavaFX在一次操作中更改多个按钮的文本
【发布时间】:2016-12-31 01:14:33
【问题描述】:

我需要在运行时更改多个按钮的文本。 就像这样,Change text for multiple buttons in one operation,但在 JavaFX 中。

【问题讨论】:

  • 你有一个数组或列表中的所有按钮引用吗?所有按钮都布置在一个父控件中吗?您指的是哪个“操作”负责更改文本?
  • 我真的不需要更改文本。我需要更改背景颜色。按钮位于 GridView 中,希望位于另一个 GridViewn 中。 “操作”是一个 ColorPicker onAction 事件。我可以更改一个按钮的颜色,但需要对 9x9 的按钮网格进行更改。
  • 如果你想改变颜色而不是文本,这可以非常简单地使用 CSS 来完成。你应该edit你的问题说清楚。

标签: java javafx


【解决方案1】:

要更改颜色(这是您在 cmets 中指定的内容),您可以使用 CSS。

如果你给你的主GridPane 一个id 为grid,那么下面的CSS 将使网格中的所有按钮(直接后代或后代的后代等)具有白色的基色(背景颜色,以及“悬停的颜色”和“按下的颜色”都是从基色派生的):

#grid {
    -sudoku-button-color: white ;
}

#grid .button {
    -fx-base: -sudoku-button-color ;
}

现在在控制器中,您需要做的就是切换颜色:

grid.setStyle("-sudoku-button-color: ... ;");

以某种可接受的 CSS 格式传递新颜色。

如果要为每个按钮设置文本,则需要遍历按钮并依次设置每个文本。如果将按钮放在一个数组中,这会变得更容易。请注意,您可以通过为数独网格中的“块”定义 FXML 并在主网格中包含九个这样的块来进一步避免重复。

以下演示了所有这些技术:

数独.css:

#grid {
    -sudoku-button-color: white ;
    -fx-padding: 2 ;
}

.sudoku-block {
    -fx-padding: 2 ;
    -fx-border-color: black ;
}

#grid .button {
    -fx-base: -sudoku-button-color ;
    -fx-max-width: Infinity ;
    -fx-max-height: Infinity ;
}

数独块.fxml:

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

<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>

<GridPane styleClass="sudoku-block" xmlns:fx="http://javafx.com/fxml/1" fx:controller="BlockController">
    <Button fx:id="button0" GridPane.columnIndex="0" GridPane.rowIndex="0" />
    <Button fx:id="button1" GridPane.columnIndex="1" GridPane.rowIndex="0" />
    <Button fx:id="button2" GridPane.columnIndex="2" GridPane.rowIndex="0" />
    <Button fx:id="button3" GridPane.columnIndex="0" GridPane.rowIndex="1" />
    <Button fx:id="button4" GridPane.columnIndex="1" GridPane.rowIndex="1" />
    <Button fx:id="button5" GridPane.columnIndex="2" GridPane.rowIndex="1" />
    <Button fx:id="button6" GridPane.columnIndex="0" GridPane.rowIndex="2" />
    <Button fx:id="button7" GridPane.columnIndex="1" GridPane.rowIndex="2" />
    <Button fx:id="button8" GridPane.columnIndex="2" GridPane.rowIndex="2" />
</GridPane>

BlockController.java:

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;

public class BlockController {

    @FXML
    private Button button0 ;
    @FXML
    private Button button1 ;
    @FXML
    private Button button2 ;
    @FXML
    private Button button3 ;
    @FXML
    private Button button4 ;
    @FXML
    private Button button5 ;
    @FXML
    private Button button6 ;
    @FXML
    private Button button7 ;
    @FXML
    private Button button8 ;

    private Button[][] buttons ;

    public void initialize() {
        buttons = new Button[][]{
                { button0, button1, button2 },
                { button3, button4, button5 },
                { button6, button7, button8 }
        };
        for (Button[] buttonRow : buttons) {
            for (Button button : buttonRow) {
                GridPane.setFillHeight(button, true);
                GridPane.setFillWidth(button, true);
            }
        }
    }

    public void setButtonText(int column, int row, String text) {
        buttons[column][row].setText(text);
    }
}

SudokuGrid.fxml:

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

<?import javafx.scene.control.ColorPicker?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.GridPane?>


<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="SudokuController" >

    <top>
        <ColorPicker fx:id="colorPicker" onAction="#changeColor" />
    </top>

    <center>

        <GridPane fx:id="grid" id="grid">
            <fx:include source="SudokuBlock.fxml" fx:id="block0" GridPane.columnIndex="0" GridPane.rowIndex="0" />
            <fx:include source="SudokuBlock.fxml" fx:id="block1" GridPane.columnIndex="1" GridPane.rowIndex="0" />
            <fx:include source="SudokuBlock.fxml" fx:id="block2" GridPane.columnIndex="2" GridPane.rowIndex="0" />
            <fx:include source="SudokuBlock.fxml" fx:id="block3" GridPane.columnIndex="0" GridPane.rowIndex="1" />
            <fx:include source="SudokuBlock.fxml" fx:id="block4" GridPane.columnIndex="1" GridPane.rowIndex="1" />
            <fx:include source="SudokuBlock.fxml" fx:id="block5" GridPane.columnIndex="2" GridPane.rowIndex="1" />
            <fx:include source="SudokuBlock.fxml" fx:id="block6" GridPane.columnIndex="0" GridPane.rowIndex="2" />
            <fx:include source="SudokuBlock.fxml" fx:id="block7" GridPane.columnIndex="1" GridPane.rowIndex="2" />
            <fx:include source="SudokuBlock.fxml" fx:id="block8" GridPane.columnIndex="2" GridPane.rowIndex="2" />
        </GridPane>

    </center>
</BorderPane>

数独控制器.java:

import javafx.fxml.FXML;
import javafx.scene.control.ColorPicker;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;

public class SudokuController {


    @FXML
    private ColorPicker colorPicker ;
    @FXML
    private GridPane grid ;
    @FXML
    private BlockController block0Controller ;
    @FXML
    private BlockController block1Controller ;
    @FXML
    private BlockController block2Controller ;
    @FXML
    private BlockController block3Controller ;
    @FXML
    private BlockController block4Controller ;
    @FXML
    private BlockController block5Controller ;
    @FXML
    private BlockController block6Controller ;
    @FXML
    private BlockController block7Controller ;
    @FXML
    private BlockController block8Controller ;

    private BlockController[][] blocks ;

    public void initialize() {
        blocks = new BlockController[][] {
            { block0Controller, block1Controller, block2Controller },
            { block3Controller, block4Controller, block5Controller },
            { block6Controller, block7Controller, block8Controller }            
        };

        for (int blockColumn = 0 ; blockColumn < 3 ; blockColumn++) {
            for (int blockRow = 0 ; blockRow < 3 ; blockRow++) {

                for (int columnInBlock = 0 ; columnInBlock < 3 ; columnInBlock++) {
                    for (int rowInBlock = 0 ; rowInBlock < 3 ; rowInBlock++) {

                        int column = blockColumn * 3 + columnInBlock ;
                        int row = blockRow * 3 + rowInBlock ;

                        String text = String.format("[%d, %d]", column, row);

                        blocks[blockColumn][blockRow].setButtonText(columnInBlock, rowInBlock, text);

                    }
                }

            }
        }
    }

    @FXML
    private void changeColor() {
        Color color = colorPicker.getValue();
        int r = (int) (255 * color.getRed());
        int g = (int) (255 * color.getGreen());
        int b = (int) (255 * color.getBlue());
        String formattedColor = String.format("#%02x%02x%02x", r, g, b);
        grid.setStyle("-sudoku-button-color: "+formattedColor+";");


    }
}

最后是应用程序类,Sudoku.java:

import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Sudoku extends Application {

    @Override
    public void start(Stage primaryStage) throws IOException {
        Scene scene = new Scene(FXMLLoader.load(getClass().getResource("SudokuGrid.fxml")));
        scene.getStylesheets().add("sudoku.css");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

截图:

【讨论】:

  • 这是一个非常好的方法,因为据我了解,这解决了文本、颜色和其他问题,因为我可以直接访问按钮属性。您正在构建一个对象(BlockController),它是一组 9x9 按钮。然后构建一个 9x9 的 BlockControllers 数组。而这个 blocks[blockColumn][blockRow] 是一个单独的按钮。非常非常棒。谢谢你分配@James_D。这超出了我的要求。
【解决方案2】:

一个非常简单的解决方案是遍历 GridPane 的子列表,如果它们是 Button 的实例,则对它们进行操作:

colorPicker.setOnAction(e -> {
   ObservableList<Node> children = gridPane.getChildren();
   for (Node child : children) {
       if (child instanceof Button) {
          // Do something
       }
   }
});

【讨论】:

  • 谢谢,效果很好。我是 Java 新手,但不知何故设法实现了该代码。但是...通过将 gridPane 导入到 Controler (@FXML GridPane gp),我失去了对按钮的直接访问权限。例如,我有 bt00.setText("kldfjg") 的每个地方都停止工作。另一个问题是我更改了 GridPane 中的所有按钮,但另一个 gridPane 中有 9 个 GridPane。在@FXML 中声明这只是设置按钮文本的噩梦。 PS,它是一个数独网格,我想突出一个孔方形,线和柱。
  • 对于这么大的节点,我通常不会使用 FXML 创建它们。我将使用 FXML 创建最基本的 UI,其余的可以通过 Java 代码动态创建。 P.S. - 您不应在评论部分添加与当前问题无关的问题。相反,你应该问一个新问题 :)
  • 好吧,但它必须是 FXML。所以,我无能为力。我希望有一个简单的方法,但......没关系......关于这个问题,没有看到需要一个新问题。你的答案当然是正确的。有效。谢谢。我将逐个按钮更改它。
  • 学校项目...不是我的规则 :(
  • @JPedro 为什么它“必须是 FXML”?
猜你喜欢
  • 2011-06-11
  • 2017-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-03
  • 2016-01-24
  • 1970-01-01
  • 2011-09-11
相关资源
最近更新 更多