panel with image background and mouse draw - java

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.

Related

Double buffered image example in Jpanel

I would know if my implementation is correct for double buffered image.. because i note that tremble the borders of my image that i move in the screen ... It is normal??
public void paintComponent(Graphics g) {
Image bufferimage= createImage(180,180);
Graphics dbg= bufferimage.getGraphics();
//clean the screen
dbg.setColor(new Color(100,100,100));
dbg.fillRect(0,0,getWidth(),getHeight());
if (game_is_running) {
// draw various type of object with drawImage
for(int i=0; list[i]!=null; i++) {
list[i].draw(dbg);
}
target.draw(dbg);
I.draw(dbg);
}
//finally draw the image linked to graphics
g.drawImage(bufferimage,0,0,this);
}
Move the creation of the bufferimage out of the paintComponent() method. You don't need to create this every time that method is called. You are drawing the whole surface anyway.
When you are done with the Graphics retrieved from bufferImage (i.e. dbg variable in your case) you are supposed to call dispose() on it.
Finally you might be able to get away without the second image if you ensure that your component and the components that contain it, have the property doubleBufferred set to true.
All the paintComponent() method should do is draw the image.
The "if game is running" code does not belong in the paintComponent() method. The idea is to have a Timer or something that changes the state of your game and does the custom drawing on your image. Then when Swing invokes the paintComponent() method you simple paint the image in its current state.
Take a look at the DrawOnImage example from Custom Painting Approaches. The code adds rectangles to the image by using the mouse. Then whenever the component is repainted the image is painted.
The ideas is to create/modify the image once and then repaint the image. In a game it may turn out that every time you modify the image you also paint it, but the code should not be part of the paintComponent() method.

Fading a portion of Graphics in Java Swing

I am trying to implement the fade in/fade out animation in swing.
I am using a JPanel which does not have any components in it. It is completely drawn by paintComponent() method.
Now in one of the portion of this JPanel, I want to implement the fade in/fade-out animation. When I tried using AlphaComposite, the animation is being triggered for whole JPanel.
Can I limit this animation in a small clipped region in that panel?
Graphics2D g2d = (Graphics2D) g;
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.XOR, alpha));
Have you tried using an Graphics object (like rectangle, circle etc..) for your fade in/out? That way it won't be triggered for the complete panel.
Good luck!
Perhaps, but that may be more difficult to achieve than what it's worth. Create a JComponent of the size you want to animate (or fade), add it to your JPanel, and have repaint() called on your smaller component during animation instead of the larger JPanel.
You can use setClip() before painting to restrict the fading area.
Suppose you want a small fading rectangle. Using Area class create 2 Shapes. Intersection of original clip and fading rect and subtraction (subtract the fading rectangle from the original clip).
Call super.paintComponent() twice with 2 different clips. For the second paint you can set your alpha filter.

Painting in Swing, blinking issue

I have the following problem in swing.
I'm implementing basic drawing operations (lines, shapes). When I'm moving mouse with pressed left button, I need to repaint current shape. So I clear the screen and repaint already drawn shapes and currently being drawn one.
Shapes are drawn in paint() method and on mouse move event I call repaint() (paint() is called automatically). The problem is that the screen is blinking strongly on each repaint and it looks really ugly. Please tell me, what I'm doing wrong? Thanks.
I think what you are looking for is double buffering.
Shapes are drawn in paint()
Custom painting should be done in the paintComponent() method and make sure you invoke super.paintComponent() as the first line.
Also custom painting is done on a JPanel (or JComponent), not on the JFrame directly.
I had flickering or blinking problem. I solved it using the following code.
public void update(Graphics g) {
paint(g);
}
#Override
public void paint(Graphics g) {
//super.repaint();
if (myimg != null) {
g.drawImage(myimg, 0, 0, this);
}
//update(g);
}
You don't need to clear the screen, you just call repaint() then it's enough. If you have to clear the screen, it'll blink if you don't use synchronization, because the painting job is done in a separate thread.

creating a pen tool, repainting issue - JAVA

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.

Adding a watermark to a JTextArea

Is they a way of adding a watermark to a JTextArea?
I suspect that you'd need to subclass JTextArea and override the paintComponent() method, drawing your background image first and calling super.paintComponent() to render the text:
public void paintComponent (Graphics g) {
g.drawImage(watermark, 0, 0, this);
super.paintComponent(g);
}
edit: as pointed out by camickr, a JTextArea is opaque, so your subclass will need to change this by calling setOpaque(false).
I doubt the suggestion given above will work. A JTextArea is opaque, so the text will paint over top of the image. So at the very least you will need to make the text area non-opague and you will then need to play with the background colors of the viewport and/or scrollpane.
If you want a reusable solution try creating an ImageBorder. The order of painting is:
a) paintComponent
b) paintBorder
c) paintChildren
So if you add the border to the text area it will paint on top of the text in a fixed location.
Or if you add the border to the viewport it will paint below the text is a floating location.
You may also consider using JXLayer which can create quite complex visual effects

Categories