我正在将一些代码从Java移植到Scala,并且在尝试“橡皮筋”时遇到绘制人工制品的问题 - 即绘制一个随鼠标指针移动的矩形。
这在Java2D中相对简单,但是我在使用Scala / JavaFX时遇到了问题。
我在OS / X 10.8.4上使用Scala 2.10.2,JavaFX 2.2.0-b21和Java 1.7.0_06 Java HotSpot(TM)64位服务器VM。
graphicsContext2D.globalBlendMode = BlendMode.DIFFERENCE似乎等同于Graphics2D.setXORMode(),它几乎可以工作,但它:
最后一项不是我的预期,但我想我明白它在做什么(将Canvas中的未定义背景视为黑色,以便在绘制时将XOR设置为白色,并在未绘制时将其设置为黑色,即使它看起来是绿色的。)
这是一个显示问题的测试用例:
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.scene.paint.Color
import scalafx.Includes._
import scalafx.scene.canvas.{GraphicsContext, Canvas}
import scalafx.scene.layout.Pane
import scalafx.scene.input._
import scalafx.geometry.Rectangle2D
import scalafx.scene.transform.Affine
import scalafx.scene.effect.BlendMode
object Dragger {
var startX: Double = 0.0
var startY: Double = 0.0
var oldRectangle: Rectangle2D = null
def mouseReleased(event: MouseEvent) {
}
def mousePressed(event: MouseEvent) {
startX = event.x
startY = event.y
}
def mouseDragged(g2: GraphicsContext, event: MouseEvent) {
if (oldRectangle != null)
drawRectangle(g2, oldRectangle)
val x0 = math.min(startX, event.x)
val y0 = math.min(startY, event.y)
val newRectangle = new Rectangle2D(x0, y0, math.abs(event.x - startX), math.abs(event.y - startY))
drawRectangle(g2, newRectangle)
oldRectangle = newRectangle
}
def drawRectangle(g2: GraphicsContext, r: Rectangle2D) {
//g2.strokeRect(r.minX, r.minY, r.width, r.height) // <--- stroke instead of fill for grey lines that don't undraw
g2.fillRect(r.minX, r.minY, r.width, r.height)
}
}
object Test extends JFXApp
{
println("javafx.runtime.version: " + System.getProperties.get("javafx.runtime.version"))
println("java.runtime.version: " + System.getProperties.get("java.runtime.version"))
stage = new JFXApp.PrimaryStage {
title = "Hello Stage"
width = 600
height = 472
scene = new Scene {
fill = Color.LIGHTGREEN
root = new Pane {
content = new Canvas(600, 450) {
graphicsContext2D.setStroke(Color.BLUE)
graphicsContext2D.setFill(Color.BLUE)
graphicsContext2D.fillRect(4, 4, 592, 442)
graphicsContext2D.setTransform(new Affine)
graphicsContext2D.globalBlendMode = BlendMode.DIFFERENCE
graphicsContext2D.setStroke(Color.WHITE)
graphicsContext2D.setFill(Color.WHITE)
graphicsContext2D.setLineWidth(1) // <--- increase line width to 2 to fix stroked line undrawing
onMouseDragged = (event: MouseEvent) => {
Dragger.mouseDragged(graphicsContext2D, event)
}
onDragDetected = (event: MouseEvent) => {
//Drag complete
}
onMousePressed = (event: MouseEvent) => {
Dragger.mousePressed(event)
}
onMouseReleased = (event: MouseEvent) => {
Dragger.mouseReleased(event)
}
}
}
}
}
}
此屏幕截图显示了重复移动鼠标后出现的问题(通过划线和2像素线宽):
非常感谢任何帮助。
答案 0 :(得分:1)
您可以使用JavaFX功能而不是使用矩形移动自己。
您可以使用矩形的setTranstalteX()
和setTranslateY()
方法。请参阅Ensemble示例 - &gt; Graphics - &gt; Transforms - &gt; Translate中的Oracle示例。
这里还有The Ensemble的代码:
public class TranslateSample extends Application {
private void init(Stage primaryStage) {
Group root = new Group();
primaryStage.setResizable(false);
primaryStage.setScene(new Scene(root, 230,220));
//create 2 rectangles with different color
Rectangle rect1 = new Rectangle(90, 90, Color.web("#ed4b00", 0.75));
Rectangle rect2 = new Rectangle(90, 90, Color.web("#ed4b00", 0.5));
//translate second one
rect2.setTranslateX(140);
// rectangle with adjustable translate
Rectangle rect3 = new Rectangle(40, 130, 60, 60);
rect3.setFill(Color.DODGERBLUE);
rect3.setTranslateX(20);
rect3.setTranslateY(10);
//show the rectangles
root.getChildren().addAll(rect2, rect1, rect3);
//create arrow
Polygon polygon = createArrow();
polygon.setLayoutX(110);
polygon.setLayoutY(30);
polygon.setRotate(90);
root.getChildren().addAll(polygon);
}
public static Polygon createArrow() {
Polygon polygon = new Polygon(new double[]{
7.5, 0,
15, 15,
10, 15,
10, 30,
5, 30,
5, 15,
0, 15
});
polygon.setFill(Color.web("#ff0900"));
return polygon;
}
public double getSampleWidth() { return 230; }
public double getSampleHeight() { return 220; }
@Override public void start(Stage primaryStage) throws Exception {
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args) { launch(args); }
}