【问题标题】:How to resize component with mouse drag in JavaFX如何在 JavaFX 中通过鼠标拖动调整组件大小
【发布时间】:2013-05-31 07:23:49
【问题描述】:

我对如何通过鼠标拖动来调整此组件的大小很感兴趣:

VBox stackedTitledPanes = createStackedTitledPanes();

    ScrollPane scroll = makeScrollable(stackedTitledPanes);

    TabPane tabPane = new TabPane();
    BorderPane mainPane = new BorderPane();

    tabPane.setStyle("-fx-font-size: 12pt;"); // Set global size for the font
    // Create Tabs
    Tab tabA = new Tab();
    tabA.setText("Main Component");
    tabA.setStyle("-fx-font-size: 12pt;"); // Set size of the tab name
    // Add something in Tab
    StackPane tabA_stack = new StackPane();
    tabA_stack.setAlignment(Pos.CENTER);
    tabA_stack.getChildren().add(scroll); 
    tabA.setContent(tabA_stack);
    tabPane.getTabs().add(tabA);

    Tab tabB = new Tab();
    tabB.setText("Second Component");
    tabB.setStyle("-fx-font-size: 12pt;"); // Set size of the tab name
    // Add something in Tab
    StackPane tabB_stack = new StackPane();
    tabB_stack.setAlignment(Pos.CENTER);
    tabB_stack.getChildren().add(new Label("Label@Tab B"));
    tabB.setContent(tabB_stack);
    tabPane.getTabs().add(tabB);

    Tab tabC = new Tab();
    tabC.setText("Last Component");
    tabC.setStyle("-fx-font-size: 12pt;"); // Set size of the tab name
    // Add something in Tab
    StackPane tabC_vBox = new StackPane();
    tabC_vBox.setAlignment(Pos.CENTER);
    tabC_vBox.getChildren().add(new Label("Label@Tab C"));
    tabC.setContent(tabC_vBox);
    tabPane.getTabs().add(tabC);

    mainPane.setCenter(tabPane);

    mainPane.setPrefSize(395, 580);
    mainPane.setLayoutX(850);
    mainPane.setLayoutY(32);

    scroll.setPrefSize(395, 580);
    scroll.setLayoutX(850);
    scroll.setLayoutY(32);

    root.getChildren().add(mainPane);

问题是我在主舞台上放置了几个组件。当我调整一个组件的大小时,例如增加组件的高度,我必须减小下一个组件的大小,而不会跨过该组件。我该怎么做?

【问题讨论】:

    标签: javafx-2 javafx javafx-8


    【解决方案1】:

    我认为是堆栈窗格导致了问题,它不支持像 VBox 或 HBox 那样的调整大小行为。我在自己的程序中拖动以调整 TextArea 或 List 组件的大小,以使它们在必要时变大。在此处查看代码:

    https://bitbucket.org/atill/estimate/src/22390a2ca034b55f1916e46435b714e5c489b90e/src/main/java/projmon/ui/DragResizer.java?at=master

    及用法:

    https://bitbucket.org/atill/estimate/src/22390a2ca034b55f1916e46435b714e5c489b90e/src/main/java/projmon/control/TaskFormController.java?at=master

    编辑我已经提取了 EstiMate,但在这个要点中拖动调整器仍然是开源的。

    https://gist.github.com/andytill/4369729

    或完整的代码。

    import javafx.event.EventHandler;
    import javafx.scene.Cursor;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.Region;
    
    /**
     * {@link DragResizer} can be used to add mouse listeners to a {@link Region}
     * and make it resizable by the user by clicking and dragging the border in the
     * same way as a window.
     * <p>
     * Only height resizing is currently implemented. Usage: <pre>DragResizer.makeResizable(myAnchorPane);</pre>
     * 
     * @author atill
     * 
     */
    public class DragResizer {
    
        /**
         * The margin around the control that a user can click in to start resizing
         * the region.
         */
        private static final int RESIZE_MARGIN = 5;
    
        private final Region region;
    
        private double y;
    
        private boolean initMinHeight;
    
        private boolean dragging;
    
        private DragResizer(Region aRegion) {
            region = aRegion;
        }
    
        public static void makeResizable(Region region) {
            final DragResizer resizer = new DragResizer(region);
    
            region.setOnMousePressed(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    resizer.mousePressed(event);
                }});
            region.setOnMouseDragged(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    resizer.mouseDragged(event);
                }});
            region.setOnMouseMoved(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    resizer.mouseOver(event);
                }});
            region.setOnMouseReleased(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    resizer.mouseReleased(event);
                }});
        }
    
        protected void mouseReleased(MouseEvent event) {
            dragging = false;
            region.setCursor(Cursor.DEFAULT);
        }
    
        protected void mouseOver(MouseEvent event) {
            if(isInDraggableZone(event) || dragging) {
                region.setCursor(Cursor.S_RESIZE);
            }
            else {
                region.setCursor(Cursor.DEFAULT);
            }
        }
    
        protected boolean isInDraggableZone(MouseEvent event) {
            return event.getY() > (region.getHeight() - RESIZE_MARGIN);
        }
    
        protected void mouseDragged(MouseEvent event) {
            if(!dragging) {
                return;
            }
    
            double mousey = event.getY();
    
            double newHeight = region.getMinHeight() + (mousey - y);
    
            region.setMinHeight(newHeight);
    
            y = mousey;
        }
    
        protected void mousePressed(MouseEvent event) {
    
            // ignore clicks outside of the draggable margin
            if(!isInDraggableZone(event)) {
                return;
            }
    
            dragging = true;
    
            // make sure that the minimum height is set to the current height once,
            // setting a min height that is smaller than the current height will
            // have no effect
            if (!initMinHeight) {
                region.setMinHeight(region.getHeight());
                initMinHeight = true;
            }
    
            y = event.getY();
        }
    }
    

    【讨论】:

    • 有什么简单的例子可以实现组件的鼠标调整大小吗?
    • 这很简单,使用 DragResizer 并查看 TaskFormController 的第 174 和 175 行。
    • 此时,这些链接已断开。在帖子中直接包含内容避免了这种陷阱
    【解决方案2】:

    这里是针对上下区域情况的修改版本。如果一个区域增长,另一个区域会变小。

    public class DragResizer {
    
        /**
         * The margin around the control that a user can click in to start resizing
         * the region.
         */
        private static final int RESIZE_MARGIN = 5;
    
        private final Region top, bottom;
    
        private double y;
    
        private boolean initMinHeight;
    
        private boolean dragging;
    
        private double ySum;
    
        private DragResizer(Region top, Region bottom) {
            this.top = top;
            this.bottom = bottom;
            ySum = top.getPrefHeight() + bottom.getPrefHeight();
        }
    
        public static void makeResizable(Region top, Region bottom) {
            final DragResizer resizer = new DragResizer(top, bottom);
    
            top.setOnMousePressed(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    resizer.mousePressed(event);
                }});
            top.setOnMouseDragged(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    resizer.mouseDragged(event);
                }});
            top.setOnMouseMoved(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    resizer.mouseOver(event);
                }});
            top.setOnMouseReleased(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    resizer.mouseReleased(event);
                }});
        }
    
        protected void mouseReleased(MouseEvent event) {
            dragging = false;
            top.setCursor(Cursor.DEFAULT);
        }
    
        protected void mouseOver(MouseEvent event) {
            if(isInDraggableZone(event) || dragging) {
                top.setCursor(Cursor.S_RESIZE);
            }
            else {
                top.setCursor(Cursor.DEFAULT);
            }
        }
    
        protected boolean isInDraggableZone(MouseEvent event) {
            return event.getY() > (top.getHeight() - RESIZE_MARGIN);
        }
    
        protected void mouseDragged(MouseEvent event) {
            if(!dragging) {
                return;
            }
    
            double mousey = event.getY();
    
            double dy = (mousey - y);
    
            if(top.getMinHeight() + dy >= ySum || bottom.getPrefHeight() - dy >= ySum)
                return;
    
            top.setMinHeight(top.getMinHeight() + dy);
            top.setPrefHeight(top.getPrefHeight() + dy);
    
            bottom.setMinHeight(bottom.getMinHeight() - dy);
            bottom.setPrefHeight(bottom.getPrefHeight() - dy);
    
            y = mousey;
        }
    
        protected void mousePressed(MouseEvent event) {
    
            // ignore clicks outside of the draggable margin
            if(!isInDraggableZone(event)) {
                return;
            }
    
            dragging = true;
    
            // make sure that the minimum height is set to the current height once,
            // setting a min height that is smaller than the current height will
            // have no effect
            if (!initMinHeight) {
                top.setMinHeight(top.getHeight());
                initMinHeight = true;
            }
    
            y = event.getY();
        }
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-30
    • 2016-09-08
    • 1970-01-01
    相关资源
    最近更新 更多