mit Ich habe eine ziemlich einfache Implementierung eines Drag & Drop, die einen Speicherort der Datei bekommt und dann versteckt sich einige Elemente auf der Bühne Informationen über die Datei anzuzeigen. Allerdings wird mein Programm vollständig blockiert, wenn ich versuche, setVisible() oder einen anderen Befehl zu verwenden, der mit der Bühne interagiert. Wenn ich nur nach dem Ziehen mit der Datei einen Ausdruck habe, funktioniert es gut, aber sobald ich irgendeine Logik habe, die die Benutzeroberfläche manipuliert, stoppt sie einfach. DieseJavaFX Deadlock, wenn setVisible Methode mit Dragevent
ist, was aus der Sackgasse aussieht, nachdem eine Datei in
"[email protected]" prio=5 tid=0x1 nid=NA waiting
java.lang.Thread.State: WAITING
at sun.misc.Unsafe.park(Unsafe.java:-1)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
gezogen wird hier das minimierte Hauptverfahren, das das Drag-Ereignis wird.
package sample;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.stage.Stage;
import java.io.File;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Scene scene = new Scene(root, 300, 275);
scene.setOnDragOver(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent event) {
Dragboard db = event.getDragboard();
if (db.hasFiles()) {
event.acceptTransferModes(TransferMode.COPY);
} else {
event.consume();
}
}
});
scene.setOnDragDropped(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent event) {
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasFiles()) {
success = true;
String filePath = null;
for (File file:db.getFiles()) {
filePath = file.getAbsolutePath();
System.out.println(filePath);
Controller controller = new Controller();
//Part where it crashes,
controller.buttonTest.setVisible(false);
}
}
event.setDropCompleted(success);
event.consume();
}
});
primaryStage.setTitle("Hello World");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Der minimierte-Controller
package sample;
import javafx.scene.control.Button;
public class Controller {
public Button buttonTest;
}
Die minimierte fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<GridPane alignment="center" hgap="10" vgap="10" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="sample.Controller">
<columnConstraints>
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
<children>
<Button fx:id="buttonTest" mnemonicParsing="false" text="Test" />
</children>
</GridPane>
Ich dachte, ich könnte in der Lage sein, dies zu umgehen, indem das dragevent in seinen eigenen Thread Aufspalten aber nach den gemeinsamen Zugriff Regeln in javafx wäre es ohnehin nicht möglich, die Bühne zu manipulieren, da alle Grafiken im javafxGUI-Hauptthread liegen müssen.
der Hoffnung, jemand kann mir in die richtige Richtung weisen, danke!
Was 'controller' ist und wo Initialisierst du es? –
@James_D Entschuldigung vergessen zu schließen, ich initialisiere es vor der Start-Methode, es ist der Controller der fxml-Datei. – nmu
Es kann unmöglich der Controller für die fxml-Datei sein, wenn Sie es vor der Startmethode initialisieren. Der Controller für die fxml-Datei wird vom 'FXMLLoader' beim Aufruf von' load' erstellt und wurde daher nicht instanziiert, bis die erste Zeile Ihrer Startmethode abgeschlossen ist. –