I am trying to create a pen tool using mouse listeners:
public void mouseDragged(MouseEvent e) {
imageL.setCoordinates(originalPos, e.getPoint());
imageL.repaint();
originalPos = e.getPoint();
}
The paint function in the JLabel (imageL) receives two sets of points that allow drawing a line based upon the mouse drag. The only issue is that every time the drag is performed, the new layer does not contain the line drawn from the previous mouse drag. The paint function of the JLabel is as follows:
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(drawingColour);
g2d.drawLine(originCors.x,originCors.y,endCors.x,endCors.y);
}
So essentially my question is: How do I "add" the new line to the current layer?
any help would be great,
Thanks in advance
You want to draw in a JComponent's (and JLabel extends from JComponent) paintComponent method, not the paint method unless you plan to handle all the painting of the component's borders and children. Next, you may wish to have your drawing component hold an ArrayList of Point and add Points to this array list in the mouseDragged method. Then the paintComponent method can iterate through the list and paint all the lines. If all you want to do is paint one line, then have the painting JLabel hold both points in a class field.
Michael,
For a start, in swing (a JLabel is a swing component, as apposed to the older AWT library) the recommended practice is to override the paintComponent method (not the "paint" method). See The Java Tutorials: Custom Painting for the hows & whys of it.
If you want to custom-paint a-list-of-lines then you're going to have to do just that... not just the "new" one. One way around this is to "update" an image with each new line, and then custom-paint that... this is slightly quicker as you only "paint" the each line once, at the cost of using more memory (to maintain the "backgroun image")... but this technique lends itself to "double buffering", which avoids "that flickering" you get when you draw directly to the screen. See The Java Tutorials: Working with Images for the details. It's actually pretty straight forward.
I suggest you google for "java double buffering example" (avoid Rose India, it's full of crap).
Cheers. Keith.
Related
My question is that i need to make a GUI that keeps updating becuse i get values that can change from a DB and i got some problems in the graphical area.
well im using Drawline and Drawstring from Graphics2D that print values that are found on the database, this strings and lines move and change value, so i need to call repaint(); with a timer to make them apper in the jpanel, the problem is that repaint(); is not removing the old painting in the background before painting, but when i resize all updates perfecly.
i know a way to clear but the background color goes away too so,
There is a way to update the jpanel removing old paintings and keep the deafult background color?
Not updated
After changing a coordenate and a label text to "AXIS Y" (repaint called automatically from a timer)
Thanks.
From the looks of your image, it looks like you're just forgetting to call super.paintComponent in the paintComponent method. What this does is repaint the background for you, so aren't left with the previous paint artifacts.
#Override
protected voud paintComponent(Graphics g) {
super.paintComponent(g);
}
Note: For future reference, though the images gave us a good picture, it always best to post a Minimal, Complete, and Verifiable example along with those images, so we don't have to make guesses (educated or not)
So I have a JPanel called displayPane and I want to make it a drawing area for a graph (I am making a graphing calculator). I am using WindowBuilder and this is the generated code for the JPanel:
JPanel displayPane = new JPanel();
displayPane.setBackground(Color.WHITE);
displayPane.setBounds(173, 33, 455, 432);
frame.getContentPane().add(displayPane);
After that I want to draw the axis of the graph but I have no idea how.
I've searched everywhere about it but everyone constructs a member class or something in the main class and adds the paintComponent(Graphics g) but that confuses me. What is that trying to accomplish ? Or just give me your way of doing it I don't really care as long as I understand it.
Any help is appreciated :)
Since this is homework, I'm going to give you general guidance without code, but first and foremost, please read this link on performing custom painting with Swing. Next you should put the Window Builder software to the side and work on creating your own code from scratch, at least do this til you're comfortable coding with Swing.
Next suggestions:
Have your DrawingPanel extend JPanel
Override paintComponent(Graphics g)
Call the super's method in your override, super.paintComponent(g) as this will refresh the graphics and erase old "dirty" pixels.
Play with drawing lines using g.drawLine(...)`
keep doing this and you'll get the idea of what you'll need.
Custom painting is achieved by overriding the paintComponent method of a JComponent based class (like JPanel).
This gives you access to the drawing surface onto which content is drawing and eventually shown on screen
See Custom painting and Painting in AWT and Swing for more details.
The Graphics API (or more specifically, the Graphics2D API) is a power abstract toolkit which provides with the means to actually paint stuff to the screen.
At the basic level, this provides you with the ability to specify colors and draw basic shapes and text. At a more complex level, you can define you own shapes, perform more complex coloring effects, including gradient fills and transformations of the basic context
See the 2D Graphics Trail for more details.
How can I use a image as background in a JPanel if the paint () method is already used for other purposes? (I'm tried to draw over a image in a panel).
Here is my code to draw as a pencil, but I donĀ“t know how to add the image as background ?
#Override
public void paint(Graphics g) {
if (x >= 0 && y >= 0) {
g.setColor(Color.BLACK);
g.fillRect(x, y, 4, 4);
}
}
Thanks Diego
Suggestions:
Don't draw in the JPanel's paint(...) method but rather use it's paintComponent(...) method. There are several reasons for this, one being that if you use the paint(...) method, then you are also responsible for drawing the JPanel's borders and child components and at risk of messing up the rendering of these guys. Also you lose Swing's automatic double buffering.
First call the parent class's super method before calling any other code in the method. This will allow the JPanel to refresh its background and do any graphics housekeeping that may need to be done.
Next draw your background image using g.drawImage(...),
Then do your pencil drawing.
Hovercraft Full Of Eels gave good advice on one direction to take. Here is another.
Display the image in a (ImageIcon in a) JLabel.
When it comes time to paint:
Call createGraphics() on the BufferedImage to gain a Graphics2D object.
paint the lines or other visual elements to the graphics instance.
dispose of the graphics instance.
Call repaint() on the label.
E.G. as seen in this answer.
Let's say we have the following situation:
JPanel panelp=new JPanel();
paintSomething(panelp.getGraphics();
and somewhere else in a different object, the method:
void paintSomething(Graphics g){ /*code*/ }
I don't want to override paintComponent method of panelp. How can I paint something to panelp from the method paintSomething using the Graphics of panelp?
whatever.getGraphics() is snapshot is the snapshot that will go away when
after first repaint
JComponets are repainted internally from Mouse or Key Events, these events are implemented in the concrete JComponets API
simple example for usage of whatever.getGraphics() is printing to the printer or saving current GUI as printscreen to the e.g. JPEG or PGN File
basic stuff is described in the 2D Graphics
You could draw your stuff in the paintSomething into a BufferedImage which you can then draw to the panel by overriding paintComponent
I'm Basically programming a simple game engine but I'm having problems with my sprites/images not appearing when they should... or at all!
I'll try and keep this as simple as possible. I have a Sprite, GameEngine and Display class. In the gameloop, I have a method that sets the new position of my Sprite (so it just sets the x and y variables). Next I call a transform method which does the following:
public void transform() {
affineTransform.setToIdentity();
affineTransform.translate(x, y);
}
Following that, I then call a draw method in the Sprite:
public void draw() {
graphics2D.drawImage(image, affineTransform, jFrame);
}
Finally, in my thread I then call repaint() on the JFrame (the Display class). My paint method for that class is as follows:
public void paint(Graphics g) {
g.drawImage(backbuffer, insets.left, insets.top, this);
}
But nothing is appearing, apart from a black screen!
I'm also getting confused between Graphics g, and Graphics2D and when to use either. (The overridden paint method uses Graphics g). For the record, I do have a Graphics2D variable in the class that is created by calling backbuffer.createGraphics();
Another thing that is confusing me is this AffineTransform... I've read the documentation but I'm still utterly confused on how and when to use it - and what exactly it seems to do. Is there any explanation in relatively simple terms?
Surely this should be working... am I missing something out here?
To answer part of your question:
From the Graphics2D JavaDoc
This Graphics2D class extends the Graphics class to provide more sophisticated control over geometry, coordinate transformations, color management, and text layout. This is the fundamental class for rendering 2-dimensional shapes, text and images on the Java(tm) platform.
Essentially, with Graphics2D you can do much more than you can with Graphics. And with a Sun JVM 1.5+, it should be safe to cast the Graphics object you get in paint() to Graphics2D
I just noticed this: For the record, I do have a Graphics2D variable in the class that is created by calling backbuffer.createGraphics();
You should make sure you're not drawing on a Graphics[2D] canvas (I'll use this term to refer to the drawable area that the Graphics[2D] object provides) that you later throw away. If you're drawing your image on a separate canvas, you should ensure that you then draw that image onto your actual display canvas.
I don't really have a good explanation of AffineTransform but maybe these will help?
http://www.javalobby.org/java/forums/t19387.html
https://secure.wikimedia.org/wikipedia/en/wiki/Affine_transformation
From Wikipedia - In general, an affine transformation is composed of linear transformations (rotation, scaling or shear) and a translation (or "shift"). Several linear transformations can be combined into a single one. Basically, you use this class to perform operations such as rotation, translation, zoom etc.