I borrowed code from here.
Here is the code:
package hellodraganddrop;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;
/**
* Demonstrates a drag-and-drop feature.
*/
public class HelloDragAndDrop extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage stage) {
stage.setTitle("Hello Drag And Drop");
Group root = new Group();
Scene scene = new Scene(root, 400, 200);
scene.setFill(Color.LIGHTGREEN);
final Text source = new Text(50, 100, "DRAG ME");
source.setScaleX(2.0);
source.setScaleY(2.0);
final Text target = new Text(250, 100, "DROP HERE");
target.setScaleX(2.0);
target.setScaleY(2.0);
source.setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
/* drag was detected, start drag-and-drop gesture*/
System.out.println("onDragDetected");
/* allow any transfer mode */
Dragboard db = source.startDragAndDrop(TransferMode.ANY);
/* put a string on dragboard */
ClipboardContent content = new ClipboardContent();
content.putString(source.getText());
db.setContent(content);
event.consume();
}
});
target.setOnDragOver(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* data is dragged over the target */
System.out.println("onDragOver");
/* accept it only if it is not dragged from the same node
* and if it has a string data */
if (event.getGestureSource() != target &&
event.getDragboard().hasString()) {
/* allow for both copying and moving, whatever user chooses */
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
event.consume();
}
});
target.setOnDragEntered(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* the drag-and-drop gesture entered the target */
System.out.println("onDragEntered");
/* show to the user that it is an actual gesture target */
if (event.getGestureSource() != target &&
event.getDragboard().hasString()) {
target.setFill(Color.GREEN);
}
event.consume();
}
});
target.setOnDragExited(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* mouse moved away, remove the graphical cues */
target.setFill(Color.BLACK);
event.consume();
}
});
target.setOnDragDropped(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* data dropped */
System.out.println("onDragDropped");
/* if there is a string data on dragboard, read it and use it */
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasString()) {
target.setText(db.getString());
success = true;
}
/* let the source know whether the string was successfully
* transferred and used */
event.setDropCompleted(success);
event.consume();
}
});
source.setOnDragDone(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* the drag-and-drop gesture ended */
System.out.println("onDragDone");
/* if the data was successfully moved, clear it */
if (event.getTransferMode() == TransferMode.MOVE) {
source.setText("");
}
event.consume();
}
});
root.getChildren().add(source);
root.getChildren().add(target);
stage.setScene(scene);
stage.show();
}
}
When drag detected it creates bended paper on the scene, and "DROP HERE" text catches it.
Is it possible to make it invisible or transparent? I tried any type of TransferMode but it is still existing.
The only solution came to my mind was just adding transparent png to DragBoard, but when drag detected on "DROP HERE" text some kind of plus icon is appearing below the cursor.
Are there any proper ways of implementing this feature?
Related
I am trying to figure out how to modify some existing code so that the console window that launches, starts out minimized as a tray icon instead of the default behavior which is to just open the window. Unfortunately I do not know Java, so I am having to just search Google and guess and check based on what code does make sense to me. I know this is asking a lot. I am trying my best to slowly pickup Java and I really appreciate the help. Could someone please read over this file and tell me if there is an obvious Boolean flip I need to make to change this behavior, or swap out some event handler. The code already has the provision to switch back and forth between tray icon and full window and I have made some progress by reading up on window listeners, specifically windowIconified, but I just don't have enough experience yet to really understand the changes I am making as they are not immediately obvious. The file below is one of many in this project, so if after reading you feel I am mistaken and the applicable code is missing, I can provide it. If I am properly understanding the code though, this is the file that builds out the console window, so I would assume the changes need to be made here. Thank you for any help!
package com.skcraft.launcher.dialog;
import com.skcraft.launcher.Launcher;
import com.skcraft.launcher.swing.LinedBoxPanel;
import com.skcraft.launcher.swing.MessageLog;
import com.skcraft.launcher.swing.SwingHelper;
import com.skcraft.launcher.util.PastebinPoster;
import com.skcraft.launcher.util.SharedLocale;
import lombok.Getter;
import lombok.NonNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import static com.skcraft.launcher.util.SharedLocale.tr;
/**
* A frame capable of showing messages.
*/
public class ConsoleFrame extends JFrame {
private static ConsoleFrame globalFrame;
#Getter private final Image trayRunningIcon;
#Getter private final Image trayClosedIcon;
#Getter private final MessageLog messageLog;
#Getter private LinedBoxPanel buttonsPanel;
private boolean registeredGlobalLog = false;
/**
* Construct the frame.
*
* #param numLines number of lines to show at a time
* #param colorEnabled true to enable a colored console
*/
public ConsoleFrame(int numLines, boolean colorEnabled) {
this(SharedLocale.tr("console.title"), numLines, colorEnabled);
}
/**
* Construct the frame.
*
* #param title the title of the window
* #param numLines number of lines to show at a time
* #param colorEnabled true to enable a colored console
*/
public ConsoleFrame(#NonNull String title, int numLines, boolean colorEnabled) {
messageLog = new MessageLog(numLines, colorEnabled);
trayRunningIcon = SwingHelper.createImage(Launcher.class, "tray_ok.png");
trayClosedIcon = SwingHelper.createImage(Launcher.class, "tray_closed.png");
setTitle(title);
setIconImage(trayRunningIcon);
setSize(new Dimension(650, 400));
initComponents();
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent event) {
performClose();
}
});
}
/**
* Add components to the frame.
*/
private void initComponents() {
JButton pastebinButton = new JButton(SharedLocale.tr("console.uploadLog"));
JButton clearLogButton = new JButton(SharedLocale.tr("console.clearLog"));
buttonsPanel = new LinedBoxPanel(true);
buttonsPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
buttonsPanel.addElement(pastebinButton);
buttonsPanel.addElement(clearLogButton);
add(buttonsPanel, BorderLayout.NORTH);
add(messageLog, BorderLayout.CENTER);
clearLogButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
messageLog.clear();
}
});
pastebinButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
pastebinLog();
}
});
hideMessages();
}
/**
* Register the global logger if it hasn't been registered.
*/
private void registerLoggerHandler() {
if (!registeredGlobalLog) {
getMessageLog().registerLoggerHandler();
registeredGlobalLog = true;
}
}
/**
* Attempt to perform window close.
*/
protected void performClose() {
messageLog.detachGlobalHandler();
messageLog.clear();
registeredGlobalLog = false;
dispose();
}
/**
* Send the contents of the message log to a pastebin.
*/
private void pastebinLog() {
String text = messageLog.getPastableText();
// Not really bytes!
messageLog.log(tr("console.pasteUploading", text.length()), messageLog.asHighlighted());
PastebinPoster.paste(text, new PastebinPoster.PasteCallback() {
#Override
public void handleSuccess(String url) {
messageLog.log(tr("console.pasteUploaded", url), messageLog.asHighlighted());
SwingHelper.openURL(url, messageLog);
}
#Override
public void handleError(String err) {
messageLog.log(tr("console.pasteFailed", err), messageLog.asError());
}
});
}
public static void showMessages() {
ConsoleFrame frame = globalFrame;
if (frame == null) {
frame = new ConsoleFrame(10000, false);
globalFrame = frame;
frame.setTitle(SharedLocale.tr("console.launcherConsoleTitle"));
frame.registerLoggerHandler();
frame.setVisible(true);
} else {
frame.setVisible(true);
frame.registerLoggerHandler();
frame.requestFocus();
}
}
public static void hideMessages() {
ConsoleFrame frame = globalFrame;
if (frame != null) {
frame.setVisible(false);
}
}
}
starts out minimized as a tray icon
You need to use:
setExtendedState(JFrame.ICONIFIED);
when you set the other frame properties.
I am trying to make a simple UI to launch a selenium test that has the ability to start a background thread which launches a browser when the Start Button is pressed and stops the thread and closes it when the Stop button is pressed.
Unfortunately when I click stop after starting it, it does not work. If I let it finish I cannot restart the thread. How would I go about updating this so that I can make it submit a new thread that can be stopped by the stop button.
package application;
import org.openqa.selenium.WebDriver;
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
public class Main extends Application {
Stage window;
GridPane grid;
public void start(Stage primaryStage) {
/*
* Set up the stage
*/
window = primaryStage;
window.setTitle("URL LOADER - V1");
grid = new GridPane();
grid.setPadding(new Insets(10,10,10,10));
grid.setVgap(8);
grid.setHgap(10);
window.setResizable(false);
/*
* URL input
*/
Label URLLabel = new Label("URL");
GridPane.setConstraints(URLLabel,0,0);
TextField URLTextField = new TextField();
URLTextField.setPromptText("https://www.google.com");
GridPane.setConstraints(URLTextField,1,0);
/*
* Create Buttons
*/
Button buttonStart = new Button("Create");
GridPane.setConstraints(buttonStart,1,6);
Button buttonStop = new Button("Stop");
GridPane.setConstraints(buttonStop,1,8);
grid.getChildren().addAll(URLLabel,URLTextField, buttonStart, buttonStop);
/*
* Create the scene
*/
Scene scene = new Scene(grid, 300, 300);
window.setScene(scene);
window.show();
Task<Void> task = new Task<Void>(){
#Override
protected Void call() {
new VisitPage().Start(this,URLTextField.getText());;
return null;
}
};
buttonStart.setOnAction(new EventHandler<ActionEvent>() {
/*
* Start Button Clicked
*/
public void handle(ActionEvent event) {
new Thread(task).start();
}
});
buttonStop.setOnAction(new EventHandler<ActionEvent>() {
/*
* Start Button Pressed
*/
public void handle(ActionEvent event) {
System.out.println("Stop Pressed");
}
});
}
public class VisitPage {
private String URL;
Browser BrowserFactory;
ThreadLocal<WebDriver> drivers;
WebDriver Browser;
public void Start(Task<Void> task, String URL) {
while (true) {
if (task.isCancelled())
{
System.out.println("Canceling...");
System.out.println("Stop Pressed");
Browser.close();
Browser.quit();
BrowserFactory.CloseDriver(drivers);
task.cancel();
}
else
{
/*
* Create Browser Factor to make ThreadLocal Browsers
*/
BrowserFactory = new Browser(1, 1);
drivers = BrowserFactory.SpawnBrowser();
/*
* Grab a Browser
*/
Browser = BrowserFactory.SpawnDriver(drivers);
/*
* Visit and scrape
*/
Browser.get(URL);
/*
* Wait 5 Seconds before closing
*/
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Browser.close();
Browser.quit();
BrowserFactory.CloseDriver(drivers);
}
}
}
}
public static void main(String[] args) {
launch(args);
}
}
According to documentation
As with FutureTask, a Task is a one-shot class and cannot be reused. See Service for a reusable Worker.
So you have to create new task for each run. So I added task as field in Main:
Stage window;
GridPane grid;
Task<Void> task;
Then create task when start button is clicked:
buttonStart.setOnAction(new EventHandler<ActionEvent>() {
/*
* Start Button Clicked
*/
#Override
public void handle(ActionEvent event) {
if(task != null) {
System.out.println("Task already running");
return;
}
task = new Task<Void>() {
#Override
protected Void call() {
new VisitPage().start(this, URLTextField.getText());
;
return null;
}
};
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
}
});
On stop button click you have to cancel task:
buttonStop.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if(task == null) {
System.out.println("Task not running");
return;
}
System.out.println("Stop Pressed");
task.cancel();
task = null;
}
});
This will do nothing, because it is your responsibility to end task when it is cancelled, and you are not ending your infinite loop.
So your VisitPage should look like this (I skipped testing details, since I do not have them on classpath):
public class VisitPage {
public void start(Task<Void> task, String URL) {
while (!task.isCancelled()) {
System.out.println("Running test");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Test run ended");
}
System.out.println("Canceling...");
System.out.println("Stop Pressed");
return;
}
}
Some minor points:
Technically task.cancel() would end your thread sometimes if you would not catch InterruptedException that is thrown if your thread is sleeping.
I am not sure how your code compiled but I had to make some variables final so they can be used in handlers: (never mind, from Java SE 8 local variables can be effectively final)
final TextField URLTextField = new TextField();
//...
final Task<Void> task = new Task<Void>(){
//...
I would define created thread as daemon so it will not keep running when you close your UI without stopping tests:
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
I also renamed Start method to start
I am creating a window with JavaFX, using an object oriented approach which will allow different kinds of windows to be created with the same basic framework. These windows will display html content.
I have run into a concurrency problem when trying to add an observer.
Window:
public Window(String linkName, String fName, String wName, int width, int height, GuiObserver o) throws IOException {
wApp = new WindowApp();
wApp.setObserver(o);
new Thread(new Runnable() {
public void run() {
wApp.launch(WindowApp.class,linkName,fName,wName,""+width,""+height);
/*try {
wApp.launch(WindowApp.class,linkName,fName,wName,""+width,""+height);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
}).start();
}
This creates the window and sets the observer, but puts the launch into a new thread. I can confirm that the observer is added, but the observer cannot be notified. Here is the WindowApp class:
/**
* Instantiate the class with an html file
* THIS MUST NOT TAKE ANY PARAMETERS
*/
public WindowApp() throws IOException {}
#Override
public void start(Stage s) throws Exception {
this.stage = s;
//get the parameters
List<String> params = getParameters().getRaw();
String linkName = params.get(0);
updateHtmlFromFile(new File(params.get(1)));
windowName = params.get(2);
windowWidth = Integer.parseInt(params.get(3));
windowHeight = Integer.parseInt(params.get(4));
//create the window
stage.setWidth(windowWidth);
stage.setHeight(windowHeight);
Scene scene = new Scene(new Group());
browser = new WebView();
webEngine = browser.getEngine();
webEngine.setJavaScriptEnabled(true);
//add the link which will bind Java and Javascript functionality
Class jC = Class.forName(linkName);
Constructor jCon = jC.getConstructor(browser.getClass(),webEngine.getClass(),stage.getClass());
javascriptLink = (JavascriptLink) jCon.newInstance(browser,webEngine,stage);
javascriptLink.setObserver(gObserver);
//javascriptLink = new JavascriptLink(browser,webEngine,stage);
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(browser);
webEngine.getLoadWorker().stateProperty()
.addListener(new ChangeListener<State>() {
#Override
public void changed(ObservableValue ov, State oldState, State newState) {
if (newState == Worker.State.SUCCEEDED) {
stage.setTitle(windowName);
}
}
});
webEngine.load(htmlUrl);
scene.setRoot(scrollPane);
stage.setScene(scene);
stage.show();
}
/**
* Add an observer to the javascript Link
* #param o
*/
public void setObserver(GuiObserver o) {
gObserver = o;
}
This object also has a "Javascript link" which interacts with the HTML document after its launch:
package gui;
import java.io.FileNotFoundException;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class MainWindowJSLink extends JavascriptLink {
private GuiObserver gObserver;
/**
* This will be called by WindowApp when appropriate, and does not need to be called by a person
* #param b
* #param we
* #param st
* #throws FileNotFoundException
*/
public MainWindowJSLink(WebView b, WebEngine we, Stage st) throws FileNotFoundException {
super(b, we, st);
}
#Override
public void eventTriggered(String eventName) {
System.out.println("Event triggered -> "+eventName);
switch (eventName) {
case "codeEditorContentsChanged":
handleCodeEditorContentsChanged();
break;
}
//notify observers if necessary
this.triggerObserver(eventName, null);
}
/**
* Handle the event that the contents of the code editor have changed
* This will probably setup a timer to wait a few seconds until the user has stopped typing,
* then send the contents to the syntax highlighter and get the result back
*/
private void handleCodeEditorContentsChanged() {
//System.out.println(getJSCodeEditorContents());
}
/**
* Get the raw contents of the code editor (unedited and not stripped of html entities)
* #return
*/
public String getJSCodeEditorContents() {
String contents = (String) super.webEngine.executeScript("getCodeEditorContents()");
return contents;
}
/**
* Set the contents of the code editor
* #param contents String
* NOTE:
*/
public void setJSCodeEditorContents(String contents) {
super.webEngine.executeScript("setCodeEditorContents(`"+contents+"`)");
}
//observer observable stuff
#Override
public void setObserver(GuiObserver o) {
gObserver = o;
gObserver.setJS(this);
System.out.println("MainWindow -> observer set");
}
#Override
public void triggerObserver(String s, Object o) {
gObserver.trigger(s,o);
}
#Override
/**
* Handle information sent from the
*/
public void send(String s, Object o) {
//handle information sent to this object
}
}
Unfortunately, the gObserver.trigger does not execute. Interestingly enough, if I put a System.exit(0) before that trigger is called, the program exits. However, if I put it after it is called (or in the corresponding method), it is not.
Can anyone offer any advice on how to fix this concurrency issue? If you need more information, please let me know, and I will provide it.
Hey there community I was wondering if is possible to create a program that allows for the user to Drag a file from anywhere on there hard drive (the desktop, documents folder, videos folder) and drop it into the window of the program.
I am creating a media player and I want to be able to play a video by dragging and dropping a MP4 into the window. Do I need to store the file in a variable, or just the location of the file into a variable. Also, it is important I keep support for cross platform.
I am using JavaFx with java 7 update 79 jdk.
Thanks in advance.
Here is a simple drag and drop example that just sets the file name and location. Drag files to it and it shows their name and location. Once you know that it should be a completely separate matter to actually play the file. It is primarily taken from Oracle's documentation: https://docs.oracle.com/javafx/2/drag_drop/jfxpub-drag_drop.htm
A minimal implementation needs two EventHandler s set OnDragOver and OnDragDropped.
public class DragAndDropTest extends Application {
#Override
public void start(Stage primaryStage) {
Label label = new Label("Drag a file to me.");
Label dropped = new Label("");
VBox dragTarget = new VBox();
dragTarget.getChildren().addAll(label,dropped);
dragTarget.setOnDragOver(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent event) {
if (event.getGestureSource() != dragTarget
&& event.getDragboard().hasFiles()) {
/* allow for both copying and moving, whatever user chooses */
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
event.consume();
}
});
dragTarget.setOnDragDropped(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent event) {
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasFiles()) {
dropped.setText(db.getFiles().toString());
success = true;
}
/* let the source know whether the string was successfully
* transferred and used */
event.setDropCompleted(success);
event.consume();
}
});
StackPane root = new StackPane();
root.getChildren().add(dragTarget);
Scene scene = new Scene(root, 500, 250);
primaryStage.setTitle("Drag Test");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
When working with Drag and Drop events, you could try the following:
Obtain a Dragboard-object of the DragEvent and work with the method getFiles:
private void handleDragDropped(DragEvent event){
Dragboard db = event.getDragboard();
File file = db.getFiles().get(0);
}
I solved this by adding two event handlers. One for DragDropped event and the other for DragOver event.
e.g:
#FXML
void handleFileOverEvent(DragEvent event)
{
Dragboard db = event.getDragboard();
if (db.hasFiles())
{
event.acceptTransferModes(TransferMode.COPY);
}
else
{
event.consume();
}
}
#FXML
void handleFileDroppedEvent(DragEvent event)
{
Dragboard db = event.getDragboard();
File file = db.getFiles().get(0);
handleSelectedFile(file);
}
Else it did not work for me, dragging the file over my pane, didn't trigger anything.
I use JavaFX, project has 2 Anchorpane (pane and paneDrop) , one of them has a button, when I drag this button create new button , when dragdropped setOnDragDetected method to new button. Problem is, when I try drag one of new butoons only last creating button move.
#FXML
private Button source;
#FXML
private AnchorPane pane;
#FXML
private AnchorPane paneDrop;
private Button b;
int i = 1;
int moveI = 0;
#FXML
private void dragDetected(MouseEvent event) {
System.out.println("onDragDetected");
b = new Button(i + "");
i++;
pane.getChildren().add(b);
b.setLayoutX(source.getLayoutX());
b.setLayoutY(source.getLayoutX());
/* drag was detected, start drag-and-drop gesture*/
paneDrop.setOnDragOver(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent k) {
paneDrop.setOnDragDropped(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent k1) {
System.out.println("ondragExited");
pane.getChildren().remove(b);
paneDrop.getChildren().add(b);
b.setLayoutX(k1.getSceneX() - paneDrop.getLayoutX());
b.setLayoutY(k1.getSceneY() - paneDrop.getLayoutY());
b.setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(MouseEvent t) {
/* drag was detected, start a drag-and-drop gesture*/
/* allow any transfer mode */
paneDrop.setOnDragOver(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent t) {
System.out.println("ondragOver");
paneDrop.setOnDragDropped(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent t1) {
System.out.println("ondragOver");
if (t1.getGestureSource() != pane
&& t1.getDragboard().hasString()) {
t1.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
t1.consume();
}
});
b.setLayoutX(t.getSceneX());
b.setLayoutY(t.getSceneY() - 224);
if (t.getGestureSource() != pane
&& t.getDragboard().hasString()) {
t.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
t.consume();
}
});
Dragboard db = b.startDragAndDrop(TransferMode.MOVE);
System.out.println("ttttttttttttt");
/* Put a string on a dragboard */
ClipboardContent content = new ClipboardContent();
content.putString(b.getText());
db.setContent(content);
t.consume();
}
});
k1.consume();
}
});
System.out.println("ondragOver");
b.setLayoutX(k.getSceneX() - pane.getLayoutX());
b.setLayoutY(k.getSceneY() - pane.getLayoutY());
if (k.getGestureSource() != pane
&& k.getDragboard().hasString()) {
k.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
k.consume();
}
});
/* allow any transfer mode */
Dragboard db = source.startDragAndDrop(TransferMode.MOVE);
/* put a string on dragboard */
ClipboardContent content = new ClipboardContent();
//System.out.println(source.getText());
content.putString(source.getText());
db.setContent(content);
event.consume();
}