Adding tree Branches and leafs in TreeView - javafx

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

Related

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 multiple tree Branches and leafs in 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);
}
}

how to close other tabs except the selected tab

I want to implement TabPane with ContextMenu to close other tabs except the selected tab
public class MainApp extends Application
{
#Override
public void start(Stage primaryStage)
{
primaryStage.setTitle("Tabs");
Group root = new Group();
Scene scene = new Scene(root, 400, 250, Color.WHITE);
final TabPane tabPane = new TabPane();
BorderPane borderPane = new BorderPane();
for (int i = 0; i < 5; i++)
{
Tab tab = new Tab();
tab.setText("Tab" + i);
HBox hbox = new HBox();
hbox.getChildren().add(new Label("Tab" + i));
hbox.setAlignment(Pos.CENTER);
tab.setContent(hbox);
tabPane.getTabs().add(tab);
ContextMenu contextMenu = new ContextMenu();
MenuItem close = new MenuItem();
MenuItem closeOthers = new MenuItem();
MenuItem closeAll = new MenuItem();
close.setText("Close");
closeOthers.setText("Close Others");
closeAll.setText("Close All");
contextMenu.getItems().addAll(close, closeOthers, closeAll);
tab.setContextMenu(contextMenu);
final ObservableList<Tab> tablist = tabPane.getTabs();
close.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
}
});
closeOthers.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
tabPane.getTabs().removeAll();
}
});
closeAll.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
tabPane.getTabs().removeAll(tablist);
}
});
}
// bind to take available space
borderPane.prefHeightProperty().bind(scene.heightProperty());
borderPane.prefWidthProperty().bind(scene.widthProperty());
borderPane.setCenter(tabPane);
root.getChildren().add(borderPane);
primaryStage.setScene(scene);
primaryStage.show();
}
}
But the code is not working. Can you help me to implement this solution.
Is there any better approach to implement this?
This is pretty simple. Just iterate through all Tab-Objects in the tablist and mark the ones which should be deleted. After the iteration remove the marked Tab-Objects.
closeOthers.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
// ArrayList of Tab-Objects in which we store Tabs which should be deleted..
ArrayList<Tab> markedTabs = new ArrayList<>();
// Iterate through all Tabs in tablist
for (Tab tab : tablist) {
// Is the tab the current active tab? if not, add it to the markedTabs-ArrayList
if (tab != tabPane.getSelectionModel().getSelectedItem())
markedTabs.add(tab);
}
// Remove them from the tabPane..
tabPane.getTabs().removeAll(markedTabs);
}
});

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