package scenegraphdemo; import javafx.application.Application; import javafx.beans.property.StringProperty; import javafx.collections.FXCollections; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.control.ListCell; import javafx.scene.control.ListView; import javafx.scene.control.Menu; import javafx.scene.control.MenuBar; import javafx.scene.control.MenuItem; import javafx.scene.control.SplitPane; import javafx.scene.control.TreeCell; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeView; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.Stage; import javafx.util.Callback; public class Main extends Application { @Override public void start(Stage stage) { MenuBar menu = new MenuBar(); Menu fileMenu = new Menu("File"); MenuItem fileExit = new MenuItem("Exit"); fileMenu.getItems().addAll(fileExit); fileExit.setOnAction(new EventHandler() { @Override public void handle(ActionEvent arg0) { try { Main.this.stop(); System.exit(0); } catch (Exception e) { e.printStackTrace(); } } }); Menu editMenu = new Menu("Edit"); Menu helpMenu = new Menu("Help"); menu.getMenus().setAll(fileMenu, editMenu, helpMenu); TreeView tv = new TreeView(); TreeItem item1 = new TreeItem(); item1.setValue("Repository"); TreeItem item2 = new TreeItem(); item2.setValue(new Person("John", "Smith", "John.Smith@gmail.com")); item1.getChildren().add(item2); TreeItem item3 = new TreeItem(); item3.setValue(new Person2("Moe", "Curly", "Moe.Curly@gmail.com")); item2.getChildren().add(item3); tv.setCellFactory(TemplatedTreeCell.createCellFactoryCallback()); tv.setRoot(item1); Node editorArea = createEditorArea(); SplitPane sp = new SplitPane(); sp.getItems().addAll(tv, editorArea); sp.setDividerPositions(0.3); BorderPane pane = new BorderPane(); pane.setTop(menu); pane.setCenter(sp); // Add resources for displaying things. sp.getProperties().put(Person.class, new DataTemplate(Person.class) { @Override protected Node loadContent(BeanPropertyFactory factory) { HBox box = new HBox(8); Label label = new Label(); label.textProperty().bind(factory.getProperty("blah")); Label label2 = new Label(); label2.textProperty().bind(factory.getProperty("firstname")); Label label3 = new Label(); label3.textProperty().bind(factory.getProperty("email")); box.getChildren().addAll(label, label2,label3); return box; } }); sp.getProperties().put(Person2.class, new DataTemplate(Person2.class) { @Override protected Node loadContent(BeanPropertyFactory factory) { VBox box = new VBox(3); Label label = new Label(); label.setText("Vertical presentation..."); Label label2 = new Label(); label2.textProperty().bind(factory.getProperty("firstname")); Label elabel = new Label(); elabel.textProperty().bind(factory.getProperty("email")); box.getChildren().addAll(label, label2, elabel); return box; } }); Scene scene = new Scene(pane, 800, 500); stage.setTitle("CDMA"); stage.setScene(scene); stage.setVisible(true); } protected Node createEditorArea() { // Label label = new Label("editor area"); // return label; ListView lv = new ListView(); Person p1 = new Person("Korny", "Blog", "f@j"); Person2 p2 = new Person2("Hugey", "Apple", "H@A"); lv.setItems(FXCollections.observableArrayList(p1, p2)); lv.setCellFactory(TemplatedListCell.createCellFactoryCallback()); return lv; } public static interface ScenegraphSearch { Node find(Object arg); } /** * This class searches for scenegraph objects using a prescribed search * algorithm. Client's use this class to find an object to bind to. * */ public static class ObservableValueFromAncestor implements ScenegraphSearch { int level = 1; Class targetClass; boolean dynamic = false; Node cache; public ObservableValueFromAncestor(Class targetClass, int level) { this.targetClass = targetClass; this.level = level; } /** * If true, the result of a find call is not cached. The default is * false. * * @return */ public boolean isDynamic() { return dynamic; } public void setDynamic(boolean dynamic) { this.dynamic = dynamic; } /** * Maximum level upwards to search. The level above the current find * parameter is considered level 1. 1 is the default and hence by * default the algorithm only searches up one level of ancestry. * * @return */ public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } public Class getTargetClass() { return targetClass; } public void setTargetClass(Class targetClass) { this.targetClass = targetClass; } /** * Return the object to bind to. * * @return */ public Node find(Object arg) { if (cache != null && !isDynamic()) return cache; if (!(arg instanceof Node)) { return null; } Node n = (Node) arg; int currentLevel = 1; while (n != null && currentLevel <= level) { if (targetClass.isAssignableFrom(n.getClass())) { if (isDynamic()) cache = n; return n; } currentLevel++; n = n.getParent(); } return null; } } public static void main(String[] args) { Application.launch(args); } }