JavaFX-изменение размера холста при изменении размера экрана

Я работаю над GUI моего редактора уровней, который я построил в JavaFX, и я хочу иметь возможность изменять размер объекта canvas до новых размеров разделенной панели. Похоже, все, что я пытался сделать, провалилось. Это включает в себя передачу объекта панели и использование его ширины напрямую, используя прослушиватели размера окна и привязку свойства width и height к свойству split pane. Любая идея. Это то, что он выглядит как перед изменением размера:

enter image description here

и после размер:

enter image description here

есть ли у кого-нибудь идеи. Код для класса довольно обширен, но код для изменения размера будет включен.

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;
}

2 ответов


как указал James_D, вам нужно перерисовать содержимое вашего холста при изменении размера. Это можно сделать, добавив прослушиватель к свойству ширины и высоты вашего холста следующим образом:

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

или в Java 8 с помощью функционального интерфейса:

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

здесь redraw() Это ваш собственный метод, который будет выглядеть так для вашего примера (рисование черного прямоугольника:

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

чтобы сделать холст 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();
}

обратите внимание, что метод resize не может просто вызвать узел.изменение размера (ширина, высота), поскольку стандартная реализация effectivele пустой.