Java FX SplitPane

时间:2015-01-06 22:19:44

标签: javafx

我的SplitPane中有两个Canvas实例。当我拖动分隔条时,一个Canvas会增长。当我向后拖动分隔符时,Canvas并没有真正收缩。它具有与调整大小相同的最大尺寸。所以我只看到Canvas的一部分,但是SplitPane可以显示多少空间。其他Canvas也会出现类似的行为。当拖动分隔器时,我需要它们缩回以适合各自的部分,而不仅仅是将它们剪掉。

Canvases在添加到SplitPane之前包装在单元素GridPane子类中。每当包装器调整大小时,此包装类会调整Canvas的大小。

问题是SplitPane给出了错误的大小:无论Canvas的最大大小是多少。为什么SplitPane认为这是正确的做法?

2 个答案:

答案 0 :(得分:2)

package experimental;

import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class SplitPaneProblem extends Application {

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

    public SplitPaneProblem() { }

    @Override
    public void start(Stage primaryStage) throws Exception {
        SplitPane splitPane = new SplitPane();
        splitPane.setOrientation(Orientation.VERTICAL);
        splitPane.getItems().add(new TestPane("0",new Canvas()));
        splitPane.getItems().add(new TestPane("1",new Canvas()));
        primaryStage.setScene(new Scene(splitPane));
        primaryStage.setHeight(400);
        primaryStage.setWidth(400);
        primaryStage.show();
    }

    public class TestPane extends AnchorPane {

        String name;
        Canvas canvas;

        public TestPane(String name,Canvas canvas) {
            super();
            this.canvas = canvas;
            getChildren().add(canvas);
//1         canvas.setManaged(false);
            this.name = name;
        }

        @Override
        public void resize(double width,double height) {
            System.out.println(name+" input  "+width+' '+height);
            super.resize(width, height);
            System.out.println(name+" panel  "+getWidth()+' '+getHeight());
//0         canvas.setWidth (width);
//0         canvas.setHeight(height);
            System.out.println(name+" canvas "+canvas.getWidth()+' '+canvas.getHeight());
        }
    }
}

Canvas不会自行调整大小。如图所示运行代码,然后上下拖动分隔线。阅读控制台输出。 Canvas实例的大小永远不会从(0,0)更改。

取消注释以// 0开头的行并再次运行它。现在,Canvas实例被强制调整为其包含窗格的大小。上下拖动分隔线。请注意,Canvas实例会垂直增长,但它们永远不会缩小,即使代码告诉它们。想象一下,我们在画布的角落画了一个X.这些X图纸会随着分隔线而增长。但是当你将分隔线向另一个方向拖动时,图像会被剪裁,但它永远不会收缩。

取消注释以// 1开头的行并再次运行它。现在它有效。

我不了解你,但我觉得这很奇怪。

答案 1 :(得分:1)

基于Jasper Potts的这个post,您可以创建一个可调整大小的画布,并在拆分窗格中使用它。

class ResizableCanvas extends Pane {

    private final int id;
    private final Canvas canvas = new Canvas();

    public ResizableCanvas(int id) {
        this.id=id;
        getChildren().add(canvas);
    }

    @Override
    protected void layoutChildren() {
        final int top = (int)snappedTopInset();
        final int right = (int)snappedRightInset();
        final int bottom = (int)snappedBottomInset();
        final int left = (int)snappedLeftInset();
        final int w = (int)getWidth() - left - right;
        final int h = (int)getHeight() - top - bottom;
        canvas.setLayoutX(left);
        canvas.setLayoutY(top);
        if (w != canvas.getWidth() || h != canvas.getHeight()) {
            canvas.setWidth(w);
            canvas.setHeight(h);
            GraphicsContext gc = canvas.getGraphicsContext2D();
            gc.clearRect(0, 0, w, h);
            if(id==1){
                gc.setFill(Color.BLUE);                
                gc.fillOval(5, 5, w-10, h-10);
            } else {
                gc.setFill(Color.RED);
                gc.fillRect(10, 10, w-20, h-20);
            } 
        }
    }
}

@Override
public void start(Stage stage) throws Exception {
    ResizableCanvas canvas1 = new ResizableCanvas(1);
    ResizableCanvas canvas2 = new ResizableCanvas(2);

    SplitPane split = new SplitPane();
    split.getItems().addAll(canvas1,canvas2);

    stage.setScene(new Scene(split, 600, 400));
    stage.show();
}

请注意,每次调整场景大小或移动拆分内容分隔符时,两个画布都将重新绘制,但始终具有各自窗格的确切大小。正如他也建议的那样,您可以考虑对画布内容进行快照,并使用图像来提高性能。