【问题标题】:JavaFX - question regarding binding button's disabled stateJavaFX - 关于绑定按钮的禁用状态的问题
【发布时间】:2023-03-24 10:24:02
【问题描述】:

我正在尝试创建一个维护任务列表的虚拟应用程序。

目前,我要做的只是添加到列表中。我在文本框中输入任务名称,单击添加任务按钮,并希望列表会更新为新项目并清除任务名称输入。如果任务名称不为空,我只希望能够添加任务。下面的代码是我的实现,但我对绑定有疑问。

我将文本框的文本变量绑定到视图模型中的字符串,并将按钮的禁用变量绑定到视图模型中的布尔值。

当任务名称更改时,我有一个触发器来更新禁用状态。当任务名称发生绑定时,布尔值会相应更新,但按钮仍显示为禁用。但是当我将鼠标悬停在按钮上时,它就会启用。我相信这是由于 JavaFX 1.3 的绑定是惰性的 - 仅在读取绑定变量时才更新它。

另外,当我添加任务时,我会清除模型中的任务名称,但文本框的文本不会改变 - 即使我使用的是bind with inverse

有没有办法按照我的预期通过绑定自动更新文本框的文本和按钮的禁用状态?

谢谢,

詹姆斯

AddTaskViewModel.fx:

package jamiebarrow;

import java.lang.System;

public class AddTaskViewModel {

function logChange(prop:String,oldValue,newValue):Void {
    println("{System.currentTimeMillis()} : {prop} [{oldValue}] to [{newValue}] ");
}


    public var newTaskName: String on replace old {
        logChange("newTaskName",old,newTaskName);
        isAddTaskDisabled = (newTaskName == null or newTaskName.trim().length() == 0);
    };
    public var isAddTaskDisabled: Boolean on replace old {
        logChange("isAddTaskDisabled",old,isAddTaskDisabled);
    };
    public var taskItems = [] on replace old {
        logChange("taskItems",old,taskItems);
    };

    public function addTask() {
        insert newTaskName into taskItems;
        newTaskName = "";
    }

}

Main.fx:

package jamiebarrow;

import javafx.scene.control.Button;
import javafx.scene.control.TextBox;
import javafx.scene.control.ListView;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.scene.layout.HBox;

def viewModel = AddTaskViewModel{};

var txtName: TextBox = TextBox {
            text: bind viewModel.newTaskName with inverse
            onKeyTyped: onKeyTyped
        };

function onKeyTyped(event): Void {
    txtName.commit(); // ensures model is updated
    cmdAddTask.disable = viewModel.isAddTaskDisabled;// the binding only occurs lazily, so this is needed
}

var cmdAddTask = Button {
            text: "Add"
            disable: bind viewModel.isAddTaskDisabled with inverse
            action: onAddTask
        };

function onAddTask(): Void {
    viewModel.addTask();
}

var lstTasks = ListView {
            items: bind viewModel.taskItems with inverse
        };

Stage {
    scene: Scene {
        content: [
            VBox {
                content: [
                    HBox {
                        content: [
                            txtName,
                            cmdAddTask
                        ]
                    },
                    lstTasks
                ]
            }
        ]
    }
}

【问题讨论】:

  • 注意:onKeyTyped 方法可以确保文本框在用户键入而不是失去焦点时更新模型,并更新 cmdAddButton 状态。

标签: binding javafx viewmodel presentation-model


【解决方案1】:

作为记录,这个问题已经在question regarding binding button’s disabled state线程中得到了回答。

简短的总结:JavaFX 1.3 中有一个错误,用于bind with inverse 到对象中的字段。有一种解决方法,但它破坏了封装。

【讨论】:

  • 再次感谢 PhiLho。尚未实际实施更改,但看起来不错,所以相信它现在可以工作:) 有机会时会再次检查。
猜你喜欢
  • 2020-01-27
  • 2013-05-29
  • 1970-01-01
  • 1970-01-01
  • 2014-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多