2014-11-22 141 views
1

我正在編寫一個應用程序(基本上)模仿MS Paint的過程;您可以選擇鉛筆工具,並繪製一個筆劃爲3的線;您可以選擇標記工具並繪製一條線條,筆畫爲7等。圍繞畫布繪製邊框

我想要在我的畫布周圍繪製邊框。這很簡單,是的。但是,通過其他方法,我可以考慮實現這一點的唯一方法是在繪製邊框後進行大量斑點檢查。有沒有一種有效的方式來做到這一點,而不會與已經選擇的工具的筆觸/顏色衝突?

這裏是drawBorder()方法:

private void drawBorder(GraphicsContext g) { 
    final double canvasWidth = g.getCanvas().getWidth(); 
    final double canvasHeight = g.getCanvas().getHeight(); 

    g.setStroke(Color.BLACK); 
    g.setLineWidth(4); 
    g.strokeRect(0, 0, canvasWidth, canvasHeight); 

    //sets the color back to the currently selected ColorPicker color 
    g.setStroke(selectedColor); 
} 

然而,這個代碼將與我clear()行動

clearTool.setOnAction(e -> { 
      graphics.clearRect(0, 0, 
       canvas.getWidth(), canvas.getHeight()); 
      drawBorder(graphics); 
     }); 

後因畫布的結算相沖突,所以筆畫線寬度爲4。這是一個問題,因爲如果我選擇了鉛筆工具作爲選定的工具(筆劃線寬爲3),那麼將會是4,直到我選擇另一個工具並切換回鉛筆工具;此外,如果在按下清除按鈕時選擇了標記工具,則同樣的概念適用(筆劃線寬7將爲4,直到我選擇另一個工具,然後重新選擇標記工具)。

我試圖避免必須設置每個工具的檢查,並讓它每次都重置筆劃的線寬 - 雖然這會工作,但似乎令人費解。

回答

3

考慮將畫布放在窗格中,並使用CSS來設置窗格的樣式。例如:

import javafx.application.Application; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.control.Button; 
import javafx.scene.layout.Priority; 
import javafx.scene.layout.StackPane; 
import javafx.scene.layout.VBox; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 

public class CanvasWithBorderExample extends Application { 

    @Override 
    public void start(Stage primaryStage) { 

     final int SIZE = 400 ; 
     Canvas canvas = new Canvas(SIZE, SIZE); 

     GraphicsContext gc = canvas.getGraphicsContext2D() ; 
     gc.setStroke(Color.RED); 
     gc.moveTo(0, 0); 
     gc.lineTo(SIZE, SIZE); 
     gc.stroke(); 

     StackPane canvasContainer = new StackPane(canvas); 
     canvasContainer.getStyleClass().add("canvas"); 

     VBox root = new VBox(10, canvasContainer, new Button("Click here")); 
     root.setFillWidth(false); 
     VBox.setVgrow(canvasContainer, Priority.NEVER); 
     root.setAlignment(Pos.CENTER); 

     Scene scene = new Scene(root); 
     scene.getStylesheets().add("canvas-with-border.css"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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

用帆布帶,border.css:

.canvas { 
    -fx-background-color: antiquewhite, white ; 
    -fx-background-insets: 0, 20 ; 
    -fx-padding: 20 ; 
} 
1

編輯:我很快就將Swing Canvas知識應用到JavaFX。如果您在JavaFX中使用resizable Canvas,則仍然需要按照以下說明進行操作。 如果不是,我可能會使用Oracle的Java tutorial中描述的圖層方法。


如果我理解正確,那麼在我看來你有一個不正確的做法。例如,假設您在用戶繪製鉛筆時直接繪製到「畫布」中。這是不正確的。 畫布可以隨時要求您重畫它,並且您必須爲此做好準備。

也就是說,在離屏的GraphicsContext中執行用戶繪圖,並使用自己的設置,以保持與用戶選擇的工具一致。 然後,在您的Canvas paint()方法中,將該上下文的內容複製到Canvas。如果你喜歡的話,那時你還可以添加自己的邊框或其他註釋。

可能是因爲您已經使用了屏幕外繪圖並希望將邊框繪製到屏幕外緩衝區中(例如,由於用戶的「添加邊框」操作)。然後查看GraphicsContext的save()和restore()方法。它們可以保存狀態,更改設置,執行繪圖,然後恢復舊狀態。

+0

在哪裏有,我可以看到這樣的例子嗎? – Nxt3 2014-11-23 17:32:32

+1

JavaFX中沒有'Canvas.paint()'方法。 – 2014-11-23 18:33:08

+1

@James_D啊,我的錯。改編了答案。 – fishinear 2014-11-23 18:59:20