I'm porting some code from Java to Scala and having problems with drawing artefacts when attempting "rubber banding" - ie drawing a rectangle that moves with the mouse pointer.
This was relatively simple to do in Java2D, but I'm having problems making it work in Scala/JavaFX.
I'm using Scala 2.10.2, JavaFX 2.2.0-b21 and , Java 1.7.0_06 Java HotSpot(TM) 64-Bit Server VM on OS/X 10.8.4.
graphicsContext2D.globalBlendMode = BlendMode.DIFFERENCE seems equivalent to Graphics2D.setXORMode() and it almost works, but it:
The last item isn't what I expected, but I think I understand what it is doing (treating the undefined background in the Canvas as black, so that it XORs to white on draw, and black on undraw, even though it looked green to start with.)
This is a test case that shows the problem:
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)
}
}
}
}
}
}
This screenshot shows the problem (this is with stroking and a 2 pixel line width) after moving the mouse around repeatedly:
Any help would be greatly appreciated.
You can use the JavaFX capabilities instead of doing the rectangle move your self. you can use the setTranstalteX()
and setTranslateY()
method of the rectangle. see Oracle example in the Ensemble Sample-->Graphics-->Transforms-->Translate. Here also the code from 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); }
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.