Is there a simple way to select and move (rotate, pan, zoom) multiple shapes in Java3D simultaneously? I've seen the examples where you can pick (click) a single shape and drag it, but I haven't been able to find an easy way to select and move multiple shapes.
What I want to be able to do is:
Have many unselected shapes on the screen
Select one or more shapes (by individually clicking or dragging a box)
Move only the selected shapes with a mouse listener
When the shapes are unselected, they should stay where they are and stop moving
When new shapes are added, they should stay where they are and start moving
My initial idea was to have 2 Branch Groups "Selected" and "Unselected". The Selected BranchGroup would have a parent TransformGroup that is attached to the root, the Unselected BranchGroup would be attached directly to the root. As items were selected (which I can do with a PickCanvas) they would be removed from the Unselected BG and put in the Selected BG.
The main problem with this is that the shapes jump when they are selected or unselected. This is because they are taking on the transform of the group they are going to.
I feel like there is probably some easier way to do this, maybe leveraging something that is built into Java3D.
The best way I figured out how to do this was to use the 2 Branch Group method I suggested in the initial question.
You create 2 Branch Groups, one for selected nodes and one for unselected nodes. When you move nodes from one group to the other, you must translate the individual nodes so they remain at their current position rather than jumping to the translation of the new branch group they are joining.
Related
In my program I have styled my buttons using css. I am using "-fx-background-radius" to round the corners and have noticed that when I hover over where the corners used to be it allows me to click the button. I was just wondering if there is a way to make it so that the 'hit-box' for the button matches what you see.
Thank you.
The pickOnBounds property
Defines how the picking computation is done for this node when triggered by a MouseEvent or a contains function call. If pickOnBounds is true, then picking is computed by intersecting with the bounds of this node, else picking is computed by intersecting with the geometric shape of this node.
The "bounds" are essentially the rectangular region containing the node (button in this case). The "geometric shape" accounts for how the node is actually rendered.
So you just need to call setPickOnBounds(false) on the button.
I have a game that is played in a 2D-world and I am currently working on the world editor. The editor draws the elements of the map as JavaFX Rectangles and Lines in a JavaFX Group. While the world can be infinitly big, the Group-node that I use to draw the map in shrinks to the minimal size required by the map.
To enable the user to pan through the map of the world, I wrapped the JavaFX Group in a ScrollPane. That actually works but the ScrollPane pulls the Group into its upper left corner like this:
That means that the user can scroll down or to the right if there are elements of the map below or on the right of the current viewport, but the user can only scroll up until the upper-left element of the map is in the upper left corner of the ScrollPane. That is actually useful for usual content (you don't want to scroll beyond the top of a web page or a menu) but I want the user to be able to scroll even beyond that even if there are no map elements (that's what I meant by an infinite drawing plane before doing the edit):
(quick and dirty photoshop)
I already tried to center the group using this solution but it resulted in the shapes dancing around the center of the window when manipulating them.
Edit:
Made the question a bi´t clearer (hopefully ^^ )
Is there a way to allow the user to draw individually selectable, movable, and re-sizable shapes within JavaFX and/or canvas that I am not considering or aware of?
I am new to JavaFX (Java GUIs in general, actually) and am trying to devise a method of allowing a user to draw (click & drag) up to 100 rectangles on a pane/workspace/page. I am also looking for a method to make this scalable, but keeping static proportions for now will be fine. I have not found a great deal of comparable examples in my search, most of which explore only one of those options but leave out certain things I need to accomplish. Usually they show pre-defined nodes or canvas shapes that aren't individually workable. So I am trying to find the best method to accomplish this.
Drawing the shapes is NOT the issue, I know how to do that. It's making them individual objects within the workspace (selectable, movable, re-sizable).
My current idea is to create a Javafx pane, then create 100 canvases within the pane as predefined layers which will be the same dimensions as the entire workspace. Each drawn rectangle will occupy one of the layers/canvas. Selecting each rectangle will involve a click event within the drawn rectangle within the layer allowing the user to edit the, (move, re-size, etc.)
The following Oracle tutorial is what I am going off of for this method of layering. http://docs.oracle.com/javafx/2/canvas/jfxpub-canvas.htm
I have the feeling that my working premise for this method is flawed. One reason is it requires pre-defined number of layers. Although I want to limit this anyway, it is not very dynamic. But mostly, it just seems convoluted.
My apologies for the lack of code, and for the the conceptual nature of the question, but I've been searching and experimenting (unsuccessfully) for a couple weeks. Any help or insight would be appreciated.
Thank You
Project Context
I'm creating a basic form creator. The user (in creation mode) will drag a series of rectangles that are associated with corresponding objects indicating certain attributes, coordinates, and dimensions of each rectangle. This data will be saved and used (in form mode) for the placement of text fields for form use. Wherever rectangle were drawn on the workspace, text fields of the same location and dimension will be placed on the form.
The easiest method I can think of is by making a group, and adding rectangles to the group, on-demand. You can then attach transforms and mouselisteners to each rectangle, and have it so that the properties of the transform is updated when a drag is detected. I've put together a simple demo here. Use a right-click to make a rectangle, left mouse drag to resize, and middle mouse drag to move the rectangle.
Group root = new Group();
Scene scene = new Scene(root, 1080, 720, true);
scene.addEventFilter(MouseEvent.MOUSE_PRESSED,e->{
if(e.getButton()==MouseButton.SECONDARY)
{
//make a new rectangle
Rectangle rect = new Rectangle(100,100);
root.getChildren().add(rect);
rect.setFill(Color.CYAN);
Scale scaler = new Scale(1,1);
Translate locationCenter = new Translate(e.getX(),e.getY());
rect.getTransforms().add(locationCenter);
rect.getTransforms().add(scaler);
rect.getTransforms().add(new Translate(-50,-50));
//listen for left mouse drags
rect.addEventFilter(MouseEvent.MOUSE_DRAGGED, e2->{
if(e2.getButton()==MouseButton.PRIMARY)
{
//resize with left drag
double scaleX=e2.getSceneX()-rect.localToParent(0,0).getX();
double scaleY=e2.getSceneY()-rect.localToParent(0,0).getY();
scaler.setX(scaleX/100);
scaler.setY(scaleY/100);
} else if(e2.getButton()==MouseButton.MIDDLE)
{
//move with middle drag
locationCenter.setX(e2.getSceneX());
locationCenter.setY(e2.getSceneY());
}
});
}
});
So I am trying to create a 2D side-scrolling javafx game.
So far I used AnimationTimer to control movement of my character. But now I am kind of stuck trying to make the stage move.
I can move non-interactive elements using AnimationTimer again. But I am lacking an idea for how should I generate interactive elements in game.
For example, lets say player walks a lot of steps and reaches to take a pickup. Now how do I put this pickup in stage so it is somewhere later in game. To try explain my problem better, consider this pesky image I drew in paint:
Initially, only the screen between green bounds is visible to player. The player must walk forward (and hence the screen must walk forward too) and should find that pickup between two walls. How do I place pickup outside scene's visible view so it comes into view only when player reaches it?
The easy way: You add everything to the scene and give it absolute coordinates. You move the player by changing its coordinates in the scene. Depending on the position of the player you start scrolling. While you scroll the background you also move all other objects about the same x and y coordinates. The visible view has a given width and height. Depending on the player's position, view width/height and object range the objects become visible during scrolling.
I want to have something like this five buttons, one button surrounded by four other buttons. Just like this:
I know that with Android that we can only have square type views so how would it be possible to do this? OpenGl or something? Anyone have any links to something related? Basically I want curved buttons that are close together.
My guess is that at the end of the day it will be easier to do this in a custom view.
But if you want to use stock views, I'd suggest the following. First, use a RelativeLayout container to arrange the four outside buttons in a 2x2 grid. Then position the center button so it overlaps the grid in the center. Put the center button at a higher Z (closer to the user) than the four surrounding buttons. Then use transparency as part of the button images to get them to look like you want. Then (hopefully) try it out. If the Z order is right, the center button will capture taps that would otherwise have gone to one of the other four buttons.
This actually won't work as is, because the center button square will intrude into the surrounding squares. I don't know if it would work, but you can then try replacing the center button with another grid of button "pieces". The grid would have empty positions except where the center button image overlaps the grid cell. You'll have to make this fine enough to avoid intruding into the outer button images.
EDIT:
It occurred to me that perhaps you could do this with a group of TouchDelegate objects. You would arrange the buttons as I described at first, but make only the parent container clickable. It would use five TouchDelegates to find out which button (if any) was under the tap coordinates. Unfortunately, TouchDelegate only work with Rect hit regions, which leaves us where we started. However, you could cannibalize the source of TouchDelegate and define your own version that accepts some sort of general shape class instead of just a Rect. (The shape class would have to have the equivalent of Rect.contains() to test for a hit. There's nothing built into Android, but you could easily write your own classes for the specific shapes you have.)
You could simplify the code a bit by putting the hit and delegation logic directly in the parent container view, but it would be cleaner, I think, to have a reusable delegate class that separates out the event handling from the container itself.
You can use a mask color for example:
a completely red button,like the image that you posted,the just do pixel color check against the red button,something like:
bool insideMyAwsomeShapeButton(int mouse_x,int mouse_y) {
if get_image_pixel_color_at_pos(mouse_x,mouse_y) == rgbcolor(1,0,0)
{
return true;
}
return false; }
again,this is just a thought,you have to find out specific api on android to do the task,like check pixel color.