微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

调整他的大小后,JavaFX 11 拖放对手势目标不起作用

如何解决调整他的大小后,JavaFX 11 拖放对手势目标不起作用

我遇到了下一个问题.. 我在我的应用程序中添加一个简单的拖放功能,以将卡片从左右 ListView 移动到中心表格。该表只是一个 GridView。网格子元素完美接收任何拖动事件,一切正常。

但是...如果我调整应用程序窗口的大小,我无法将卡片拖到 GridView 的右侧和底部。可能是这个 GridView 只是调整大小,但 JavaFX 拖动提供程序只是使用旧边界?我如何修复它并“说”拖动提供者关于新的 GridView 尺寸?

工作环境:

  • Oracle JDK 11.0.9
  • 自定义 JavaFX 11.0.2 运行时映像
  • Linux(内核 5.10.11,内部版本 170)
  • GTK 2(为使用 -Djdk.gtk.version=2 的 JFX 应用程序指定)

DragAndDropProvider.java(主 DnD 类):

public class DragAndDropProvider {
    
    public static final DataFormat SUBJECT_DATA_FORMAT = new DataFormat(SubjectCard.class.getName());
    public static final DataFormat TEACHER_DATA_FORMAT = new DataFormat(TeacherCard.class.getName());

    public static <T extends DatabaseCellDto<CARD>,CARD> void allowDragSourceFeature(ListView<T> listView) {
        listView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
        listView.setonDragDetected(event -> dragDetected(event,listView));
        listView.setonDragDone(event -> dragDone(event,listView));
    }
    
    public static void allowDragTargetFeature(LessonDto lesson) {
        lesson.setonDragOver(DragAndDropProvider::dragOver);
    }
    
    private static <T extends DatabaseCellDto<CARD>,CARD> void dragDetected(MouseEvent event,ListView<T> listView) {
        // make sure at list item is selected
        T selectedItem = listView.getSelectionModel().getSelectedItem();
        if(selectedItem == null) {
            event.consume();
            return;
        }
        
        // determining the date format
        DataFormat dataFormat;
        CARD card = selectedItem.getCard();
        
        if(card instanceof SubjectCard)
            dataFormat = SUBJECT_DATA_FORMAT;
        else if(card instanceof TeacherCard)
            dataFormat = TEACHER_DATA_FORMAT;
        else
            throw new RuntimeException("Unsupported transfer object type: " + card.getClass().getSimpleName());
 
        // initiate a drag-and-drop gesture
        Dragboard dragboard = listView.startDragAndDrop(TransferMode.ANY);
 
        // put the selected item to the dragboard
        ClipboardContent content = new ClipboardContent();
        content.put(dataFormat,selectedItem.getCard());
 
        dragboard.setContent(content);
        event.consume();
    }
 
    private static void dragOver(DragEvent event) {
        // if drag board has an ITEM_LIST and it is not being dragged
        // over itself,we accept the MOVE transfer mode
        Dragboard dragboard = event.getDragboard();
 
        if(dragboard.hasContent(SUBJECT_DATA_FORMAT) || dragboard.hasContent(TEACHER_DATA_FORMAT))
            event.acceptTransferModes(TransferMode.ANY);
 
        event.consume();
    }
 
    private static void dragDropped(DragEvent event,LessonDto target) {
        // transfer the data to the target
        Dragboard dragboard = event.getDragboard();
        boolean dragCompleted = false;
 
        if(dragboard.hasContent(SUBJECT_DATA_FORMAT)) {
            SubjectCard content = (SubjectCard) dragboard.getContent(SUBJECT_DATA_FORMAT);
            target.updateSubject(content);
            dragCompleted = true;
        } else if(dragboard.hasContent(TEACHER_DATA_FORMAT)) {
            TeacherCard content = (TeacherCard) dragboard.getContent(TEACHER_DATA_FORMAT);
            target.updateTeacher(content);
            dragCompleted = true;
        }
 
        event.setDropCompleted(dragCompleted);
        event.consume();
    }

}

应用界面(俄语,抱歉):

解决方法

我的问题解决了。 解决方法很简单。 当应用程序窗口最大化时,舞台的大小仍然是默认的,这是在初始化时设置的。 (例如,700 x 500)但实际上必须是例如 1366 x 768(这是我的屏幕分辨率)。

我只是使用此代码来修复它。 只需在 FXML 控制器初始化后插入此代码:)

        // stage is the window stage
        // we need the maximized property that mean is window maximized or not
        stage.maximizedProperty().addListener((a,b,isMaximized) -> {
            if(isMaximized) {
                // if this window is maximized,then we use
                // bounds maxX and maxY values than equals your
                // screen size parameters
                
                // mainPane is a root element in your FXML file
                // just set any FX:ID for that and use it here
                
                // you also can try Scene#getParent (cast to Region or any children)
                // to use him size parameters,but I prefer to use that
                stage.setWidth(mainPane.getBoundsInParent().getMaxX());
                stage.setHeight(mainPane.getBoundsInParent().getMaxY());
            } else {
                // overwise after window minimazing we just restore default
                // size parameters saved in the stage object
                stage.setWidth(stage.getWidth());
                stage.setHeight(stage.getHeight());
            }
        });

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。