我的SplitPane中有两个Canvas实例。当我拖动分隔条时,一个Canvas会增长。当我向后拖动分隔符时,Canvas并没有真正收缩。它具有与调整大小相同的最大尺寸。所以我只看到Canvas的一部分,但是SplitPane可以显示多少空间。其他Canvas也会出现类似的行为。当拖动分隔器时,我需要它们缩回以适合各自的部分,而不仅仅是将它们剪掉。
Canvases在添加到SplitPane之前包装在单元素GridPane子类中。每当包装器调整大小时,此包装类会调整Canvas的大小。
问题是SplitPane给出了错误的大小:无论Canvas的最大大小是多少。为什么SplitPane认为这是正确的做法?
答案 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();
}
请注意,每次调整场景大小或移动拆分内容分隔符时,两个画布都将重新绘制,但始终具有各自窗格的确切大小。正如他也建议的那样,您可以考虑对画布内容进行快照,并使用图像来提高性能。