Thursday 15 May 2014

javafx - resizable and movable rectangle -



javafx - resizable and movable rectangle -

with next code (thanks several posts here), draw rectangle, want resizable , movable. 2 anchors (the upper left , lower right) want, , lastly 1 (lower middle) moves rectangle, 2 first anchors not follow rectangle.

when create them move, listener of them, resizes rectangle.

package application; import javafx.application.application; import javafx.beans.property.doubleproperty; import javafx.beans.property.simpledoubleproperty; import javafx.beans.value.changelistener; import javafx.beans.value.observablevalue; import javafx.collections.fxcollections; import javafx.collections.observablelist; import javafx.event.eventhandler; import javafx.scene.cursor; import javafx.scene.group; import javafx.scene.scene; import javafx.scene.input.mouseevent; import javafx.scene.paint.color; import javafx.scene.shape.circle; import javafx.scene.shape.rectangle; import javafx.scene.shape.shape; import javafx.scene.shape.stroketype; import javafx.stage.stage; import javafx.stage.stagestyle; public class main extends application { private rectangle rectangle; private grouping group; private scene scene; private stage primarystage; private observablelist<double> coins; public static void main(string[] args) { application.launch(args); } @override public void start(stage primarystage) { grouping = new group(); rectangle = new rectangle(200,200,400,300); coins = fxcollections.observablearraylist(); //upperleft coins.add(rectangle.getx()); coins.add(rectangle.gety()); //lowerright coins.add(rectangle.getx() + rectangle.getwidth()); coins.add(rectangle.gety()+ rectangle.getheight()); //moving coins.add(rectangle.getx() + (rectangle.getwidth()/2)); coins.add(rectangle.gety()+ (rectangle.getheight())); group.getchildren().addall(createcontrolanchorsfor(coins)); group.getchildren().add(rectangle); scene = new scene(group,800,800); primarystage.setscene(scene); primarystage.show(); } //@return list of anchors can dragged around modify points in format [x1, y1, x2, y2...] private observablelist<anchor> createcontrolanchorsfor(final observablelist<double> points) { observablelist<anchor> anchors = fxcollections.observablearraylist(); //coin gauchehaut doubleproperty xproperty = new simpledoubleproperty(points.get(0)); doubleproperty yproperty = new simpledoubleproperty(points.get(1)); xproperty.addlistener(new changelistener<number>() { @override public void changed(observablevalue<? extends number> ov, number oldx, number x) { system.out.println(oldx + " et " + x); rectangle.setx((double) x); rectangle.setwidth((double) rectangle.getwidth() -((double) x- (double) oldx)); anchors.get(2).setcenterx((double) x + rectangle.getwidth()/2 ); } }); yproperty.addlistener(new changelistener<number>() { @override public void changed(observablevalue<? extends number> ov, number oldy, number y) { rectangle.sety((double) y); rectangle.setheight((double) rectangle.getheight() -((double) y- (double) oldy)); } }); anchors.add(new anchor(color.gold, xproperty, yproperty)); //coin droitebas doubleproperty xproperty2 = new simpledoubleproperty(points.get(2)); doubleproperty yproperty2 = new simpledoubleproperty(points.get(3)); xproperty2.addlistener(new changelistener<number>() { @override public void changed(observablevalue<? extends number> ov, number oldx, number x) { rectangle.setwidth((double) rectangle.getwidth() -((double) oldx- (double) x)); anchors.get(2).setcenterx((double) x - rectangle.getwidth()/2 ); } }); yproperty2.addlistener(new changelistener<number>() { @override public void changed(observablevalue<? extends number> ov, number oldy, number y) { rectangle.setheight((double) rectangle.getheight() -((double) oldy- (double) y)); anchors.get(2).setcentery((double) y); } }); anchors.add(new anchor(color.gold, xproperty2, yproperty2)); //moving doubleproperty xpropertym = new simpledoubleproperty(points.get(4)); doubleproperty ypropertym = new simpledoubleproperty(points.get(5)); xpropertym.addlistener(new changelistener<number>() { @override public void changed(observablevalue<? extends number> ov, number oldx, number x) { rectangle.setx((double) x - rectangle.getwidth()/2 ); //anchors.get(0).setcenterx((double) x- rectangle.getwidth()/2); //anchors.get(0).setvisible(false); } }); ypropertym.addlistener(new changelistener<number>() { @override public void changed(observablevalue<? extends number> ov, number oldy, number y) { rectangle.sety((double) y - rectangle.getheight() ); coins.set(1, (double) y); } }); anchors.add(new anchor(color.gold, xpropertym, ypropertym)); homecoming anchors; } //a draggable anchor displayed around point. class anchor extends circle { private final doubleproperty x, y; anchor(color color, doubleproperty x, doubleproperty y) { super(x.get(), y.get(), 20); setfill(color.derivecolor(1, 1, 1, 0.5)); setstroke(color); setstrokewidth(2); setstroketype(stroketype.outside); this.x = x; this.y = y; x.bind(centerxproperty()); y.bind(centeryproperty()); enabledrag(); } //make node movable dragging around mouse. private void enabledrag() { final delta dragdelta = new delta(); setonmousepressed(new eventhandler<mouseevent>() { @override public void handle(mouseevent mouseevent) { // record delta distance drag , drop operation. dragdelta.x = getcenterx() - mouseevent.getx(); dragdelta.y = getcentery() - mouseevent.gety(); getscene().setcursor(cursor.move); } }); setonmousereleased(new eventhandler<mouseevent>() { @override public void handle(mouseevent mouseevent) { getscene().setcursor(cursor.hand); } }); setonmousedragged(new eventhandler<mouseevent>() { @override public void handle(mouseevent mouseevent) { double newx = mouseevent.getx() + dragdelta.x; if (newx > 0 && newx < getscene().getwidth()) { setcenterx(newx); } double newy = mouseevent.gety() + dragdelta.y; if (newy > 0 && newy < getscene().getheight()) { setcentery(newy); } //recompute screen; group.getchildren().add(rectangle); scene = new scene(group,800,800);; primarystage.setscene(scene); } }); setonmouseentered(new eventhandler<mouseevent>() { @override public void handle(mouseevent mouseevent) { if (!mouseevent.isprimarybuttondown()) { getscene().setcursor(cursor.hand); } } }); setonmouseexited(new eventhandler<mouseevent>() { @override public void handle(mouseevent mouseevent) { if (!mouseevent.isprimarybuttondown()) { getscene().setcursor(cursor.default); } } }); } //records relative x , y co-ordinates. private class delta { double x, y; } } }

any idea, , should add together ?

since "handles" in same position relative rectangle, bind position position of rectangle. can accomplish

circle.centerxproperty().bind(...); circle.centeryproperty().bind(...);

where argument observablevalue<number>.

then in dragging handlers, move rectangle required (the computations complex not bad). since positions of circles bound, follow rectangle.

here's 1 possible implementation uses strategy:

import java.util.arrays; import javafx.application.application; import javafx.geometry.point2d; import javafx.scene.cursor; import javafx.scene.scene; import javafx.scene.layout.pane; import javafx.scene.paint.color; import javafx.scene.shape.circle; import javafx.scene.shape.rectangle; import javafx.stage.stage; public class draggingrectangle extends application { public static void main(string[] args) { application.launch(args); } @override public void start(stage primarystage) { pane root = new pane(); rectangle rect = createdraggablerectangle(200, 200, 400, 300); rect.setfill(color.navy); root.getchildren().add(rect); scene scene = new scene(root, 800, 800); primarystage.setscene(scene); primarystage.show(); } private rectangle createdraggablerectangle(double x, double y, double width, double height) { final double handleradius = 10 ; rectangle rect = new rectangle(x, y, width, height); // top left resize handle: circle resizehandlenw = new circle(handleradius, color.gold); // bind top left corner of rectangle: resizehandlenw.centerxproperty().bind(rect.xproperty()); resizehandlenw.centeryproperty().bind(rect.yproperty()); // bottom right resize handle: circle resizehandlese = new circle(handleradius, color.gold); // bind bottom right corner of rectangle: resizehandlese.centerxproperty().bind(rect.xproperty().add(rect.widthproperty())); resizehandlese.centeryproperty().bind(rect.yproperty().add(rect.heightproperty())); // move handle: circle movehandle = new circle(handleradius, color.gold); // bind bottom center of rectangle: movehandle.centerxproperty().bind(rect.xproperty().add(rect.widthproperty().divide(2))); movehandle.centeryproperty().bind(rect.yproperty().add(rect.heightproperty())); // forcefulness circles live in same parent rectangle: rect.parentproperty().addlistener((obs, oldparent, newparent) -> { (circle c : arrays.aslist(resizehandlenw, resizehandlese, movehandle)) { pane currentparent = (pane)c.getparent(); if (currentparent != null) { currentparent.getchildren().remove(c); } ((pane)newparent).getchildren().add(c); } }); wrapper<point2d> mouselocation = new wrapper<>(); setupdragging(resizehandlenw, mouselocation) ; setupdragging(resizehandlese, mouselocation) ; setupdragging(movehandle, mouselocation) ; resizehandlenw.setonmousedragged(event -> { if (mouselocation.value != null) { double deltax = event.getscenex() - mouselocation.value.getx(); double deltay = event.getsceney() - mouselocation.value.gety(); double newx = rect.getx() + deltax ; if (newx >= handleradius && newx <= rect.getx() + rect.getwidth() - handleradius) { rect.setx(newx); rect.setwidth(rect.getwidth() - deltax); } double newy = rect.gety() + deltay ; if (newy >= handleradius && newy <= rect.gety() + rect.getheight() - handleradius) { rect.sety(newy); rect.setheight(rect.getheight() - deltay); } mouselocation.value = new point2d(event.getscenex(), event.getsceney()); } }); resizehandlese.setonmousedragged(event -> { if (mouselocation.value != null) { double deltax = event.getscenex() - mouselocation.value.getx(); double deltay = event.getsceney() - mouselocation.value.gety(); double newmaxx = rect.getx() + rect.getwidth() + deltax ; if (newmaxx >= rect.getx() && newmaxx <= rect.getparent().getboundsinlocal().getwidth() - handleradius) { rect.setwidth(rect.getwidth() + deltax); } double newmaxy = rect.gety() + rect.getheight() + deltay ; if (newmaxy >= rect.gety() && newmaxy <= rect.getparent().getboundsinlocal().getheight() - handleradius) { rect.setheight(rect.getheight() + deltay); } mouselocation.value = new point2d(event.getscenex(), event.getsceney()); } }); movehandle.setonmousedragged(event -> { if (mouselocation.value != null) { double deltax = event.getscenex() - mouselocation.value.getx(); double deltay = event.getsceney() - mouselocation.value.gety(); double newx = rect.getx() + deltax ; double newmaxx = newx + rect.getwidth(); if (newx >= handleradius && newmaxx <= rect.getparent().getboundsinlocal().getwidth() - handleradius) { rect.setx(newx); } double newy = rect.gety() + deltay ; double newmaxy = newy + rect.getheight(); if (newy >= handleradius && newmaxy <= rect.getparent().getboundsinlocal().getheight() - handleradius) { rect.sety(newy); } mouselocation.value = new point2d(event.getscenex(), event.getsceney()); } }); homecoming rect ; } private void setupdragging(circle circle, wrapper<point2d> mouselocation) { circle.setondragdetected(event -> { circle.getparent().setcursor(cursor.closed_hand); mouselocation.value = new point2d(event.getscenex(), event.getsceney()); }); circle.setonmousereleased(event -> { circle.getparent().setcursor(cursor.default); mouselocation.value = null ; }); } static class wrapper<t> { t value ; } }

javafx anchor rectangles

No comments:

Post a Comment