2014-11-22 100 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