[英]JavaFX: canvas improperly resized while in the TabsPane
我正在嘗試創建一個使用JavaFX for GUI的應用程序。 主窗口具有一組選項卡,其中一個選項卡具有用於可視化的畫布。 我已經注意到,調整畫布的大小不是一件容易的事,並且有很多技巧和問題與此相關。
我以這段代碼為例。 它工作正常,直到我嘗試將其放入TabsPane中為止。 當我放大窗口時,圖像也會放大,但是當我推開窗口時,畫布不會閃爍! 此外,選項卡頂部的面板也不會收縮。
這是演示此問題的窗口的屏幕截圖:
這是代碼:
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/**
* 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();
}
}
@Override
public void start(Stage stage) throws Exception {
TabPane tabs = new TabPane();
Tab tab = new Tab("tab", createNewTaskArea());
tabs.getTabs().add(tab);
stage.setScene(new Scene(tabs, 500, 500));
stage.setTitle("Tip 1: Resizable Canvas");
stage.show();
}
private Pane createNewTaskArea() {
Label newTaskNameQuery = new Label("Task name:");
TextField newTaskName = new TextField("Untitled task");
newTaskNameQuery.setLabelFor(newTaskName);
GridPane topPane = new GridPane();
topPane.setPadding(new Insets(5));
topPane.setHgap(5);
topPane.setVgap(10);
topPane.add(newTaskNameQuery, 0, 0);
topPane.add(newTaskName, 1, 0);
GridPane.setHalignment(newTaskNameQuery, HPos.RIGHT);
GridPane.setHgrow(newTaskName, Priority.ALWAYS);
ResizableCanvas canvas = new ResizableCanvas();
VBox panel = new VBox();
// Bind canvas size to stack pane size.
panel.widthProperty().addListener(observable -> canvas.setWidth(panel.getWidth()));
panel.heightProperty().addListener(
observable -> canvas.setHeight(panel.getHeight() - topPane.getHeight())
);
panel.getChildren().addAll(topPane, canvas);
return panel;
}
public static void main(String[] args) {
launch(args);
}
}
是否可以使其正常工作?
似乎TabPane會引起問題,因為如果我將其刪除並使該選項卡的內容成為整個窗口的內容,則所有功能都將按我的預期工作。
這是行不通的,因為VBox
減小其大小,就需要減小Canvas
的大小,這不會發生,因為只有在減小VBox
大小時才減小Canvas
大小...
只需將Canvas
放在可調整大小的父級中,為其設置適當的布局參數,然后根據此父級的大小調整Canvas
的大小,就容易得多:
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);
}
}
VBox panel = new VBox();
// parent to be resized
Pane pane = new Pane(canvas);
// grow/shrink pane when VBox height is increased/decreased
VBox.setVgrow(pane, Priority.ALWAYS);
// bind canvas size to parent size
canvas.widthProperty().bind(pane.widthProperty());
canvas.heightProperty().bind(pane.heightProperty());
panel.getChildren().addAll(topPane, pane);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.