2016-06-07 55 views
1

我正在嘗試使用JavaFX製作應用程序。如何將JavaFX Canvas嵌入到BorderPane中?

我想要製作的是窗口頂部爲MenuBar,中心爲Canvas。 我也希望窗口能夠調整大小。 參照下面的鏈接,其示出了如何使Canvas可調整大小,我首先提出了以下的代碼:

JavaFX Tip 1: Resizable Canvas – DLSC

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.control.Menu; 
import javafx.scene.control.MenuBar; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 

public class CanvasInBorderPane extends Application { 

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

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     BorderPane borderPane = new BorderPane(); 

     // Put menu bar on the top of the window 
     MenuBar menuBar = new MenuBar(new Menu("File"), new Menu("Edit"), 
       new Menu("Help")); 
     borderPane.setTop(menuBar); 

     // Put canvas in the center of the window (*) 
     Canvas canvas = new Canvas(); 
     borderPane.setCenter(canvas); 
     // Bind the width/height property so that the size of the Canvas will be 
     // resized as the window is resized 
     canvas.widthProperty().bind(borderPane.widthProperty()); 
     canvas.heightProperty().bind(borderPane.heightProperty()); 
     // redraw when resized 
     canvas.widthProperty().addListener(event -> draw(canvas)); 
     canvas.heightProperty().addListener(event -> draw(canvas)); 
     draw(canvas); 

     Scene scene = new Scene(borderPane); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    /** 
    * Draw crossed red lines which each each end is at the corner of window, 
    * and 4 blue circles whose each center is at the corner of the window, 
    * so that make it possible to know where is the extent the Canvas draws 
    */ 
    private void draw(Canvas canvas) { 
     int width = (int) canvas.getWidth(); 
     int height = (int) canvas.getHeight(); 
     GraphicsContext gc = canvas.getGraphicsContext2D(); 
     gc.clearRect(0, 0, width, height); 
     gc.setStroke(Color.RED); 
     gc.strokeLine(0, 0, width, height); 
     gc.strokeLine(0, height, width, 0); 
     gc.setFill(Color.BLUE); 
     gc.fillOval(-30, -30, 60, 60); 
     gc.fillOval(-30 + width, -30, 60, 60); 
     gc.fillOval(-30, -30 + height, 60, 60); 
     gc.fillOval(-30 + width, -30 + height, 60, 60); 
    } 
} 

然後我等(1)的窗口(見下圖)。

我知道這是因爲實際尺寸Canvas應該小於borderPane的尺寸。但我不知道如何獲得BorderPane的CENTER區域。

我然後試圖把一個包裝PaneborderPane的中心並嵌入Canvas進去,包裝Pane的寬度和高度結合Canvas。我改變了10+線以上用於初始化Canvas(從註釋行開始(*))的代碼如下:

 // Create a wrapper Pane first 
     BorderPane wrapperPane = new BorderPane(); 
     borderPane.setCenter(wrapperPane); 
     // Put canvas in the center of the window 
     Canvas canvas = new Canvas(); 
     wrapperPane.setCenter(canvas); 
     // Bind the width/height property to the wrapper Pane 
     canvas.widthProperty().bind(wrapperPane.widthProperty()); 
     canvas.heightProperty().bind(wrapperPane.heightProperty()); 
     // redraw when resized 
     canvas.widthProperty().addListener(event -> draw(canvas)); 
     canvas.heightProperty().addListener(event -> draw(canvas)); 
     draw(canvas); 

然後奇怪的事情發生。當我增加了窗戶的寬度時,我認爲一切都很順利。 (圖片(2))

但是,雖然我減少了寬度,但Canvas的寬度不會減小,換句話說,適合窗口的大小。 (圖(3))

高度也是如此。

有沒有人有辦法解決這個問題? 我的Java版本是1.8.0_71。

The screenshots of the window

回答

3

使用普通Pane包裹畫布上,而不是BorderPane

// Create a wrapper Pane first 
    Pane wrapperPane = new Pane(); 
    borderPane.setCenter(wrapperPane); 
    // Put canvas in the center of the window 
    Canvas canvas = new Canvas(); 
    wrapperPane.getChildren().add(canvas); 
    // Bind the width/height property to the wrapper Pane 
    canvas.widthProperty().bind(wrapperPane.widthProperty()); 
    canvas.heightProperty().bind(wrapperPane.heightProperty()); 
    // redraw when resized 
    canvas.widthProperty().addListener(event -> draw(canvas)); 
    canvas.heightProperty().addListener(event -> draw(canvas)); 
    draw(canvas);