how to make window pop up for short time then disappear it without any actionEvent jAVAfX - javafx

hi am using JavaFx i want to create a simple window that will appear at first the application will go start then it will stay for short time then it will disappear automatically without any event then my main window will appear now
can anyone help me in this idea

package x;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class AutoHideExmpl extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
VBox v = new VBox();
TextField fiiled = new TextField("asdasdf");
TextField d = new TextField("asdfasdf");
TextField gd = new TextField("asdf");
TextField da = new TextField("asdf");
TextField cd = new TextField("asdf");
v.getChildren().addAll(fiiled, d, gd, da, cd);
v.setMinSize(500, 500);
Scene c = new Scene(v);
primaryStage.setScene(c);
primaryStage.show();
Stage s1 = new Stage();
VBox v1 = new VBox();
TextField fiiled1 = new TextField("asdasdf");
TextField d1 = new TextField("asdfasdf");
TextField gd1 = new TextField("asdf");
TextField da1 = new TextField("asdf");
TextField cd1 = new TextField("asdf");
v1.getChildren().addAll(fiiled1, d1, gd1, da1, cd1);
v1.setMinSize(300, 300);
Scene c1 = new Scene(v1);
s1.setScene(c1);
s1.show();
Task t = new Task<Void>() {
#Override
protected Void call() throws Exception {
Thread.sleep(60000);
Platform.runLater(() -> {
s1.close();
});
System.out.println("hidding");
return null;
}
};
Thread ts = new Thread(t);
ts.start();
}
}
you can user this too
Thread ts = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(60000);
Platform.runLater(() -> {
s1.close();
});
System.out.println("hidding");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
ts.start();
i hope this will help you if any ? write comment

Related

Detecting button click of button added to javafx listview

I am very new to Java so please be patient with me. I have successfully added buttons, labels and even a progress bar to a listview cell. I need to be able to detect when one of the buttons has been clicked. Adding controls to listview content I managed to get from a couple of posts here the code i am using is shown below
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.ProgressBar;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class ListViewDemo extends Application {
public static class lvCell extends VBox {
Label labelName = new Label();
Label labelPath = new Label();
Label labelElapse = new Label();
Button buttonPlayPause = new Button();
Button buttonStop = new Button();
ImageView ivStop = new ImageView();
ImageView ivPlay = new ImageView();
Pane buttonSpacer = new Pane();
Pane progressBarSpacer = new Pane();
HBox hbDetail = new HBox();
HBox hbProgress = new HBox();
ProgressBar pbProgress = new ProgressBar();
File filePlay;
File fileStop;
double prefWidth = 10;
double prefHeight = 10;
lvCell(String labelText) {
super();
labelName.setText(labelText);
labelName.setMaxWidth(Double.MAX_VALUE);
labelPath.setMaxWidth(0);
labelPath.setText("Path");
pbProgress.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(labelName, Priority.ALWAYS);
HBox.setHgrow(pbProgress, Priority.ALWAYS);
HBox.setMargin(labelName, new Insets(5, 0, 0, 0));
HBox.setMargin(pbProgress, new Insets(0, 0, 0, 0));
labelPath.setVisible(false);
buttonSpacer.setPrefSize(prefWidth, prefHeight);
labelElapse.setPrefSize(50, prefHeight);
labelElapse.setText("Time");;
progressBarSpacer.setPrefSize(prefWidth * 6, prefHeight);
filePlay = new File("src/image/play.png");
fileStop = new File("src/image/stop.png");
Image imagePlay = new Image(filePlay.toURI().toString());
Image imageStop = new Image(fileStop.toURI().toString());
ivPlay.setImage(imagePlay);
ivStop.setImage(imageStop);
ivPlay.setFitHeight(prefHeight);
ivPlay.setFitWidth(prefWidth);
ivStop.setFitHeight(prefHeight);
ivStop.setFitWidth(prefWidth);
buttonPlayPause.setGraphic(ivPlay);
buttonStop.setGraphic(ivStop);
buttonPlayPause.setMaxSize(prefWidth, prefHeight);
buttonStop.setMaxSize(prefWidth, prefHeight);
pbProgress.setMaxHeight(2);
pbProgress.setPrefHeight(2);
hbDetail.getChildren().addAll(buttonPlayPause, buttonStop, buttonSpacer, labelName, labelPath);
hbProgress.getChildren().addAll(progressBarSpacer, pbProgress, labelElapse);
this.getChildren().addAll(hbDetail, hbProgress);
}
}
public Parent createContent() {
BorderPane layout = new BorderPane();
List < lvCell > list = new ArrayList < > ();
for (int i = 0; i < 10; i++) {
list.add(new lvCell("Item " + i));
}
ListView < lvCell > listView = new ListView < lvCell > ();
ObservableList < lvCell > myObservableList = FXCollections.observableList(list);
listView.setItems(myObservableList);
layout.setCenter(listView);
return layout;
}
#Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(createContent()));
stage.setWidth(300);
stage.setHeight(200);
stage.show();
}
public static void main(String args[]) {
launch(args);
}
}
The screen looks like this:
Any help will be greatly appreciated.
Thanks in advance, and wishing you a peaceful journey.
Yas
This is not a class well designed to put into a ListView. An object used as item in a ListView should contain data; the ListCell implementation produced by the cellFactory is responsible for determining the visual representation of the data in the ListView. This way you avoid the creation of nodes for every object reducing the memory footprint, which is exactly what ListView is designed for.
Simplified example
The data here contains just the progress and some text; it's displayed in a ProgressBar and the text of the cell; an additional button in the cell allows increasing the progress by 0.25 for each click and removing any items reaching a progress of 1.
Data class
public class Data {
private final DoubleProperty progress = new SimpleDoubleProperty();
private final String text;
public Data(String text) {
this.text = text;
}
public double getProgress() {
return progress.get();
}
public void setProgress(double value) {
progress.set(value);
}
public String getText() {
return text;
}
public ObservableValue<? extends Number> progressProperty() {
return progress;
}
}
ListView code
ListView<Data> listView = new ListView<>(someData);
listView.setCellFactory(l -> new ListCell<Data>() {
private final ProgressBar progressBar = new ProgressBar();
private final Button button = new Button("increase");
private final HBox content = new HBox(progressBar, button);
{
button.setOnAction(evt -> {
Data item = getItem();
int index = getIndex();
double progress = item.getProgress() + 0.25;
item.setProgress(progress);
if (progress >= 1) {
getListView().getItems().remove(index);
}
});
}
#Override
protected void updateItem(Data item, boolean empty) {
super.updateItem(item, empty);
progressBar.progressProperty().unbind();
if (item == null) {
setGraphic(null);
setText("");
} else {
setGraphic(content);
setText(item.getText());
progressBar.progressProperty().bind(item.progressProperty());
}
}
});

JavaFX : Mouse events for a PopOver Window (ControlsFX)

I am having the following code to display a PopOver (Custom PopUp by ControlsFX - mvn repo)
public class JavaFXApplication35 extends Application {
#Override
public void start(Stage primaryStage) {
try {
Label lblName = new Label("Tetsing name");
Label lblStreet = new Label("Some street name");
Label lblCityStateZip = new Label("Some city, 111111");
VBox vBox = new VBox(lblName, lblStreet, lblCityStateZip);
PopOver popOver = new PopOver(vBox);
Label label = new Label("Mouse mouse over me");
label.setOnMouseEntered(mouseEvent -> {
popOver.show(label, -3);
});
label.setOnMouseExited(mouseEvent -> {
if (popOver.isShowing()) {
popOver.hide();
}
});
StackPane root = new StackPane();
root.getChildren().add(label);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.setOnCloseRequest((WindowEvent event) -> {
System.exit(0);
});
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
The problem is ,
I want the pop-up to be displayed when mouse entered the Label - works fine.
I want the pop-up to be hidden when user exits mouse from Label but not if he enters mouse in to the pop-up window.
I have added MouseEntered and MouseExited actions on Label but how can i handle the another scenario where i don't want to hide the pop-up if user enters mouse in to pop-up.
I ran into the same problem. Here is my solution. Just pass your label (or other node) and PopOver's content node as arguments to this method.
public static void addAutoHidingPopOver(Node hoverableNode, Node contentNode) {
//Creating PopOver
PopOver popOver = new PopOver(hoverableNode);
popOver.setContentNode(contentNode);
//Here you can set custom parameters of your PopOver
//...
//Mouse Actions handling
final Timeline timeline = new Timeline();
timeline.getKeyFrames().add(new KeyFrame(Duration.millis(1000)));
timeline.setOnFinished(finishEvent -> {
if (hoverableNode.isHover() || contentNode.isHover()) timeline.play();
else popOver.hide();
});
hoverableNode.setOnMouseEntered(mouseEvent -> {if (!popOver.isShowing()) popOver.show(hoverableNode);});
hoverableNode.setOnMouseExited(mouseEvent -> timeline.play());
}
PopOver will be hidden after 1 sec after mouse leave hoverableNode or contentNode. Use it like this:
addAutoHidingPopOver(someLabel, someContentNode);
Note, that your content node should take all visible space of PopOver for comfort use.
That could be expected behavior. I am not sure, but here is a workaround. You can use a ToggleButton.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.controlsfx.control.PopOver;
public class App extends Application
{
#Override
public void start(Stage primaryStage)
{
//Build PopOver look and feel
Label lblName = new Label("John Doe");
Label lblStreet = new Label("123 Hello Street");
Button lblCityStateZip = new Button("MadeUpCity, XX 55555");
VBox vBox = new VBox(lblName, lblStreet, lblCityStateZip);
//Create PopOver and add look and feel
PopOver popOver = new PopOver(vBox);
ToggleButton toggleButton = new ToggleButton("Click me!");
toggleButton.selectedProperty().addListener((obs, oldValue, newValue) -> {
if (newValue) {
popOver.show(toggleButton);
}
else {
popOver.hide();
}
});
;
StackPane root = new StackPane();
root.getChildren().add(toggleButton);
var scene = new Scene(root, 500, 500);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}

Display Popup with ProgressBar in JavaFX

How can I display my progress bar through pop up and automatically close if process is finished. Here is my code.
Task<ProgressForm> task = new Task<ProgressForm>() {
#Override
public ProgressForm call() throws InterruptedException{
ProgressForm pf = new ProgressForm();
for (int i = 1; i <= 10; i++) {
pf.activateProgressBar(this);
updateProgress(i, 10);
}
return pf;
}
};
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent t) {
ProgressForm pf = (ProgressForm)task.getValue();
pf.getDialogStage().close();
}
});
Thread th = new Thread(task);
th.run();
Progress form class:
private final Stage dialogStage;
private final ProgressBar pb = new ProgressBar();
private final ProgressIndicator pin = new ProgressIndicator();
public ProgressForm() {
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);
// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");
pb.setProgress(-1F);
pin.setProgress(-1F);
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);
Scene scene = new Scene(hb);
dialogStage.setScene(scene);
}
public void activateProgressBar(final Task task) throws InterruptedException {
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
}
public Stage getDialogStage() {
return dialogStage;
}
The problem with this code is
if i use .show(), displaying pop up is smooth but NO PROGRESS BAR.
if i use .showAndWait(), displaying pop up requires manual exit for the pop up to close BUT Progress bar displays.
Any thoughts/ideas about this?
The two rules for multithreading in JavaFX are:
Code which modifies the UI (creates a Stage or changes properties
of nodes that are part of a scene graph) must be executed on the
JavaFX Application thread. Violating this rule will either throw
IllegalStateExceptions or result in unpredictable behavior.
Code which takes a long time to execute should be executed in a background thread (i.e. not the FX Application Thread). Violating this rule will cause the UI to become unresponsive.
Your code violates the first rule, because it calls the ProgressForm constructor in a background thread. You should set up the UI first, show the dialog, and then start the background thread.
Note that there is no need to repeatedly bind the progress properties of the progress bar and indicator to the progress property of the task. Once it is bound, it will remain bound until and unless you unbind it.
It's quite hard to fix your code as it stands, because your background task doesn't actually do anything that takes any time. Here's a version of what you're doing with just a pause:
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class ProgressDialogExample extends Application {
#Override
public void start(Stage primaryStage) {
Button startButton = new Button("Start");
startButton.setOnAction(e -> {
ProgressForm pForm = new ProgressForm();
// In real life this task would do something useful and return
// some meaningful result:
Task<Void> task = new Task<Void>() {
#Override
public Void call() throws InterruptedException {
for (int i = 0; i < 10; i++) {
updateProgress(i, 10);
Thread.sleep(200);
}
updateProgress(10, 10);
return null ;
}
};
// binds progress of progress bars to progress of task:
pForm.activateProgressBar(task);
// in real life this method would get the result of the task
// and update the UI based on its value:
task.setOnSucceeded(event -> {
pForm.getDialogStage().close();
startButton.setDisable(false);
});
startButton.setDisable(true);
pForm.getDialogStage().show();
Thread thread = new Thread(task);
thread.start();
});
StackPane root = new StackPane(startButton);
Scene scene = new Scene(root, 350, 75);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class ProgressForm {
private final Stage dialogStage;
private final ProgressBar pb = new ProgressBar();
private final ProgressIndicator pin = new ProgressIndicator();
public ProgressForm() {
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);
// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");
pb.setProgress(-1F);
pin.setProgress(-1F);
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);
Scene scene = new Scene(hb);
dialogStage.setScene(scene);
}
public void activateProgressBar(final Task<?> task) {
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
}
public Stage getDialogStage() {
return dialogStage;
}
}
public static void main(String[] args) {
launch(args);
}
}
You can use controlsfx library to display this easily
private void progressDialogue(){
copyWorker = createWorker();
ProgressDialog dialog = new ProgressDialog(copyWorker);
dialog.initStyle(StageStyle.TRANSPARENT);
dialog.setGraphic(null);
//stage.initStyle(StageStyle.TRANSPARENT);
dialog.initStyle(StageStyle.TRANSPARENT);
//dialog.setContentText("Files are Uploading");
//dialog.setTitle("Files Uploading");
//dialog.setHeaderText("This is demo");
dialog.setHeaderText(null);
dialog.setGraphic(null);
dialog.initStyle(StageStyle.UTILITY);
new Thread(copyWorker).start();
dialog.showAndWait();
}
public Task createWorker() {
return new Task() {
#Override
protected Object call() throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
updateMessage("2000 milliseconds");
updateProgress(i + 1, 10);
}
return true;
}
};
}
now you need to call the method progressDialogue();
the code is from this video : https://www.youtube.com/watch?v=DK_1YGLI9ig

JavaFX: Bind multiple Charts to single data property

In an attempt to use multiple views with one single backing model instance I tried to bind several charts to the same data property. But strangely only the last bound chart does show the data, while the first appears to be totally empty, although getData() on the first chart does yield the expected results, even after an update of the underlying property's content.
I wrote a short example to illustrate my problem hoping that someone may reveal my mistake to me and show me how to do it properly.
package javafx.databinding;
import java.util.ArrayList;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.chart.PieChart.Data;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class TestDataBinding extends Application
{
public static void main(String[] args)
{
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception
{
Property<ObservableList<Data>> sourceData =
new SimpleListProperty<Data>(FXCollections.observableList(new ArrayList<Data>()));
sourceData.getValue().add(new Data("first", 1));
sourceData.getValue().add(new Data("second", 2));
PieChart firstChart = new PieChart();
PieChart secondChart = new PieChart();
firstChart.dataProperty().bind(sourceData);
secondChart.dataProperty().bind(sourceData);
HBox layout = new HBox();
layout.getChildren().addAll(firstChart, secondChart);
Scene scene = new Scene(layout, 500d, 200d);
primaryStage.setScene(scene);
primaryStage.show();
System.out.println(firstChart.getData());
System.out.println(secondChart.getData());
Platform.runLater(new Task<Void>()
{
#Override
protected Void call() throws Exception
{
Thread.sleep(5000);
sourceData.getValue().get(0).setPieValue(5);
sourceData.getValue().get(1).setPieValue(3);
System.out.println(firstChart.getData());
System.out.println(secondChart.getData());
return null;
}
});
}
}
As excepted the logging results in
[Data[first,1.0], Data[second,2.0]]
[Data[first,1.0], Data[second,2.0]]
[Data[first,5.0], Data[second,3.0]]
[Data[first,5.0], Data[second,3.0]]
but the charts look like this
This is indeed very badly documented by JavaFX...
The PieChart.Data class is a mixture of data and view. For example the legends are stored as Text Nodes inside the data class. As you may know, a Node can only be contained in a single Parent element.
The following modified example works fine:
#Override
public void start(Stage primaryStage) throws Exception {
IntegerProperty first = new SimpleIntegerProperty(1);
IntegerProperty second = new SimpleIntegerProperty(1);
Data d11 = new Data("first", 0);
d11.pieValueProperty().bind(first);
Data d12 = new Data("first", 0);
d12.pieValueProperty().bind(second);
ObservableList<Data> sourceData1 = FXCollections.observableArrayList(d11,d12);
Data d21 = new Data("first", 0);
d21.pieValueProperty().bind(first);
Data d22 = new Data("first", 0);
d22.pieValueProperty().bind(second);
ObservableList<Data> sourceData2 = FXCollections.observableArrayList(d21,d22);
PieChart firstChart = new PieChart(sourceData1);
PieChart secondChart = new PieChart(sourceData2);
HBox layout = new HBox();
layout.getChildren().addAll(firstChart, secondChart);
Scene scene = new Scene(layout, 500d, 200d);
primaryStage.setScene(scene);
primaryStage.show();
System.out.println(firstChart.getData());
System.out.println(secondChart.getData());
new Thread(new Task<Void>() {
#Override
protected Void call() throws Exception {
Thread.sleep(5000);
first.set(5);
second.set(3);
System.out.println(firstChart.getData());
System.out.println(secondChart.getData());
return null;
}
}).start();
}

Java "Could Not Serialize the Data"

I'm trying to get my clipboard to receive some custom data in a drag and drop. The custom data is another java type. This other type does implement serializable, so I'm really not sure why this isn't working. Any ideas are appreciated!
imgView.setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
ClipboardContent content = new ClipboardContent();
content.put(dataFormat, RHSIconizedToken.this);
Dragboard db = imgView.startDragAndDrop(TransferMode.ANY);
db.setContent(content);
event.consume();
}
});
To retrieve this object later I'm using:
RHSIconizedToken replacementRHSiToken = (RHSIconizedToken) db.getContent(RHSIconizedToken.getDataFormat());
I'm getting the following error, but the RHSIconizedToken does implement Serializable
java.lang.IllegalArgumentException: Could not serialize the data
GetDataFormat returns the DataFormat Object that is used in the put argument in the first code example.
That's because your object is not serializable.
Indeed, it's not because it implements Serializable that it is Serializable.
Look deeper inside the exception, you might find something like this
Caused by: java.io.NotSerializableException: javafx.beans.property.SimpleObjectProperty
Maybe making some fields transient will help.
If your drag object isn't serializable, save it in a global variable during the drag. Here's a JavaFx (Java8 with lambdas) example with draggable tabs that go bewteen panes within the same JVM.
import java.util.Random;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DataFormat;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class DraggingTabPane extends Application {
private static final DataFormat TAB_TYPE = new DataFormat("nonserializableObject/tab");
private static Tab dndTab;// global for drag-n-drop of non-serializable type
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
TabPane tabPane1 = createDndTabPane();
TabPane tabPane2 = createDndTabPane();
VBox root = new VBox(10);
root.getChildren().addAll(tabPane1, tabPane2);
final Random rng = new Random();
for (int i=1; i<=8; i++) {
final Tab tab = createDraggableTab("Tab "+i);
final StackPane pane = new StackPane();
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);
final Label label = new Label("This is tab "+i);
label.setStyle(String.format("-fx-text-fill: rgb(%d, %d, %d);", 256-red, 256-green, 256-blue));
pane.getChildren().add(label);
pane.setMinWidth(600);
pane.setMinHeight(250);
tab.setContent(pane);
if (i<=4) {
tabPane1.getTabs().add(tab);
} else {
tabPane2.getTabs().add(tab);
}
}
primaryStage.setScene(new Scene(root, 600, 600));
primaryStage.show();
}
public TabPane createDndTabPane() {
final TabPane tabPane = new TabPane();
tabPane.setOnDragOver(event -> {
if (event.getDragboard().hasContent(TAB_TYPE)
&& dndTab.getTabPane() != tabPane) {// && different from source location
event.acceptTransferModes(TransferMode.MOVE);
event.consume();
}
});
tabPane.setOnDragDropped(event -> {
if (event.getDragboard().hasContent(TAB_TYPE)
&& dndTab.getTabPane() != tabPane) {// && different from source location
dndTab.getTabPane().getTabs().remove(dndTab);
tabPane.getTabs().add(dndTab);
event.setDropCompleted(true);
event.consume();
}
});
return tabPane;
}
private Tab createDraggableTab(String text) {
final Tab tab = new Tab();
final Label label = new Label(text);
tab.setGraphic(label);
label.setOnDragDetected(event -> {
Dragboard dragboard = label.startDragAndDrop(TransferMode.MOVE);
ClipboardContent clipboardContent = new ClipboardContent();
clipboardContent.put(TAB_TYPE, 1);
dndTab = tab;
dragboard.setContent(clipboardContent);
event.consume();
});
return tab ;
}
}

Resources