Skip to content

Instantly share code, notes, and snippets.

@jewelsea
Created October 30, 2013 08:55
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save jewelsea/7229260 to your computer and use it in GitHub Desktop.
Save jewelsea/7229260 to your computer and use it in GitHub Desktop.
Sample for creating a role based UI using JavaFX FXML
public enum Role { FATHER, SON, MOTHER, DAUGHTER, BROTHER, SISTER }
import javafx.collections.*;
import javafx.scene.*;
import java.util.*;
public 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) {
if (roles.length == 0) {
nodeRoles.remove(node);
return;
}
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 void assignRolesToNodeTree(Node node) {
Object userData = node.getUserData();
if (userData instanceof ObservableList) {
List<Role> roles = new ArrayList<>();
for (Object object: (ObservableList) userData) {
if (object instanceof Role) {
roles.add((Role) object);
}
}
Role[] roleArray = new Role[roles.size()];
int i = 0;
for (Role role: roles) {
roleArray[i++] = role;
}
assignRole(node, roleArray);
}
if (node instanceof Parent) {
Parent parent = (Parent) node;
for (Node child: parent.getChildrenUnmodifiable()) {
assignRolesToNodeTree(child);
}
}
}
}
<?import javafx.collections.FXCollections?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.HBox?>
<?import Role?>
<HBox fx:id="root" prefWidth="-1.0" spacing="10.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
<children>
<Label contentDisplay="TOP" text="Darth Vader">
<userData>
<FXCollections fx:factory="observableArrayList">
<Role fx:value="FATHER"/>
</FXCollections>
</userData>
<graphic>
<ImageView>
<image>
<Image url="http://icons.iconarchive.com/icons/jonathan-rey/star-wars-characters/128/Vader-03-icon.png" />
</image>
</ImageView>
</graphic>
</Label>
<Label contentDisplay="TOP" text="Queen Amidala">
<userData>
<FXCollections fx:factory="observableArrayList">
<Role fx:value="MOTHER"/>
</FXCollections>
</userData>
<graphic>
<ImageView>
<image>
<Image url="http://icons.iconarchive.com/icons/jonathan-rey/star-wars-characters/128/Padme-Amidala-icon.png" />
</image>
</ImageView>
</graphic>
</Label>
<Label contentDisplay="TOP" text="Luke Skywalker">
<userData>
<FXCollections fx:factory="observableArrayList">
<Role fx:value="SON"/>
<Role fx:value="BROTHER"/>
</FXCollections>
</userData>
<graphic>
<ImageView>
<image>
<Image url="http://icons.iconarchive.com/icons/jonathan-rey/star-wars-characters/128/Luke-Skywalker-01-icon.png" />
</image>
</ImageView>
</graphic>
</Label>
<Label contentDisplay="TOP" text="Princess Leia">
<userData>
<FXCollections fx:factory="observableArrayList">
<Role fx:value="DAUGHTER"/>
<Role fx:value="SISTER"/>
</FXCollections>
</userData>
<graphic>
<ImageView>
<image>
<Image url="http://icons.iconarchive.com/icons/jonathan-rey/star-wars-characters/128/Leia-icon.png" />
</image>
</ImageView>
</graphic>
</Label>
</children>
</HBox>
import javafx.fxml.FXML;
import javafx.scene.Node;
public class RolePlayController {
@FXML private Node root;
private RoleManager roleManager;
public RolePlayController(RoleManager roleManager) {
this.roleManager = roleManager;
}
@FXML public void initialize() {
roleManager.assignRolesToNodeTree(root);
}
}
import javafx.application.Application;
import javafx.beans.value.*;
import javafx.collections.*;
import javafx.fxml.FXMLLoader;
import javafx.scene.*;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import java.io.IOException;
public class RoleVisibility extends Application {
private RoleManager roleManager = new RoleManager();
@Override
public void start(Stage stage) throws IOException {
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().toLowerCase());
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() throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setController(new RolePlayController(roleManager));
return loader.load(
getClass().getResourceAsStream("roleplay.fxml")
);
}
public static void main(String[] args) {
launch(args);
}
}
@jewelsea
Copy link
Author

Answer to StackOverflow question: Is there a way to implement a property like “rendered” on JAVAFX? - which is really "How to create a role based JavaFX UI using FXML"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment