如何在JavaFX中将可见性绑定到控制器

时间:2014-11-20 03:45:18

标签: java binding javafx javafx-2 fxml

我正在尝试使用JavaFX为我的游戏创建一个菜单。我希望有一个“继续”按钮,我只希望在游戏运行时可见。我正在尝试将按钮的可见性属性绑定到控制器,但它似乎没有工作 - 按钮只是不可见。

我查看了Google和StackExchange,并且我已经找到了有关如何以编程方式设置它的信息,但我宁愿不将Java代码与FXML结合得比我真正需要的更紧密。

这是我的FXML页面代码......

<?xml version="1.0" encoding="UTF-8"?>
    <?import javafx.geometry.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.text.*?>

<GridPane fx:controller="com.silferein.erq.gui.MenuController" 
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
    <padding><Insets top="25" right="25" bottom="25" left="25"/></padding>

    <Text id="welcome-text" text="Main Menu" GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="2"/>
    <Button text="New" onAction="#handleNew" GridPane.rowIndex="1"/>
    <Button text="Continue" onAction="#handleContinue" GridPane.rowIndex="2" visible="${controller.gameRunning}" />
    <Button text="Load" onAction="#handleLoad" GridPane.rowIndex="3"/>
    <Button text="Save" onAction="#handleSave" GridPane.rowIndex="4"/>
    <Button text="Quit" onAction="#handleQuit" GridPane.rowIndex="5"/>
</GridPane>

这是我的控制器代码(略微修剪):

@FXML protected void handleContinue(ActionEvent event) {
    System.out.println("Continue!");
    parent.handle(new GUIEvent(GUIEvent.Type.CONTINUE));
}
// ...
@FXML protected boolean getGameRunning() {
    System.out.println("Test!");
    // Some check to see if there's a game in progress...
    return true;
}

知道我做错了什么吗?我的代码编译,除“继续”之外的所有按钮都可见且有效。

2 个答案:

答案 0 :(得分:2)

创建一个BooleanProperty:

BooleanProperty isGameRunning = new SimpleBooleanProperty(false);

让你的&#39;继续&#39; - 按钮fx:id(比如btnContinue)并将其注入控制器。

@Inject Button btnContinue;

将按钮可见性属性绑定到isGameRunning属性。 (在初始化方法中执行此操作)

btnContinue.visibleProperty().bind(isGameRunning);

现在每当您更改isGameRunning的值时,按钮的可见性都会发生变化。

答案 1 :(得分:2)

正如haisi概述的那样,缺少的链接是扩展Initialize()方法以创建从yout gameRunning布尔(Property)到按钮的visibleProperty()的属性绑定:

FXML:

xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
    <padding><Insets top="25" right="25" bottom="25" left="25"/></padding>

    <Text id="welcome-text" text="Main Menu" GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="2"/>
    <Button text="New" onAction="#handleNew" GridPane.rowIndex="1"/>
    <Button fx:id="continueBtn" text="Continue" onAction="#handleContinue" GridPane.rowIndex="2" />
    <Button text="Load" onAction="#handleLoad" GridPane.rowIndex="3"/>
    <Button text="Save" onAction="#handleSave" GridPane.rowIndex="4"/>
    <Button text="Quit" onAction="#handleQuit" GridPane.rowIndex="5"/>
</GridPane>

类别:

public class GameController implements Initializable {
    private BooleanProperty gameRunning = new SimpleBooleanProperty(false);

    @FXML Button continueBtn;

    @FXML protected void handleNew(ActionEvent event) {
        gameRunning.set(true);
    }
    @FXML protected void handleLoad(ActionEvent event) {

    }
    @FXML protected void handleSave(ActionEvent event) {

    }
    @FXML protected void handleQuit(ActionEvent event) {
        gameRunning.set(false);
    }
    @FXML protected void handleContinue(ActionEvent event) {
        System.out.println("Continue!");
        //parent.handle(new GUIEvent(GUIEvent.Type.CONTINUE));
    }
    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        continueBtn.visibleProperty().bind(gameRunning);  
    }
}

我有期望,将gameRunning实现为完整的javafx bean属性(setGameRunning,getGameRunning,gameRunningProperty)并且visible =“$ {gameRunning}”应该自动解决,但无法正常实现。已经在Binding a Label's text property (in an FXML file) to an IntegerProperty (in a controller)

中进行了讨论