Add Element to Canvas JavaFX - java

So I want to add elements or items to a canvas through a GraphicsContext.
For example, to add a Rectangle, I don't want to use fillRect(...), I want to create a Rectangle rect = new Rectangle(...) and add it to my GraphicsContext,
So I can perform changes on that rect.
Something like this :
Rectangle rect = new Rectangle();
rect.setHeight(100);
rect.setWidth(100);
rect.setFill(Color.BLACK);
DragResizeMod.makeResizable(rect, null);
then added it to
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.add(rect); //somehow
There is a solution which is to use a Pane instead of Canvas but I don't think it the best way, since a GraphicsContext run on a single thread.
Thanks in advance.

Adding Rectangles to a properly configured Pane is the way to go. I don't understand what your problem with this approach is. This is the way JavaFX works and you will probably not be able to change this.

Related

HoverProperty inside canvas in javafx-8

I want to draw a line in javafx-8 canvas such that when I keep my mouse over it, it should change its color and glow (if possible).
How do I do this?
Sorry, you can't do this.
In javafx, every Node is mouse aware, that is, you can track MouseEvent on a Node, but, unfortunately, drawings inside a Canvas aren't Node, rather they are mapping of pixels of that Canvas.
Alternative :
You can use an AnchorPane instead of canvas and have Line , Circle as its children.

How do I create a view following the player in a JavaFX game?

I'm trying to make my first game in JavaFX, where a player object (not a Node) will move inside a level. However, the full level shouldn't be visible inside the window, only a part of it surrounding the player should be. I've searched quite a bit for a solution to this that works with the way I've done my project, but haven't been successful. The following code describes how I've set up my GUI:
private VBox appRoot;
private Pane gameRoot;
private Canvas canvas;
private GraphicsContext gc;
private HBox uiRoot;
This is the different panes I use. The appRoot contains both the gameRoot and the uiRoot, in that order. The gameRoot contains the canvas. Everything inside the level, including the level itself, is drawn onto the canvas, like this:
canvas = new Canvas(ROOM_WIDTH, ROOM_HEIGHT);
gc = canvas.getGraphicsContext2D();
createLevel(ROOM_WIDTH, ROOM_HEIGHT, CELL_WIDTH, CELL_HEIGHT);
gc.scale(2, 2);
drawLevel(gc, ROOM_WIDTH, ROOM_HEIGHT, CELL_WIDTH, CELL_HEIGHT);
player.render(gc);
createLevel and drawLevel just creates a level and draws squares where different blocks should be. The player object's render method draws the player at its x- and y-coordinates. As you can see I've scaled the canvas, so as of now the entire level isn't shown when the game is started.
The problem is that I can't make it so that what is shown in the window is the things surrounding the player object. I've seen some code utilizing the methods setLayoutX and setLayoutY, but I've been unable to reproduce this so that it works.
I would be very grateful if anybody could help me out with this, and hopefully without changing too much of how the drawing is done.
Thanks! :)
Also, here are two pictures showing how it looks; the first is when the player is not inside the current view, and the second is with the player in the view.
Image without player in view
Image with player in view
Do not us the Canvas directly to display the level. Instead you can use an image that represents your level and then have the image in an ImageView. On that ImageView you can define a viewport of the area of the image that is visible.
To get the image you can either use your Canvas node and take a snapshot (See this question). This is probably the easiest way with what you have. Or you can forego the Canvas altogether and draw the image. If the levels are predefined (and not generated at runtime), this seems the best approach, then you can supply the images as resources along with the code.

can i draw a gradient background for a figureCanvas in Java

I'd like to draw a gradient background for a FigureCanvas. Unfortunately the code which works for Composites or similars does not work for my FigureCanvas. Where it makes a perfect gradient background on my Composite it simply puts one color as background of my FigureCanvas.
Here is a snippetof how it works with all my other Controls.
Rectangle rect = parent.getClientArea();
Image newImage = new Image(parent.getDisplay(), 1, Math.max(1,
rect.height));
GC gc = new GC(newImage);
gc.setForeground(composite.getDisplay().getSystemColor(SWT.COLOR_WHITE));
gc.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_BLUE));
gc.fillGradientRectangle(0, 0, 1, rect.height, true);
gc.dispose();
composite.setBackgroundImage(newImage);
Am i missing something here? Or is it simply not possible without overwriting or extending something (if so what?)? I also tried using the same backgroundImage as another Composite has it, where it works fine.
Thank you for answers!
turns out the problem was not the FigureCanvas itself but GEF which overwrote it somewhere else.

Java Swing: How to fill a shape with a single image

I know that one can use g2d.setPaint(new TexturePaint(img,rect)) in order to fill a shape with an Image, but the problem is that the shape is tessellated with the image instead of rescaling the single image to the bounding box of the shape in order to fill the whole area.
The latter is what I want to achieve.
For example, if I have an image of 20x20 and I want to fill an Ellipse2D of width = 200 and height = 300, I would like to fill that Ellipse2D with a rescaled version of 200x300 of the image instead of tessellating it with the 20x20 image.
Is there a way to achieve this and hopefully in an efficient way?
Try this:
g2d.setPaint(new TexturePaint(img.getScaledInstance(200, 300, 0),rect));
I never tried this out before but it seems like it should work.

How to show icons during drag and drop

I am working on some NetBeans platform app, and i am currently stuck on some detail in Visual Library. Ok, here is problem. I have Visual Editor for my app, with pallet, scene and everything works great, just there is a problem when i am dragging icons from pallet to scene. They are not displayed during drag event, i would like to create that effect, can someone help on this?
I do this in two phases:
1) Create a screenshot (an image) of a palette element. I create the screenshot lazily and then cache it within the view. To create the screenshot, you can use this snippet:
screenshot = new BufferedImage(getWidth(), getHeight(), java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE);// buffered image
// creating the graphics for buffered image
Graphics2D graphics = screenshot.createGraphics();
// We make the screenshot slightly transparent
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f));
view.print(graphics); // takes the screenshot
graphics.dispose();
2) Paint the screenshot on the receiving view. When the drag gesture is recognized, find a way to make the screenshot available to the receiving view or one of its ancestor (you could make it available on the frame or its content pane, depending on where you want to make the screenshot drag available) and paint the image within the paint method. Something like this:
a. Make the screenshot available:
capturedDraggedNodeImage = view.getScreenshot(); // Transfer the screenshot
dragOrigin = SwingUtilities.convertPoint(e.getComponent(), e.getDragOrigin(), view); // locate the point where the click was made
b. As the mouse is dragged, update the location of the screenshot
// Assuming 'e' is a DropTargetDragEvent and 'this' is where you want to paint
// Convert the event point to this component coordinates
capturedNodeLocation = SwingUtilities.convertPoint(((DropTarget) e.getSource()).getComponent(), e.getLocation(), this);
// offset the location by the original point of drag on the palette element view
capturedNodeLocation.x -= dragOrigin.x;
capturedNodeLocation.y -= dragOrigin.y;
// Invoke repaint
repaint(capturedNodeLocation.x, capturedNodeLocation.y,
capturedDraggedNodeImage.getWidth(), capturedDraggedNodeImage.getHeight());
c. paint the screenshot in paint method:
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.drawImage(capturedDraggedNodeImage, capturedNodeLocation.x,
capturedNodeLocation.y, capturedDraggedNodeImage.getWidth(),
capturedDraggedNodeImage.getHeight(), this);
}
Instead of calling repaint() and perform the painting in the paint() method, you could invoke paintImmediately() as the mouse moves but the rendering will be a lot poorer and you could observe some flickering, so I would not recommend that option. Using paint() and repaint() provides a better user experience and a smooth rendering.
If I hear you well, you are creating a graphical editor of some sort, with drag and drop of elements, and you want to create an effect during that drag and drop?
If so, you basically need to create a ghost of the object you're dragging and attach it to the move of the mouse. Easier said than done, of course, but you get the gist.
So what you need is to take the image of what you're dragging (it shouldn't be too much trouble) and move it according to the position of the mouse (think of substracting the relative position of the mouse cursor in the object you're dragging).
But I think that kind of code is available somewhere. I'd advise you to look that up :
http://free-the-pixel.blogspot.fr/2010/04/ghost-drag-and-drop-over-multiple.html
http://codeidol.com/java/swing/Drag-and-Drop/Translucent-Drag-and-Drop/
Hope that helps you!

Categories

Resources