当前位置: 首页 > 知识库问答 >
问题:

如何在javaFX中调整画布的大小?

庄萧迟
2023-03-14

在javaFX中,调整画布大小没有这样的方法,唯一的解决方案是从画布扩展。

class ResizableCanvas extends Canvas {

    public ResizableCanvas() {
        // Redraw canvas when size changes.
        widthProperty().addListener(evt -> draw());
        heightProperty().addListener(evt -> draw());
    }

    private void draw() {
        double width = getWidth();
        double height = getHeight();

        GraphicsContext gc = getGraphicsContext2D();
        gc.clearRect(0, 0, width, height);

    }

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

“从画布扩展”是使画布可调整大小的唯一解决方案吗?因为这个解决方案只有在我们不想使用FXML的情况下才起作用,如果我们在FXML中声明一个画布,我们如何使它可以调整大小?

这是我的代码:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Main extends Application {

    Controller controller;

    @Override
    public void start(Stage primaryStage) throws Exception{
        FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
        AnchorPane root = loader.load(); // controller initialized
        controller = loader.getController();
        GraphicsContext gc = controller.canvas.getGraphicsContext2D();
        gc.setFill(Color.AQUA);
        gc.fillRect(0, 0, root.getPrefWidth(), root.getPrefHeight());
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(controller.Pane, controller.Pane.getPrefWidth(), controller.Pane.getPrefHeight()));
        primaryStage.show();
    }

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

共有3个答案

牧献
2023-03-14

取自http://werner.yellowcouch.org/log/resizable-javafx-canvas/:要使JavaFx画布可调整大小,只需重写min/pref/max方法。使其可调整大小并实现resize方法。

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

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>
}
广晔
2023-03-14

在给出的所有答案中,没有一个在让画布与其父画布自动调整大小方面对我有效。我决定尝试一下,这就是我想到的:

import javafx.scene.canvas.Canvas;

public class ResizableCanvas extends Canvas {

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

    @Override
    public double maxHeight(double width) {
        return Double.POSITIVE_INFINITY;
    }

    @Override
    public double maxWidth(double height) {
        return Double.POSITIVE_INFINITY;
    }

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

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

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

这是唯一一个真正使画布可调整大小的方法。

我采用这种方法的理由如下:

  • 我不想通过强制父组件在构造函数中向我们发送宽度高度来破坏封装,这也意味着画布不能在FXML中使用。
  • 我也不想依赖于父节点的宽度和高度属性,从而通过占用所有空间使画布成为父节点中唯一的子节点。
  • 最后,画布需要在另一个类中绘制,这意味着我不能使用当前接受的答案,其中也包括通过绘制方法绘制到画布。

有了这个画布,我不需要绑定到它的父宽度/高度属性来调整画布的大小。它只是根据父级选择的大小调整大小。此外,任何使用画布的人都可以绑定到其宽度/高度属性,并在这些属性更改时管理自己的绘图。

蒙峰
2023-03-14

我认为有一个指南对设置可调整大小的画布很有用:

JavaFx提示-可调整大小的画布

指南中的一段代码:

/**
 * Tip 1: A canvas resizing itself to the size of
 *        the parent pane.
 */
public class Tip1ResizableCanvas extends Application {

    class ResizableCanvas extends Canvas {

        public ResizableCanvas() {
            // Redraw canvas when size changes.
            widthProperty().addListener(evt -> draw());
            heightProperty().addListener(evt -> draw());
        }

        private void draw() {
            double width = getWidth();
            double height = getHeight();

            GraphicsContext gc = getGraphicsContext2D();
            gc.clearRect(0, 0, width, height);

            gc.setStroke(Color.RED);
            gc.strokeLine(0, 0, width, height);
            gc.strokeLine(0, height, width, 0);
        }

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

        @Override
        public double prefWidth(double height) {
            return getWidth();
        }

        @Override
        public double prefHeight(double width) {
            return getHeight();
        }
    }
 类似资料:
  • 我有一个问题已经部分解决了,但我很好奇另一个(更好的)解决方法…我想要一个画布,什么填充整个窗口,并调整自己的大小,如果窗口的大小。 根据这个:https://dlemmermann.wordpress.com/2014/04/10/javafx-tip-1-resizable-canvas/和这个:如何在JavaFX中使canvas可调整大小?我已创建(复制)类: 并将以下内容放入viewfie

  • 下面是和,我试图使它尽可能简单。 黑色是名为的,其内部是名为的。我要做的是将中的的大小调整为的大小减去4。但当您调整窗口大小时,一切都失败了。 你要尝试的... 2)增加窗口的大小,然后慢慢减小。 为什么会这样?我有这个问题三个月了,但我找不到解决办法... 我也看过javafx-resize Canvas,当屏幕调整大小时,但这里的问题似乎是不同的... 如果我不手动设置画布的宽度和高度,它甚至

  • 一直以来,我都在开发一款分辨率为800x480(流行手机分辨率)的应用程序。 我的画布HTML: 现在,为了使其全屏显示其他分辨率,我在调整大小事件后执行以下操作: 这是可行的,但问题是我不能以这种方式保持纵横比。800x480是4:3,但是如果我在5:3的手机上运行这个应用程序,有些东西(尤其是圆圈)看起来会被拉伸。 有没有什么方法可以让它在所有分辨率下看起来都很好,而不必为每个纵横比创建一组独

  • 我一直在尝试对JavaFX阶段进行缩放转换,以替换应用程序主窗口的当前场景(在本例中为登录帧)。 当发生这种情况时,由于新场景更大,窗口的大小会以一种不优雅的方式突然被重新调整。

  • 我正在使用NetBeans GUI编辑器创建一个应用程序,其中我想要一个,其顶部组件将是中的和底部组件将是,或类似的东西。 当我向下拉分隔符,从而增加顶部组件的大小时,所有东西的大小似乎都调整得很好。 当我尝试向上推动分隔符时,问题就出现了:分隔符似乎位于下方(也可能位于下方)。 我尝试了和的首选/最小/最大大小的各种组合,但似乎都不起作用。 这是 Netbeans 生成的代码中可能与手头的问题有

  • 本文档概述了您可以用来调整图像的裁剪、旋转和画布大小的各种方法。 使用裁剪命令裁剪图像 使用选区工具来选择要保留的图像部分。 选取“图像”>“裁剪”。 使用裁切命令裁剪图像 “裁切”命令通过移去不需要的图像数据来裁剪图像,其所用的方式与“裁剪”命令所用的方式不同。可以通过裁切周围的透明像素或指定颜色的背景像素来裁剪图像。 选取“图像”>“裁切”。 在“裁切”对话框中选择选项: “透明像素”修整掉图