Adding multiple tree Branches and leafs in javafx - javafx

hi i post this question before but didn't get any answer. Adding tree Branches and leafs in TreeView
i need help, Please have a look at code,
public class Main extends Application
{
private BorderPane border;
#Override
public void start(Stage primaryStage)
{
border = new BorderPane();
Scene scene = new Scene(border,200,200);
primaryStage.setTitle("BorderPane");
primaryStage.setScene(scene);
primaryStage.show();
TreeItem<String> tree = new TreeItem<String>("Root");
TreeItem<String> item1 = new TreeItem<String>("Branch");
item1.getChildren().add(new TreeItem<String>("Leaf"));
item1.setExpanded(true);
tree.setExpanded(true);
tree.getChildren().addAll(item1);
TreeView<String> treeView = new TreeView<String>(tree);
treeView.setEditable(true);
treeView.setCellFactory(new Callback<TreeView<String>,TreeCell<String>>(){
#Override
public TreeCell<String> call(TreeView<String> arg0) {
return new AddMenuTreeCell();
}
});
VBox vbox =new VBox(2);
vbox.setPadding(new Insets(5));
VBox.setVgrow(treeView, Priority.ALWAYS);
vbox.getChildren().addAll(treeView);
border.setLeft(vbox);
}
private static class AddMenuTreeCell extends TextFieldTreeCell<String> {
private ContextMenu menu = new ContextMenu();
private TextField textField;
public AddMenuTreeCell() {
MenuItem addItem1 = new MenuItem("Insert Branch");
MenuItem addItem2 = new MenuItem("Insert Leaf");
menu.getItems().addAll(addItem1,addItem2);
addItem1.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
TreeItem<String> newBranch =
new TreeItem<String>("Brunch");
getTreeItem().getChildren().add(newBranch);
}
});
addItem2.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
TreeItem<String> newLeaf =
new TreeItem<String>("leaf");
getTreeItem().getChildren().add(newLeaf);
}
});
}
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty && getTreeItem().getParent() == null){
setContextMenu(menu);
}
}
}
}
With this user can add multiple Branches and Leafs.
But the problem is, if user add a Branch it should be like "Branch1" next added branch should be "Branch2", "Branch3",...... same for leafs added in any branch have their numbers.
So that later on user can assign different task to different branches and leafs.
Thank you!

Replace AddMenuTreeCell class to below code and try now
private static class AddMenuTreeCell extends TextFieldTreeCell<String> {
private ContextMenu menu = new ContextMenu();
private TextField textField;
int i = 1, j = 1;
public AddMenuTreeCell() {
MenuItem addItem1 = new MenuItem("Insert Branch");
MenuItem addItem2 = new MenuItem("Insert Leaf");
menu.getItems().addAll(addItem1, addItem2);
addItem1.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
TreeItem<String> newBranch = new TreeItem<String>("Brunch" + i);
getTreeItem().getChildren().add(newBranch);
i++;
}
});
addItem2.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
TreeItem<String> newLeaf = new TreeItem<String>("leaf" + j);
getTreeItem().getChildren().add(newLeaf);
j++;
}
});
setContextMenu(menu);
}
}

Related

JavaFX TableView custom header

i am customizing JavaFX TableView's header.
therefore i add a Graphic to the Label. By clicking the Label of the header i toggle my custom header(two lined). all this is working fine.
The header gets automatically resized so the custom headerfits in.
BUT, when i hide my custom headerthe headerstays large.
What am i missing so the headershrinks again?
i created a MCVE to demonstrate my problem:
public class TableViewHeaderMCVE extends Application {
private final TableView<Person> table = new TableView<>();
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
final VBox root = new VBox();
Scene scene = new Scene(root);
stage.setWidth(218);
stage.setHeight(216);
TableColumn colName = new TableColumn("name");
colName.setMinWidth(100);
colName.setSortable(false);
TableColumn colProfession = new TableColumn("profession");
colProfession.setMinWidth(100);
colProfession.setSortable(false);
table.getColumns().addAll(colName, colProfession);
root.getChildren().addAll(table);
stage.setScene(scene);
stage.show();
// apply this after show!
TableViewHeader.installMod(table);
}
public static class TableViewHeader {
public static void installMod(TableView table) {
for (Node n : table.lookupAll(".column-header > .label")) {
if (n instanceof Label) {
new CustomHeaderLabel((Label) n);
}
}
}
}
public static class CustomHeaderLabel extends BorderPane {
protected Label customNode = null;
BooleanProperty expanded = new SimpleBooleanProperty(this, "expanded", false);
public CustomHeaderLabel(final Label parent) {
Label label = new Label(parent.getText());
// custom MenuButton
Button btn = new Button();
btn.setGraphic(new Label("\u2261"));
btn.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent ae) {
System.out.println("Hello World");
}
});
TextField filterTextField = new TextField();
filterTextField.promptTextProperty().set("type here to filter");
setCenter(label);
setRight(btn);
setBottom(filterTextField);
EventHandler<MouseEvent> toggleHeader = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent me) {
expanded.set(!expanded.get());
}
};
parent.setOnMouseClicked(toggleHeader);
expanded.addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> obs, Boolean oldValue, Boolean value) {
showCustomHeader(value);
}
});
label.textProperty().bind(parent.textProperty());
parent.setGraphic(this);
customNode = parent;
showCustomHeader(expanded.get());
}
protected void showCustomHeader(Boolean value) {
if (value) {
customNode.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
customNode.setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
public static class Person {
private final SimpleStringProperty name;
private final SimpleStringProperty profession;
private Person(String name, String profession) {
this.name = new SimpleStringProperty(name);
this.profession = new SimpleStringProperty(profession);
}
public String getName() {
return name.get();
}
public String getProfession() {
return profession.get();
}
}
}
thanks to #James_D for his reply.
after his reply i tested the code on another computer
works on:
JDK 1.8.0_161 on Windows 10
JDK 9.0.4 and JDK 10 on Mac OS X
fails on:
JDK 1.8.0_66-b18 on Windows 7

Javafx: Adjusting TreeView with right order

Here is a TreeView in which User can add tree items like Roots and its Coordinates.
Problem is all newly added Roots have same rectangles generated by Coordinates. Every root should have its own result not same from other Roots. For this do i have to assign index for every root so that it has its own result?
public class Main extends Application
{ public static void main(String[] args)
{launch(args);}
static final Map<TreeItem<String>, BorderPane> map = new HashMap();
#Override
public void start(Stage primaryStage)
{
BorderPane root = new BorderPane();
TreeItem<String> tree = new TreeItem<String>("Main System");
TreeItem<String> item1 = new TreeItem<String>("Roots");
TreeView<String> treeView = new TreeView<String>(tree);
treeView.setOnMouseClicked((event)->{
TreeItem<String> TreeItem = (TreeItem<String>)treeView.getSelectionModel().getSelectedItem();
if(TreeItem.getValue().equals("Roots"))
{
root.setCenter(getRootsPanel());
}
else
{
root.setCenter(map.get(TreeItem));
}
});
treeView.setCellFactory(new Callback<TreeView<String>,TreeCell<String>>(){
#Override
public TreeCell<String> call(TreeView<String> p) {
return new AddMenuTreeCell();
}
});
tree.setExpanded(true);
root.setLeft(treeView);
tree.getChildren().add(item1);
Scene scene = new Scene(root, 700, 500);
primaryStage.setTitle("Tree View");
primaryStage.setScene(scene);
primaryStage.show();
}
TreeItem<String> addNewTreeItem(String name){
TreeItem TreeItem = new TreeItem(name);
return TreeItem;
}
private static class AddMenuTreeCell extends TextFieldTreeCell<String> {
private ContextMenu menu = new ContextMenu();
private TextField textField;
public AddMenuTreeCell() {
MenuItem newitem1 = new MenuItem("Insert Roots");
MenuItem newitem2 = new MenuItem("Insert Coordinates");
menu.getItems().addAll(newitem1,newitem2);
newitem1.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
TreeItem<String> item3 = new TreeItem<String>("Roots");
// item3.getChildren().clear();
getTreeItem().getChildren().add(item3);
}
});
newitem2.setOnAction(new EventHandler<ActionEvent>() {
#SuppressWarnings("unchecked")
#Override
public void handle(ActionEvent arg0) {
TreeItem<String> newLeaf = new TreeItem<String>("Coordinates");
TreeItem<String> uxItem1 = new TreeItem("X");
map.put(uxItem1, getrightPane1());
TreeItem<String> uyItem1 = new TreeItem("y");
map.put(uyItem1, getrightPane1());
newLeaf.getChildren().addAll(uxItem1,uyItem1);
getTreeItem().getChildren().add(newLeaf);
}
});
}
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(item);
}
setText(null);
setGraphic(textField);
} else {
setText(item);
setGraphic(getTreeItem().getGraphic());
if (!(getTreeItem().isLeaf() && getTreeItem().getParent() == null)){
setContextMenu(menu);
}
}
}
}
}
private static BorderPane getrightPane1() {
TextField textf1 = new TextField();
TextField textf2 = new TextField();
BorderPane root1 = new BorderPane();
VBox vbox = new VBox(20);
vbox.setPadding(new Insets(10));
HBox h1 = new HBox(7);
HBox h2 = new HBox(7);
textf1.setPrefWidth(100);
textf1.setPromptText("Enter Height");
textf1.setOnKeyReleased(new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent event)
{
if(textf1.getText().length() > 0 && textf2.getText().length() > 0)
{
Rectangle rect1 = new Rectangle();
rect1.setHeight(Double.parseDouble(textf1.getText()));
rect1.setWidth(Double.parseDouble(textf2.getText()));
rect1.setFill(null);
rect1.setStroke(Color.RED);
root1.setCenter(rect1);
}
}
});
textf2.setPrefWidth(100);
textf2.setPromptText("Enter Width");
textf2.setOnKeyReleased(new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent event)
{
if(textf1.getText().length() > 0 && textf2.getText().length() > 0)
{
Rectangle rect2 = new Rectangle();
rect2.setHeight(Double.parseDouble(textf1.getText()));
rect2.setWidth(Double.parseDouble(textf2.getText()));
rect2.setFill(null);
rect2.setStroke(Color.RED);
root1.setCenter(rect2);
}
}
});
if(textf1.getText().length() > 0 && textf2.getText().length() > 0 && root1.getCenter() == null)
{
Rectangle rect = new Rectangle();
rect.setHeight(Double.parseDouble(textf1.getText()));
rect.setWidth(Double.parseDouble(textf2.getText()));
rect.setFill(null);
rect.setStroke(Color.RED);
root1.setCenter(rect);
}
h1.getChildren().addAll(new Label("Y1:"), textf1);
h2.getChildren().addAll(new Label("X1:"), textf2);
vbox.getChildren().addAll(h1, h2);
root1.setLeft(vbox);
return root1;
}
private static BorderPane getRootsPanel() {
BorderPane root2 = new BorderPane();
HBox hbox = new HBox(10);
hbox.setPadding(new Insets(40));
hbox.setAlignment(Pos.TOP_CENTER);
List<BorderPane> listBordePane = new ArrayList(map.values());
for(BorderPane element : listBordePane)
{
Node node = element.getCenter();
if(node instanceof Rectangle)
{
Rectangle rect1 = ((Rectangle)node);
Rectangle rect2 = new Rectangle();
rect2.setWidth(rect1.getWidth());
rect2.setHeight(rect1.getHeight());
rect2.setFill(rect1.getFill());
rect2.setStroke(rect1.getStroke());
Platform.runLater(()->{hbox.getChildren().add(rect2);});
}
}
Platform.runLater(()->{root2.setLeft(hbox);});
return root2;
}
}
Note: if use clear() to clean every root, it would cause issue for this problem,
" let suppose user has main root in which there are 2 sub roots with 1 coordinate each. so each sub root show 2 rectangles in horizontal order and Main root will have 4 rectangles in horizontal order".
Any idea will be helpful please. Thank you

Adding tree Branches and leafs in TreeView

i am working on treeView program in which, user need to add branches and leafs here is my example
public class Main extends Application
{
private BorderPane border;
#Override
public void start(Stage primaryStage)
{
border = new BorderPane();
Scene scene = new Scene(border,200,200);
primaryStage.setTitle("BorderPane");
primaryStage.setScene(scene);
primaryStage.show();
TreeItem<String> tree = new TreeItem<String>("Root");
TreeItem<String> item1 = new TreeItem<String>("Branch");
item1.getChildren().add(new TreeItem<String>("Leaf"));
item1.setExpanded(true);
tree.setExpanded(true);
tree.getChildren().addAll(item1);
TreeView<String> treeView = new TreeView<String>(tree);
treeView.setEditable(true);
treeView.setCellFactory(new Callback<TreeView<String>,TreeCell<String>>(){
#Override
public TreeCell<String> call(TreeView<String> arg0) {
return new AddMenuTreeCell();
}
});
VBox vbox =new VBox(2);
vbox.setPadding(new Insets(5));
VBox.setVgrow(treeView, Priority.ALWAYS);
vbox.getChildren().addAll(treeView);
border.setLeft(vbox);
}
private static class AddMenuTreeCell extends TextFieldTreeCell<String> {
private ContextMenu menu = new ContextMenu();
private TextField textField;
public AddMenuTreeCell() {
MenuItem addItem1 = new MenuItem("Insert Branch");
MenuItem addItem2 = new MenuItem("Insert Leaf");
menu.getItems().addAll(addItem1,addItem2);
addItem1.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
TreeItem<String> newBranch =
new TreeItem<String>("Brunch");
getTreeItem().getChildren().add(newBranch);
}
});
addItem2.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
TreeItem<String> newLeaf =
new TreeItem<String>("leaf");
getTreeItem().getChildren().add(newLeaf);
}
});
}
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty && getTreeItem().getParent() == null){
setContextMenu(menu);
}
}
}
}
With this user can add Branch and Leaf.
But the question is, if user add a Branch it should be like "Branch1" next added branch should be "Branch2", "Branch3",...... same for leafs added in any branch have their numbers.
So that later on user can assign different task to different branches and leafs. Please
Thank you

Show Colorpicker from Contextmenu

I want to show Colorpicker from Context Menu:
ColorPicker colorssPicker = new ColorPicker();
final MenuItem resizeItem = new MenuItem("Option 1");
resizeItem.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
}
});
final MenuItem resizesItem = new MenuItem();
resizesItem.setGraphic(colorssPicker);
resizesItem.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
}
});
final ContextMenu menu = new ContextMenu();
menu.getItems().addAll(resizeItem, resizesItem);
sc.setOnMouseClicked(new EventHandler<MouseEvent>()
{
#Override
public void handle(MouseEvent event)
{
if (MouseButton.SECONDARY.equals(event.getButton()))
{
menu.show(primaryStage, event.getScreenX(), event.getScreenY());
}
}
});
This code is not working, I can't see Colorpicker when I click on the Contextmenu "Choose Color". What is the proper way to implement this?
I get this result:
This snippet will let you show a ColorPicker control embedded into a ContextMenu.
You can style it so it doesn't look like a button, by setting its backgound color.
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
final ColorPicker colorssPicker = new ColorPicker();
colorssPicker.setStyle("-fx-background-color: white;");
final MenuItem otherItem = new MenuItem(null, new Label("Other item"));
final MenuItem resizeItem = new MenuItem(null,colorssPicker);
resizeItem.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event)
{
root.setBackground(new Background(new BackgroundFill(colorssPicker.getValue(),null,null)));
}
});
final ContextMenu menu = new ContextMenu(otherItem,resizeItem);
Scene scene = new Scene(root, 300, 250);
scene.setOnMouseClicked(new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent event){
if (MouseButton.SECONDARY.equals(event.getButton())){
menu.show(primaryStage, event.getScreenX(), event.getScreenY());
}
}
});
primaryStage.setScene(scene);
primaryStage.show();
}

Remove node from TreeView

I want to create this simple example of javaFX TreeView with context menu which can remove nodes from the tree:
public class TreeViewSample extends Application {
private final Node rootIcon = new ImageView(
new Image(getClass().getResourceAsStream("folder_16.png"))
);
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Tree View Sample");
TreeItem<String> rootItem = new TreeItem<String> ("Inbox", rootIcon);
rootItem.setExpanded(true);
for (int i = 1; i < 6; i++) {
TreeItem<String> item = new TreeItem<String> ("Message" + i);
rootItem.getChildren().add(item);
}
TreeView<String> tree = new TreeView<String> (rootItem);
StackPane root = new StackPane();
root.getChildren().add(tree);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
}
I tested this context menu to remove right click selected node:
final ContextMenu contextMenu = new ContextMenu();
MenuItem item1 = new MenuItem("About");
item1.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent e)
{
System.out.println("About");
}
});
MenuItem item2 = new MenuItem("Preferences");
item2.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent e)
{
System.out.println("Preferences");
}
});
MenuItem item3 = new MenuItem("Remove");
item3.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent e)
{
DynamicTreeNodeModel c = treeView.getSelectionModel().getSelectedItem().getValue();
boolean remove = treeView.getSelectionModel().getSelectedItem().getChildren().remove(c);
System.out.println("Remove");
}
});
contextMenu.getItems().addAll(item1, item2, item3);
treeView.setContextMenu(contextMenu);
For some reason the code is not working. Can you help me to fix this issue?
You're trying to remove the selected node from it's own children. Since it doesn't exist there, nothing happens. You need to remove the selected node from it's parent's children.
MenuItem item3 = new MenuItem("Remove");
item3.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
TreeItem c = (TreeItem)treeView.getSelectionModel().getSelectedItem();
boolean remove = c.getParent().getChildren().remove(c);
System.out.println("Remove");
}
});

Resources