JavaFX - 调整屏幕大小时调整画布大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23449932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 23:03:13  来源:igfitidea点击:

JavaFX - Resize Canvas when screen is resized

javacanvasresizejavafx

提问by Mark Nutt

I'm working on the GUI of my level editor that I built in JavaFX, and I want to be able to resize the canvas object to the new split pane dimensions. It seems that everything iv'e tried has failed. This includes passing the pane object in and using it's width directly, using window size listeners and binding the width and height property to that of the split pane. Any ideas. This is what it loos like before a resize:

我正在处理我在 JavaFX 中构建的关卡编辑器的 GUI,并且我希望能够将画布对象的大小调整为新的拆分窗格尺寸。似乎我尝试过的一切都失败了。这包括传入窗格对象并直接使用它的宽度、使用窗口大小侦听器并将宽度和高度属性绑定到拆分窗格的宽度和高度属性。有任何想法吗。这是调整大小之前的样子:

enter image description here

在此处输入图片说明

And after a resize:

在调整大小之后:

enter image description here

在此处输入图片说明

Does anybody hasve any ideas. The code for the class is pretty extensive, but the code for the resizing will be included.

有没有人有任何想法。该类的代码非常广泛,但将包括调整大小的代码。

public Canvas canvas;
public String tabTitle;
public VBox layout;
public GraphicsContext g;
public Core core;

public CanvasTab(Core core, String tabTitle){
    this.core = core;
    this.canvas = new Canvas(core.scene.getWidth() - 70, core.scene.getHeight() - 70);
    layout = VBoxBuilder.create().spacing(0).padding(new Insets(10, 10, 10, 10)).children(canvas).build();

    this.g = canvas.getGraphicsContext2D();

    g.setFill(Color.BLACK);
    g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());

    HBox.setHgrow(layout, Priority.ALWAYS);

    this.setContent(layout);
    this.setText(tabTitle);

    canvas.widthProperty().bind(layout.widthProperty().subtract(20));
    canvas.heightProperty().bind(layout.heightProperty().subtract(20));
}

public CanvasTab(Canvas canvas){
    this.canvas = canvas;
}

采纳答案by schauk11erd

As James_D pointed out, you need to redraw the content of your canvas when resizing. This can be done by adding a listener to your canvas' width and height property as follows:

正如 James_D 指出的那样,您需要在调整大小时重新绘制画布的内容。这可以通过向画布的宽度和高度属性添加一个侦听器来完成,如下所示:

InvalidationListener listener = new InvalidationListener(){
    @Override
    public void invalidated(Observable o) {
        redraw();       
    }           
});
canvas.widthProperty().addListener(listener);
canvas.heightProperty().addListener(listener);

or in Java 8 using functional interfaces:

或在 Java 8 中使用函数式接口:

canvas.widthProperty().addListener(observable -> redraw());
canvas.heightProperty().addListener(observable -> redraw());

where redraw()is your own method which would look like this for your example (drawing a black rectangle:

redraw()对于您的示例,您自己的方法在哪里(绘制一个黑色矩形:

private void redraw() {
    g.setFill(Color.BLACK);
    g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
}

回答by schauk11erd

To make a JavaFx canvas resizable all that needs to be done is override the min/pref/max methods. Make it resizable and implement the resize method.

要使 JavaFx 画布可调整大小,所需要做的就是覆盖 min/pref/max 方法。使其可调整大小并实现调整大小方法。

With this method no width/height listeners are necessary to trigger a redraw. It is also no longer necessary to bind the size of the width and height to the container.

使用此方法不需要宽度/高度侦听器来触发重绘。也不再需要将宽度和高度的大小绑定到容器。

public class ResizableCanvas extends Canvas {

@Override
public double minHeight(double width)
{
    return 64;
}

@Override
public double maxHeight(double width)
{
    return 1000;
}

@Override
public double prefHeight(double width)
{
    return minHeight(width);
}

@Override
public double minWidth(double height)
{
    return 0;
}

@Override
public double maxWidth(double height)
{
    return 10000;
}

@Override
public boolean isResizable()
{
    return true;
}

@Override
public void resize(double width, double height)
{
    super.setWidth(width);
    super.setHeight(height);
    paint();
}

Note that the resize method cannot simply call Node.resize(width,height), because the standard implementation is effectivele empty.

请注意,resize 方法不能简单地调用 Node.resize(width,height),因为标准实现实际上是空的。