2017-10-18 4 views
1

ドラッグアンドドロップ操作中にポップアップダイアログを使用しています。ドロップが発生すると、ダイアログがポップアップし、解除されると、イベントチェーンが継続され、ドラッグ操作が終了したときに何かが起きるようになります。ポップアップダイアログがFXの場合は問題ありませんが、Gluonの場合はドラッグを終了しても動作しません。ここダイアログでドラッグ終了イベントが伝播しない

は、サンプルコードである:

import javafx.scene.control.Alert.AlertType; 
import javafx.scene.control.Label; 
import javafx.scene.input.ClipboardContent; 
import javafx.scene.input.DataFormat; 
import javafx.scene.input.Dragboard; 
import javafx.scene.input.TransferMode; 
import javafx.scene.layout.Background; 
import javafx.scene.layout.BackgroundFill; 
import javafx.scene.layout.HBox; 
import javafx.scene.paint.Color; 

import com.gluonhq.charm.glisten.mvc.View; 

public class MainView extends View { 

    HBox root; 

    public MainView(String name) { 
     super(name); 

     Label source = new Label("Source"); 
     configureDragSource(source); 
     Label target = new Label("Target"); 
     configureDragTarget(target); 
     Label popupTarget = new Label("Popup Target"); 
     configureDragPopupTarget(popupTarget); 
     root = new HBox(40, source, target, popupTarget); 
     setCenter(root); 
    } 

    private void configureDragSource(Label source) { 
     source.setOnDragDetected(e -> { 
      root.setBackground(new Background(new BackgroundFill(Color.RED, null, null))); 
      Dragboard db = source.startDragAndDrop(TransferMode.ANY); 
      ClipboardContent content = new ClipboardContent(); 
      content.put(DataFormat.PLAIN_TEXT, source.getText()); 
      db.setContent(content); 
     }); 
     source.setOnDragDone(e -> root.setBackground(new Background(new BackgroundFill(null, null, null)))); 
    } 

    private void configureDragTarget(Label target) { 
     target.setOnDragOver(e -> e.acceptTransferModes(TransferMode.ANY)); 

    } 

    private void configureDragPopupTarget(Label popupTarget) { 
     popupTarget.setOnDragOver(e -> e.acceptTransferModes(TransferMode.ANY)); 
     popupTarget.setOnDragDropped(e -> { 
      javafx.scene.control.Alert popup1 = new javafx.scene.control.Alert(AlertType.INFORMATION); 
      com.gluonhq.charm.glisten.control.Alert popup2 = new com.gluonhq.charm.glisten.control.Alert(AlertType.INFORMATION); 
      popup1.showAndWait(); 
     }); 
    } 
} 

ソースは背景が赤色に変化する際にドラッグされるべきです。ドラッグ操作が完了すると、背景がデフォルトに戻ります。通常のドロップターゲットは何もせず、色の変更が機能します。しかし、ポップアップターゲットをドロップすると、ダイアログが表示され、閉じているときにはFXダイアログの色のみが変化し、グルーンダイアログの色は変化しません。 popup1.showAndWait();popup2に変更してください。

が重要な場合、これはアプリケーションクラス

import com.gluonhq.charm.glisten.application.MobileApplication; 

public class TestApplication extends MobileApplication { 

    @Override 
    public void init() { 
     addViewFactory(HOME_VIEW,() -> new MainView(HOME_VIEW)); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

であり、これはGradleのビルドファイルです:

buildscript { 
    repositories { 
     jcenter() 
    } 
    dependencies { 
     classpath 'org.javafxports:jfxmobile-plugin:1.3.5' 
    } 
} 

apply plugin: 'org.javafxports.jfxmobile' 
apply plugin: 'eclipse' 

jar { 
    manifest { 
     attributes 'Main-Class': 'com.test.TestApplication' 
    } 
} 

jfxmobile { 
    downConfig { 
     version = '3.3.0' 
     plugins 'display', 'lifecycle', 'statusbar', 'storage' 
    } 
    android { 
     compileSdkVersion = 19 
//  manifest = 'src/android/AndroidManifest.xml' 
    } 
    ios { 
     infoPList = file('src/ios/Default-Info.plist') 
     forceLinkClasses = [ 
       'com.gluonhq.**.*', 
       'javax.annotations.**.*', 
       'javax.inject.**.*', 
       'javax.json.**.*', 
       'org.glassfish.json.**.*' 
     ] 
    } 
} 

eclipse { 
    classpath { 
     downloadJavadoc = true 
     downloadSources = true 
    } 
} 

repositories { 
    jcenter() 
    maven { 
     url 'http://nexus.gluonhq.com/nexus/content/repositories/releases' 
    } 
} 

mainClassName = 'com.test.TestApplication' 

dependencies { 
    compile 'com.gluonhq:charm:4.3.5' 
} 

task wrapper(type: Wrapper) { 
    gradleVersion = '4.2' 
} 

compile 'com.gluonhq:charm:4.3.7'および4.4.0にも起こります。

Java 8 b141で実行しています。なぜこれが起こるのですか?これはバグですか?

+0

ダイアログjavadocページ上の 'dialog.setContent(new Label("ただの通常のダイアログで、単純で単純な ");' ''がありません。 – Mark

+0

デスクトップで 'popup2'を実行しているときにNPEが表示されますか? –

+0

@JoséPeredaいいえ、私もイベントハンドラの中にキャッチしようとしましたが、何も捕まえられませんでした。私は特定の場所を見ているべきですか? – Mark

答えて

1

JavaFXの組み込みダイアログとGluonダイアログは同じではありません。実際、後者はLayerから拡張され、前者のようにモーダルでブロックされています。

を用いて容易に解決できることを、私はpopupTargetの上に落下した後、NPEを取得し、Mac上で掲載コードを実行:

ドラッグイベントがダイアログによって消費されていることを与えられた。また
Platform.runLater(() -> popup2.showAndWait()); 

、可能な解決策を可能性:

Platform.runLater(() -> 
    popup2.showAndWait() 
     .ifPresent(r -> 
      root.setBackground(new Background(new BackgroundFill(null, null, null))))); 

ですから、setOnDragDoneメソッドをリファクタリングでき、ちょうどダイアログも同様に閉じられた後に呼び出される可能性がメソッドを作成します。

ターゲットがドラッグにこれらのイベントを受信して​​、ジェスチャードロップ:

DRAG_OVER 
DRAG_OVER 
... // until drop is done: 
// show Dialog 
... 
// hide Dialog 
DRAG_DROPPED 
DRAG_EXITED 
DRAG_EXITED_TARGET 

EDIT

これらは、ターゲットとソースの両方がDNDイベントが開始された後に受け取るドラッグイベントがあります

これらはJavaFXとGluonのダイアログとまったく同じです(少なくともWindowsの場合、NPEのためMacではPlatform.runLater()を使用すると表示が明らかに遅れます)Dialog and hide Dialog eventsしかし、今はWindowsに焦点を当てるだけです)。

右はその最後のイベントの後に、ソースが受信:

DRAG_DONE 

だけのJavaFXダイアログで。次のようにいくつかのデバッグした後、グルーオンのダイアログがイベントを行って、ドラッグを中止した理由を説明することができる

SceneクラスはDnDGestureプライベートクラスがあります。

/** 
* A Drag and Drop gesture has a lifespan that lasts from mouse 
* PRESSED event to mouse RELEASED event. 
*/ 
class DnDGesture { 
    ... 
} 

そして、それが説明されているとして、コメントでは、マウスの押したイベントからマウスの離したイベントまでの寿命があります。

JavaFXの組み込みダイアログを使用すると、これが新しいステージに表示され、新しいシーンに表示されます。ここで重要なのは、このダイアログ(およびすべてのマウスイベントのセット)が新しいモーダルステージに表示されるため、ダイアログが非表示になると、メインステージが再びフォーカスを取り戻して再開し、マウスが移動するとリリースされました。

しかし、Gluonのダイアログを使用すると、2番目のステージはありません。すべてが同じステージで発生し、マウスが解放されるとScene.DnDGestureがヌルになるので、DRAG_EXITED_TARGETイベントがターゲットで発生すると、適切な呼び出しが行われてdndプロセスが終了しますが、この時点でdndGestureはnullです。コールはもはやソースに到達しません。

モバイル環境で2番目のステージ/シーンを避け、ビュー/レイヤーを(1つの単一ステージで)デザインに保つ理由は数多くあるので、これはバグだとは思わないが、 。

+0

はい現在、私の回避策は、エラーが発生しないため、runLaterを使わずに2番目の例で行ったのと同じように、drag doneイベントハンドラをdrag done内で呼び出すことです。グルーオンのダイアログは、ネイティブのものと同じように振る舞いますか?これはバグと見なされますか? – Mark

+0

私は何が起こっているのか、なぜ私はそれをバグとは見なさないのか、さらに解説して答えを編集しました。 –

関連する問題