有没有办法只在满足条件时才在Javafx中“渲染”组件?我有兴趣做一个具有不同角色的用户界面,如果角色允许,只需添加一个组件,我也想继续使用FXML。我没有读过类似的东西。
绑定可见性
将组件的visible属性绑定到BooleanExpression,该BooleanExpression表示该组件应可见的条件。
FXML可以进行绑定,但请注意,从JavaFX 2.2开始,“目前仅支持解析为属性值或页面变量的简单表达式。将来可能会添加对涉及布尔或其他运算符的更复杂表达式的支持。”
如果不在 FXML 中绑定,则可以使用 JavaFX API 在 Java 代码中绑定。
node.visibleProperty().bind(conditionProperty);
如果不想让不可见属性占用布局空间,也要先将托管属性绑定到可见属性。
node.managedProperty().bind(node.visibleProperty());
在更改侦听器中交替更改可见性
请注意,为基于角色的完整系统设置绑定非常复杂,因此对于这样的任务,您最好使用更改侦听器并在Java中编码部分逻辑,而不是尝试在FXML中执行所有操作。您仍然可以在FXML中设计您的UI,但您可以在控制器中添加一些代码来管理哪些项目对哪个角色可见。
基于角色的显示示例
这里是一个使用Java API的基于角色的解决方案。
解决方案根据所选角色显示不同的标记图片。
import javafx.application.Application;
import javafx.beans.value.*;
import javafx.collections.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import java.util.*;
enum Role { father, son, mother, daughter, brother, sister }
class RoleManager {
private final Map<Node, List<Role>> nodeRoles = new HashMap<>();
private ObservableList<Role> activeRoles;
public final ListChangeListener<Role> ACTIVE_ROLE_LISTENER = new ListChangeListener<Role>() {
@Override
public void onChanged(Change<? extends Role> c) {
showActiveNodes();
}
};
public void setActiveRoles(ObservableList<Role> activeRoles) {
if (this.activeRoles != null) {
this.activeRoles.removeListener(ACTIVE_ROLE_LISTENER);
}
this.activeRoles = activeRoles;
this.activeRoles.addListener(ACTIVE_ROLE_LISTENER);
}
public void showActiveNodes() {
for (Node node : nodeRoles.keySet()) {
node.setVisible(isActive(node));
}
}
public void assignRole(Node node, Role... roles) {
nodeRoles.put(node, Arrays.asList(roles));
}
private boolean isActive(Node node) {
if (activeRoles == null) {
return false;
}
for (Role role: nodeRoles.get(node)) {
if (activeRoles.contains(role)) {
return true;
}
}
return false;
}
}
public class RoleVisibility extends Application {
private RoleManager roleManager = new RoleManager();
@Override
public void start(Stage stage) {
VBox layout = new VBox(10);
layout.getChildren().setAll(
getRoleChooser(),
createContent()
);
layout.setStyle("-fx-padding: 10px; -fx-background-color: cornsilk;");
roleManager.showActiveNodes();
stage.setTitle("Role Selector");
stage.setScene(new Scene(layout));
stage.show();
}
private Node getRoleChooser() {
ObservableList<Role> activeRoles = FXCollections.observableArrayList();
VBox roleChooser = new VBox(10);
for (final Role role: Role.values()) {
CheckBox checkBox = new CheckBox(role.toString());
checkBox.selectedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean wasSelected, Boolean isSelected) {
if (isSelected) {
activeRoles.add(role);
} else {
activeRoles.remove(role);
}
}
});
roleChooser.getChildren().add(checkBox);
}
roleManager.setActiveRoles(
activeRoles
);
return roleChooser;
}
private Pane createContent() {
HBox content = new HBox(10);
// icon license:
//License: Free for non-commercial use.
//Commercial usage: Not allowed
//The products or characters depicted in these icons are © by Lucasfilm Ltd.
content.getChildren().addAll(
createLabel("Darth Vader", "Vader-03-icon.png", Role.father),
createLabel("Queen Amidala", "Padme-Amidala-icon.png", Role.mother),
createLabel("Luke Skywalker", "Luke-Skywalker-01-icon.png", Role.brother, Role.son),
createLabel("Princess Leia", "Leia-icon.png", Role.daughter, Role.sister)
);
return content;
}
private Label createLabel(String text, String graphic, Role... roles) {
Label label = new Label(
text,
new ImageView(
new Image(
"http://icons.iconarchive.com/icons/jonathan-rey/star-wars-characters/128/" + graphic
)
)
);
label.setContentDisplay(ContentDisplay.TOP);
roleManager.assignRole(label, roles);
return label;
}
public static void main(String[] args) {
launch(args);
}
}
基于FXML的解决方案
我对如何让这样的东西与FXML一起工作很感兴趣,所以我创建了一个小框架来处理基于角色的FXML UIs。它可能会有一些性能增强,并为定义基于角色的控制器添加一些方便的定义,以及为FXML中的角色定义添加缩写,但它似乎在原理上是可行的,并演示了一种基本方法。
问题内容: 首先,我阅读了埃里克森对“为什么不能在Java接口中定义静态方法?”的有用答复。。这个问题不是关于“为什么”的问题,而是关于“然后如何做”的问题。 编辑:我的原始示例不适当地,但我将其保留在下面。 虽然我现在确信在大多数情况下我想做的是过度矫kill过正,但在一种情况下可能需要这样做: 我再举一个例子。现在,让我们采用一个适合于查找表的复杂功能,例如Bessel函数。这必须进行初始化,
假设有一个类库X的输入文件,其中包含一些接口。 为了使用这个库,我需要传递一个与。当然,我可以在源文件中创建相同的接口: 但这样一来,我就有了让它和库中的一个保持最新的负担,而且它可能非常大,并导致大量代码重复。 因此,有没有办法“提取”接口的这个特定属性的类型?类似于(这不起作用,导致“找不到名称I2”错误)。 编辑:在TS操场上玩了一会儿后,我注意到以下代码完全实现了我想要的: 但是,它需要声
问题内容: 在Python中实现方法非常容易,这样它就可以处理这样的调用: 而且有很多相似的方法,你可以定义(,,等)。我知道Python类也是对象。 我的问题:例如,我可以以某种方式进行定义以使以下工作有效: 问题答案: 你正在寻找被称为“元类” ......就像是类的一个实例,是为好,被称为元类类的一个实例。默认情况下,Python类是该类的实例(唯一的例外是Python 2,它具有一些旧式的
问题内容: 我知道您可以通过执行 node.requestFocus(); 来将焦点集中在javafx中的一个节点上 。 但是有没有办法从javafx中的节点上夺走焦点或阻止对某个对象的焦点? 问题答案: 我不认为有任何保证将始终有效,但是您可以尝试将焦点设置为本质上不接受键盘输入的内容(例如布局窗格):
问题内容: 假设我们具有以下类层次结构: 如果像这样在ClassB上浏览 dict ,我只会看到bar属性: 输出为bar 我可以运用自己的方式来获取属性,不仅是指定类型,还包括其祖先。但是,我的问题是python是否已经有一种方法可以在不重新发明轮子的情况下做到这一点。 如下运行我的代码… …同时返回bar和foo。 请注意,我正在简化一些事情:名称冲突,在本例中可以使用dict时使用items
我试图在java中使用Hibernate和TypedQuery。 我试图调用的方法有一个签名 我想像bellow一样调用它,但是用一个真实的实例替换null。 上面的代码经过编译,但显然带有空指针异常。 如果我对擦除的理解是正确的,那么只要我得到类对象的一个实例,这就行了,因为所有泛型类型信息在运行时都会丢失。 是否有任何方法,我可以得到一个类的实例,我可以分配给变量cls,使这个代码将工作?