A treeview in which user can add as many root and coordinates as he want. Coordinates generate
rectangles, which are shown horizontally on root node, here is code
import javafx.scene.Node;
abstract class MyNode {
private final String label;
private Node rectangle;
MyNode(String label) {
this.label = label;
}
String getLabel() {
return label;
}
Node getRectangle() {
return rectangle;
}
void setRectangle(Node rectangle) {
this.rectangle = rectangle;
}
}
class MyRootNode extends MyNode {
MyRootNode(String label) {
super(label);
}
}
class MyCoordinateNode extends MyNode {
MyCoordinateNode(String label) {
super(label);
}
}
and the Main class is
public class Main extends Application {
private static int rootNr = 0;
private static int coordinateNr = 0;
public static void main(String[] args) {
launch(args);
}
private static final Map<TreeItem<MyNode>, BorderPane> map = new HashMap<>();
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
TreeItem<MyNode> mainTree = new TreeItem<>(new MyRootNode("Main System"));
mainTree.setExpanded(true);
TreeView<MyNode> treeView = new TreeView<>(mainTree);
treeView.setCellFactory(p -> new AddMenuTreeCell());
treeView.setOnMouseClicked((event) -> {
final TreeItem<MyNode> treeItem = treeView.getSelectionModel().getSelectedItem();
if (treeItem.getValue() instanceof MyRootNode) {
root.setCenter(getRootsPanel(treeItem));
} else {
root.setCenter(map.get(treeItem));
}
});
root.setLeft(treeView);
Scene scene = new Scene(root, 700, 700);
primaryStage.setTitle("Tree View");
primaryStage.setScene(scene);
primaryStage.show();
}
private static class AddMenuTreeCell extends TextFieldTreeCell<MyNode> {
private ContextMenu menu = new ContextMenu();
AddMenuTreeCell() {
MenuItem newitem1 = new MenuItem("Insert Root");
MenuItem newitem2 = new MenuItem("Insert Coordinates");
menu.getItems().addAll(newitem1, newitem2);
newitem1.setOnAction(arg0 -> {
TreeItem<MyNode> item = new TreeItem<>(new MyRootNode("Root" + rootNr++));
getTreeItem().getChildren().add(item);
});
newitem2.setOnAction(arg0 -> {
TreeItem<MyNode> uxItem1 = new TreeItem<>(new MyCoordinateNode("X"));
map.put(uxItem1, getRightPane(uxItem1));
TreeItem<MyNode> uyItem1 = new TreeItem<>(new MyCoordinateNode("Y"));
map.put(uyItem1, getRightPane(uyItem1));
TreeItem<MyNode> newLeaf = new TreeItem<>(new MyRootNode("Coordinates" + coordinateNr++));
newLeaf.getChildren().add(uxItem1);
newLeaf.getChildren().add(uyItem1);
getTreeItem().getChildren().add(newLeaf);
});
}
#Override
public void updateItem(MyNode item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (!isEditing()) {
setText(item.getLabel());
setGraphic(getTreeItem().getGraphic());
if (item instanceof MyRootNode) {
setContextMenu(menu);
}
}
}
}
}
private static BorderPane getRightPane(final TreeItem<MyNode> curTreeItem) {
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(event -> {
if (textf1.getText().length() > 0 && textf2.getText().length() > 0) {
Rectangle rect = getRectangle(textf1, textf2, Color.BLUE);
root1.setCenter(rect);
curTreeItem.getValue().setRectangle(rect);
}
});
textf2.setPrefWidth(100);
textf2.setPromptText("Enter Width");
textf2.setOnKeyReleased(event -> {
if (textf1.getText().length() > 0 && textf2.getText().length() > 0) {
Rectangle rect = getRectangle(textf1, textf2, Color.RED);
root1.setCenter(rect);
curTreeItem.getValue().setRectangle(rect);
}
});
h1.getChildren().addAll(new Label("Y:"), textf1);
h2.getChildren().addAll(new Label("X:"), textf2);
vbox.getChildren().addAll(h1, h2);
root1.setLeft(vbox);
return root1;
}
private static Rectangle getRectangle(TextField textf1, TextField textf2, final Color blue) {
Rectangle rect = new Rectangle();
rect.setHeight(Double.parseDouble(textf1.getText()));
rect.setWidth(Double.parseDouble(textf2.getText()));
rect.setFill(null);
rect.setStroke(blue);
return rect;
}
private static BorderPane getRootsPanel(final TreeItem<MyNode> treeItem) {
BorderPane root = new BorderPane();
CheckBox box1 = new CheckBox("Change order");
CheckBox box2 = new CheckBox("Change View");
VBox vbox = new VBox(30, box1,box2);
HBox hbox = new HBox(10);
hbox.setPadding(new Insets(40));
hbox.setAlignment(Pos.TOP_CENTER);
final List<MyNode> coordinateNodes = getCoordinateNodes(treeItem);
for (final MyNode coordinateNode : coordinateNodes) {
if (coordinateNode.getRectangle() != null) {
Platform.runLater(() -> hbox.getChildren().addAll(coordinateNode.getRectangle()));
}
}
Platform.runLater(() -> root.setLeft(hbox));
return root;
}
private static List<MyNode> getCoordinateNodes(final TreeItem<MyNode> treeItem) {
final List<MyNode> result = new ArrayList<>();
if (treeItem.getValue() instanceof MyRootNode) {
for (final TreeItem<MyNode> child : treeItem.getChildren()) {
result.addAll(getCoordinateNodes(child));
}
} else {
result.add(treeItem.getValue());
}
return result;
}
}
My Question is, How to bind all newly generated rectangles which are shown in root with these two check-boxes that if first checkbox is selected then order of rectangle should be changed like(1,2,3 to 3,2,1), with second checkbox rectangles are moved from horizontal to vertical view and if both checked then both features are applied.
due to the fact that user can add rectangle as many as he want, it is difficult for me to bind all of them.
i tried by putting bounty on the question but still didn't get any response. Please i am desperately searching help on this problem . Please
i will be very Thankfull.
Related
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle(" ");
RadioButton rbRed = new RadioButton("Red");
RadioButton rbGreen = new RadioButton("Green");
ToggleGroup group = new ToggleGroup();
rbRed.setToggleGroup(group);
rbGreen.setToggleGroup(group);
HBox hbox = new HBox(rbRed, rbGreen);
hbox.setAlignment(Pos.CENTER);
rbRed.setOnAction(e -> {
if (rbRed.isSelected()) {
hbox.setBackground(Color.RED);
}
});
rbGreen.setOnAction(e -> {
if (rbGreen.isSelected()) {
hbox.setBackground(Color.GREEN);
}
});
Scene scene = new Scene(hbox, 400, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
this is my code. when clicked on the radio button, it should change the background color.
You need a background not just a color like so
public class Main extends Application {
#Override
public void start(Stage stage) {
stage.setTitle(" ");
RadioButton rbRed = new RadioButton("Red");
RadioButton rbGreen = new RadioButton("Green");
ToggleGroup group = new ToggleGroup();
rbRed.setToggleGroup(group);
rbGreen.setToggleGroup(group);
HBox hbox = new HBox(rbRed, rbGreen);
hbox.setAlignment(Pos.CENTER);
rbRed.setOnAction(e -> {
if (rbRed.isSelected()) {
hbox.setBackground(buildBackground(Color.RED));
}
});
rbGreen.setOnAction(e -> {
if (rbGreen.isSelected()) {
hbox.setBackground(buildBackground(Color.GREEN));
}
});
Scene scene = new Scene(hbox, 400, 100);
stage.setScene(scene);
stage.show();
}
private Background buildBackground(Color color){
return new Background(new BackgroundFill(color,new CornerRadii(0),new Insets(0)));
}
public static void main(String[] args) { launch(args); }
}
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
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);
}
}
i am working on an application. example code is given below
public class Main extends Application
{
private BorderPane border;
#Override
public void start(Stage primaryStage)
{
//Displaying all the functions in Scene
border = new BorderPane();
Scene scene = new Scene(border,750,500);
primaryStage.setTitle("BorderPane");
primaryStage.setScene(scene);
primaryStage.show();
//Fall-Tree Root Item
TreeItem<String> tree = new TreeItem<String>("Library");
TreeItem<String> item1 = new TreeItem<String>("Module");
TreeItem<String> item1Child = new TreeItem<String>("MX");
item1.getChildren().add(item1Child);
TreeItem<String> item2 = new TreeItem<String>("Unite");
TreeItem<String> item2Child1 = new TreeItem<String>("UX");
TreeItem<String> item2Child2 = new TreeItem<String>("UY");
item2.getChildren().addAll(item2Child1,item2Child2);
item2.setExpanded(true);
TreeItem<String> item3 = new TreeItem<String>("Translate");
TreeItem<String> item3Child = new TreeItem<String>("TX");
item3.getChildren().add(item3Child);
TreeItem<String> item4 = new TreeItem<String>("Rotate");
TreeItem<String> item4Child = new TreeItem<String>("Rx");
item4.getChildren().add(item4Child);
tree.setExpanded(true);
tree.getChildren().addAll(item1,item2,item3,item4);
TreeView<String> treeView = new TreeView<String>(tree);
//Making Tree Editable
treeView.setEditable(true);
treeView.setCellFactory(TextFieldTreeCell.forTreeView());
//Assigning Leaf an Explorer View
VBox box1 = new VBox();
treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>() {
#Override
public void changed(ObservableValue<?> observable, Object oldValue, Object newValue) {
if (newValue == item2Child1) {
box1.getChildren().add(getrightPane1());
} else {
int i = box1.getChildren().size();
if (i > 0) {
box1.getChildren().remove(0);
}
}
}
});
// Main Branch
VBox box2 = new VBox();
treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>() {
#Override
public void changed(ObservableValue<?> observable, Object oldValue, Object newValue) {
if (newValue == item2) {
box2.getChildren().add(getrightPane2());
} else {
int i = box2.getChildren().size();
if (i > 0) {
box2.getChildren().remove(0);
}
}
}
});
//Displaying all the Functions into border's center
VBox vbox =new VBox(2);
vbox.setPadding(new Insets(5));
VBox.setVgrow(treeView, Priority.ALWAYS);
vbox.getChildren().addAll(new Text("Fall Tree"),treeView);
HBox hb = new HBox();
hb.getChildren().addAll(vbox,box1,box2);
border.setCenter(hb);
}
//Method for 1st Leaf Explorer View
private BorderPane getrightPane1() {
BorderPane root = new BorderPane();
VBox vbox = new VBox(20);
vbox.setPadding(new Insets(10));
HBox h1 = new HBox(7);
HBox h2 = new HBox(7);
TextField textf1 = new TextField();
TextField textf2 = new TextField();
textf1.setPrefWidth(100);
textf1.setPromptText("Enter Height");
//Generating Rectangle's Height by providing Values in Output
textf1.setOnKeyReleased(new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent event)
{
if(textf1.getText().length() > 0 && textf2.getText().length() > 0)
{
Rectangle rect = new Rectangle();
rect.setHeight(Double.parseDouble(textf1.getText()));
rect.setWidth(Double.parseDouble(textf2.getText()));
rect.setFill(null);
rect.setStroke(Color.RED);
root.setBottom(rect);
}
}
});
textf2.setPrefWidth(100);
textf2.setPromptText("Enter Width");
//Generating Rectangle's Width by providing Values in Output
textf2.setOnKeyReleased(new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent event)
{
if(textf1.getText().length() > 0 && textf2.getText().length() > 0)
{
Rectangle rect = new Rectangle();
rect.setHeight(Double.parseDouble(textf1.getText()));
rect.setWidth(Double.parseDouble(textf2.getText()));
rect.setFill(null);
rect.setStroke(Color.RED);
root.setBottom(rect);
}
}
});
//Labels for TextFields
h1.getChildren().addAll(new Label("Y:"), textf1);
h2.getChildren().addAll(new Label("X:"), textf2);
vbox.getChildren().addAll(h1, h2);
root.setLeft(vbox);
return root;
}
//Method for Branch Explorer View
private HBox getrightPane2() {
HBox hbox = new HBox(20);
hbox.setAlignment(Pos.CENTER);
hbox.getChildren().addAll(getrightPane1());
return hbox;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
}
This is how example code works
"If user put values in field provided in "UX" the rectangle is generated in UX.
But this rectangle vanish when user clicks onto any other branch."
The application should work like this
"If user put values into field in UX, Create Rectangle in UX and in Unite Branch."
Please have a look at method getrightPane2, due to getting all children of getrightPane1, fields are shown in Unite and with that user can create rectangle but that is not right. Only Rectangle created in UX should be shown in Unite nothing else. Please any hint would be fine.
Thank you
Try this code
public class Main extends Application{
private BorderPane border;
#Override
public void start(Stage primaryStage) {
// Displaying all the functions in Scene
border = new BorderPane();
Scene scene = new Scene(border, 750, 500);
primaryStage.setTitle("BorderPane");
primaryStage.setScene(scene);
primaryStage.show();
// Fall-Tree Root Item
TreeItem<String> tree = new TreeItem<String>("Library");
TreeItem<String> item1 = new TreeItem<String>("Module");
TreeItem<String> item1Child = new TreeItem<String>("MX");
item1.getChildren().add(item1Child);
TreeItem<String> item2 = new TreeItem<String>("Unite");
TreeItem<String> item2Child1 = new TreeItem<String>("UX");
System.out.println();
TreeItem<String> item2Child2 = new TreeItem<String>("UY");
item2.getChildren().addAll(item2Child1, item2Child2);
item2.setExpanded(true);
TreeItem<String> item3 = new TreeItem<String>("Translate");
TreeItem<String> item3Child = new TreeItem<String>("TX");
item3.getChildren().add(item3Child);
TreeItem<String> item4 = new TreeItem<String>("Rotate");
TreeItem<String> item4Child = new TreeItem<String>("Rx");
item4.getChildren().add(item4Child);
tree.setExpanded(true);
tree.getChildren().addAll(item1, item2, item3, item4);
TreeView<String> treeView = new TreeView<String>(tree);
// Making Tree Editable
treeView.setEditable(true);
treeView.setCellFactory(TextFieldTreeCell.forTreeView());
// Assigning Leaf an Explorer View
VBox box1 = new VBox();
treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem>() {
#Override
public void changed(ObservableValue<? extends TreeItem> observable, TreeItem oldValue, TreeItem newValue) {
if (newValue.getValue().equals(item2Child1.getValue())) {
box1.getChildren().add(getrightPane1());
} else {
int i = box1.getChildren().size();
if (i > 0) {
box1.getChildren().remove(0);
}
}
}
});
// Main Branch
VBox box2 = new VBox();
treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem>() {
#Override
public void changed(ObservableValue<? extends TreeItem> observable, TreeItem oldValue, TreeItem newValue) {
if (newValue.getValue().equals(item2.getValue())) {
box2.getChildren().add(getrightPane2());
} else {
int i = box2.getChildren().size();
if (i > 0) {
box2.getChildren().remove(0);
}
}
}
});
// Displaying all the Functions into border's center
VBox vbox = new VBox(2);
vbox.setPadding(new Insets(5));
VBox.setVgrow(treeView, Priority.ALWAYS);
vbox.getChildren().addAll(new Text("Fall Tree"), treeView);
HBox hb = new HBox();
hb.getChildren().addAll(vbox, box1, box2);
border.setCenter(hb);
}
TextField textf1 = new TextField();
TextField textf2 = new TextField();
BorderPane root = new BorderPane();
// Method for 1st Leaf Explorer View
private BorderPane getrightPane1() {
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");
// Generating Rectangle's Height by providing Values in Output
textf1.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if (textf1.getText().length() > 0 && textf2.getText().length() > 0) {
Rectangle rect = new Rectangle();
rect.setHeight(Double.parseDouble(textf1.getText()));
rect.setWidth(Double.parseDouble(textf2.getText()));
rect.setFill(null);
rect.setStroke(Color.RED);
root.setBottom(rect);
}
}
});
textf2.setPrefWidth(100);
textf2.setPromptText("Enter Width");
// Generating Rectangle's Width by providing Values in Output
textf2.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if (textf1.getText().length() > 0 && textf2.getText().length() > 0) {
Rectangle rect = new Rectangle();
rect.setHeight(Double.parseDouble(textf1.getText()));
rect.setWidth(Double.parseDouble(textf2.getText()));
rect.setFill(null);
rect.setStroke(Color.RED);
root.setBottom(rect);
}
}
});
// Labels for TextFields
h1.getChildren().addAll(new Label("Y:"), textf1);
h2.getChildren().addAll(new Label("X:"), textf2);
vbox.getChildren().addAll(h1, h2);
root.setLeft(vbox);
return root;
}
// Method for Branch Explorer View
private HBox getrightPane2() {
HBox hbox = new HBox(20);
hbox.setAlignment(Pos.CENTER);
hbox.setPadding(new Insets(20));
System.out.println(textf1.getText());
if (!textf1.getText().equals("") && !textf2.getText().equals("")) {
Rectangle rectangle = new Rectangle();
rectangle.setHeight(Double.parseDouble(textf1.getText()));
rectangle.setWidth(Double.parseDouble(textf2.getText()));
rectangle.setFill(null);
rectangle.setStroke(Color.RED);
hbox.getChildren().addAll(rectangle);
} else {
Alert alert = new Alert(AlertType.INFORMATION, "First fill the UX Field");
alert.show();
}
return hbox;
}
/**
* #param args
* the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
I have implemented drag'n'drop functionality very similar to How to drag and drop tab nodes between tab panes, which works fine so far, but i also add a new Stage (SideStage below) if the tab is dragged outside of the main-window/stage. The problem is, the Tab is only showing after i either drag a new Tab to the TabPane there or if i resize the window. The main part of that drag'n'drop action is happening in the GuiPartFactory in the EventHandler which get's assigned to the Label of the Tab that gets dragged. I tried all sorts of size assigning, requestLayout, etc.
Sidestage class:
private TabPane tabPane;
public SideStage(double xPos, double yPos) {
tabPane = initTabArea();
VBox root = new VBox(0,GuiPartFactory.initMenuAndTitle(this),tabPane);
Scene scene = new Scene(root, 800, 600);
setScene(scene);
scene.setOnDragExited(new DnDExitAndEntryHandler());
scene.setOnDragEntered(new DnDExitAndEntryHandler());
setX(xPos);
setY(yPos);
;
initCloseWindowHandler();
}
private void initCloseWindowHandler() {
setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent event) {
System.out.println("closing this sidestage");
MainApp.sideStages.remove(SideStage.this);
}
});
}
private TabPane initTabArea() {
final TabPane tabPane = GuiPartFactory.createTabPane();
tabPane.addEventHandler(Tab.TAB_CLOSE_REQUEST_EVENT, new EventHandler<Event>() {
#Override
public void handle(Event event) {
System.out.println("tab got closed mon!");
if (tabPane.getTabs().isEmpty()) {
SideStage.this.close();
}
}
});
VBox.setVgrow(tabPane, Priority.ALWAYS);
return tabPane;
}
public void addTab(Tab tab) {
tabPane.getTabs().add(tab);
}
And the GuiPartFactory class:
public static ResourceBundle BUNDLE = ResourceBundle.getBundle("locales/Bundle", new Locale("en", "GB"));
public static TabPane createTabPane() {
final TabPane tabPane = new TabPane();
//This event gets fired when the cursor is holding a draggable object over this tabpane
tabPane.setOnDragOver(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent event) {
final Dragboard dragboard = event.getDragboard();
if (dragboard.hasString() && dragboard.getString().equals("tab") && ((Tab) MainApp.dndTemp).getTabPane() != tabPane) {
event.acceptTransferModes(TransferMode.MOVE);
event.consume();
}
}
});
//This event gets fired when the cursor is releasing a draggable object over this tabpane (this gets only called if it has been accepted in the previos dragover event!)
tabPane.setOnDragDropped(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent event) {
System.out.println("dropped");
Tab tab = (Tab) MainApp.dndTemp;
MainApp.dndHandled = true;
tab.getTabPane().getTabs().remove(tab);
tabPane.getTabs().add(tab);
tabPane.getSelectionModel().select(tab);
event.setDropCompleted(true);
event.consume();
}
});
return tabPane;
}
public static Tab createTab(String text) {
final Tab tab = new Tab();
final Label label = new Label("Tab" + text);
tab.setGraphic(label);
StackPane pane = new StackPane();
//need to set a real size here
pane.setPrefSize(500, 500);
tab.setContent(pane);
tab.getContent().setOnDragOver(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent event) {
final Dragboard dragboard = event.getDragboard();
if (dragboard.hasString() && dragboard.getString().equals("tab") && ((Tab) MainApp.dndTemp).getTabPane() != tab.getTabPane()) {
event.acceptTransferModes(TransferMode.MOVE);
event.consume();
}
}
});
tab.getContent().setOnDragDropped(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent event) {
System.out.println("dropped");
Tab transferTab = (Tab) MainApp.dndTemp;
MainApp.dndHandled = true;
transferTab.getTabPane().getTabs().remove(transferTab);
tab.getTabPane().getTabs().add(transferTab);
tab.getTabPane().getSelectionModel().select(transferTab);
event.setDropCompleted(true);
event.consume();
}
});
label.setOnDragDetected(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
Dragboard dragboard = label.startDragAndDrop(TransferMode.MOVE);
ClipboardContent clipboardContent = new ClipboardContent();
clipboardContent.putString("tab");
MainApp.dndTemp = tab;
MainApp.dndHandled = false;
dragboard.setContent(clipboardContent);
dragboard.setDragView(new Image("img/dragcursor.png"));
event.consume();
}
});
label.setOnDragDone(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent event) {
//our dragndrop failed
if (!MainApp.dndHandled) {
//lets see if it failed because we dropped outside of our java-windows
if (!MainApp.dndInside) {
if (!MainApp.dndTemp.equals(tab)) {
System.out.println("something is wrong here");
}
System.out.println("gotta make a new window!");
SideStage sideStage = new SideStage(event.getScreenX(), event.getScreenY());
MainApp.sideStages.add(sideStage);
//just a check to make sure we don't access a null variable
if (tab.getTabPane() != null) {
tab.getTabPane().getTabs().remove(tab);
}
sideStage.addTab(tab);
sideStage.sizeToScene();
tab.getTabPane().getSelectionModel().select(tab);
System.out.println("width: " + ((StackPane) tab.getContent()).getWidth());
System.out.println("height: " + ((StackPane) tab.getContent()).getHeight());
System.out.println("width: " + tab.getTabPane().getWidth());
System.out.println("height: " + tab.getTabPane().getHeight());
sideStage.show();
}
}
}
});
return tab;
}
public static Tab createTabRandomColor(String text) {
Random rng = new Random();
Tab tab = GuiPartFactory.createTab(text);
StackPane pane = (StackPane) tab.getContent();
int red = rng.nextInt(256);
int green = rng.nextInt(256);
int blue = rng.nextInt(256);
String style = String.format("-fx-background-color: rgb(%d, %d, %d);", red, green, blue);
pane.setStyle(style);
Label label = new Label("This is tab " + text);
label.setStyle(String.format("-fx-text-fill: rgb(%d, %d, %d);", 256 - red, 256 - green, 256 - blue));
pane.getChildren().add(label);
return tab;
}
public static MenuBar initMenuAndTitle(Stage stage) {
//setting up a window title
stage.setTitle(BUNDLE.getString("title.name"));
//adding the menubar
MenuBar menuBar = new MenuBar();
//adding the base menu entry
Menu menuStart = new Menu(BUNDLE.getString("menu.start"));
Menu menuView = new Menu(BUNDLE.getString("menu.view"));
Menu menuHelp = new Menu(BUNDLE.getString("menu.help"));
menuBar.getMenus().addAll(menuStart, menuView, menuHelp);
//adding the menuitems inside the menus
MenuItem aboutItem = new MenuItem(BUNDLE.getString("menu.about"));
aboutItem.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Dialogs popup = Dialogs.create();
popup.title(BUNDLE.getString("menu.about.title"));
popup.message(BUNDLE.getString("menu.about.message"));
popup.showInformation();
}
});
menuHelp.getItems().add(aboutItem);
MenuItem exitItem = new MenuItem(BUNDLE.getString("menu.exit"));
exitItem.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Dialogs popup = Dialogs.create();
popup.title(BUNDLE.getString("menu.exit.title"));
popup.message(BUNDLE.getString("menu.exit.message"));
popup.actions(new Action[]{YES, NO});
Action response = popup.showConfirm();
if(response.equals(YES)) {
System.exit(0);
}
}
});
menuStart.getItems().add(exitItem);
return menuBar;
}
And finally the MainApp class:
//for handling tag drag'n'drop outside of java windows
public static Object dndTemp = null;
public static boolean dndHandled = true;
public static boolean dndInside = true;
public static Set<SideStage> sideStages = new HashSet<>();
//holding the tabs (doe)
private TabPane tabPane;
#Override
public void start(Stage stage) {
tabPane = initTabs();
VBox root = new VBox(0, GuiPartFactory.initMenuAndTitle(stage), tabPane);
Scene scene = new Scene(root, 800, 600);
stage.setScene(scene);
stage.show();
scene.setOnDragExited(new DnDExitAndEntryHandler());
scene.setOnDragEntered(new DnDExitAndEntryHandler());
}
private TabPane initTabs() {
TabPane tabPane = GuiPartFactory.createTabPane();
Tab bedraggin = GuiPartFactory.createTab("be draggin");
Tab beraggin = GuiPartFactory.createTab("be raggin");
tabPane.getTabs().add(bedraggin);
tabPane.getTabs().add(beraggin);
for (int i = 0; i < 3; i++) {
Tab tab = GuiPartFactory.createTabRandomColor("" + i);
tabPane.getTabs().add(tab);
}
VBox.setVgrow(tabPane, Priority.ALWAYS);
return tabPane;
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be
* launched through deployment artifacts, e.g., in IDEs with limited FX
* support. NetBeans ignores main().
*
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public boolean removeSideStage(SideStage sideStage) {
return sideStages.remove(sideStage);
}
public void addTab(Tab tab) {
tabPane.getTabs().add(tab);
}
public void removeTab(Tab tab) {
tabPane.getTabs().remove(tab);
}
edit: A temporary workaround is to put the actual adding of the tab into the new TabPane into a runnable. But i think this is a rather bad solution:
Platform.runLater(new Runnable() {
#Override
public void run() {
sideStage.addTab(tab);
tab.getTabPane().getSelectionModel().select(tab);
}
});