ファイルの場所を取得し、ファイルの情報を表示するためにステージ上のいくつかの要素を非表示にするDrag and Dropを非常に簡単に実装しました。しかし、setVisible()やステージとやりとりする他のコマンドを使用しようとすると、私のプログラムは完全にデッドロックになります。ファイルをドラッグした後にprintlnがあっても問題ないですが、UIを操作するロジックがある瞬間に停止します。DragEventでsetVIsibleメソッドを使用するとJavafxのデッドロックが発生する
これは、ファイルが
"[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)
にドラッグされた後、デッドロックがここにドラッグイベントを取得最小化メインメソッドで、次のようになります。
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);
}
}
最小化コントローラ
package sample;
import javafx.scene.control.Button;
public class Controller {
public Button buttonTest;
}
最小化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>
私はそれ自身のスレッドにしたdragEventを分割することによって、これを処理することができるかもしれないと思ったが、並行処理規則に従ってjavafxでは、すべてのグラフィックがメインのjavafxGUIスレッド上になければならないため、ステージを操作することはできません。
誰かが正しい方向に私を指すことができます願って、ありがとう!
'controller'、どこで何あなたはそれを初期化していますか? –
@James_D申し訳ありませんが、それを含めることを忘れてしまった、私はそれをfxmlファイルのコントローラであるstartメソッドの前に初期化します。 – nmu
startメソッドの前に初期化すると、fxmlファイルのコントローラになることはありません。 fxmlファイルのコントローラは、 'load'を呼び出すときに' FXMLLoader'によって作成されるので、起動メソッドの最初の行が完了するまでインスタンス化されていません。 –