I would like to be able to paint Image
s onto a JFrame
, but whenever I want (not in the JFrame.paint
method.
For the project I am working on, I have a class Bullseye extends BufferedImage
, and am trying to put it onto a JFrame
:
class DrawingFrame extends JFrame {
public void drawImage(Image img, int x, int y) {
getGraphics().drawImage(img,x,y,null);
repaint();
}
}
class Main {
public static void main(String[] args) {
DrawingFrame frame = new DrawingFrame();
Bullseye bullseye = new Bullseye(20,20); //width,height
// later
frame.setVisible(true);
frame.drawImage(bullseye,10,20);
frame.drawImage(bullseye,20,20);
frame.drawImage(bullseye,30,20);
}
}
However, nothing shows up. After some research, apparently this doesn't work because the changes to the graphics
object get cleared when I repaint()
.
How can I do this? Is this even the right approach?
I think you take the problem backwards. In Swing, all drawing operations should be done within the
paint()
method.What you can do is to store the image you want to draw as attribute in your class, then, in your pain method, draw the image wherever you want. For example:
And in your other class:
Drawing to the screen in Java is (almost) always done in paint(). What you need for your class is:
If you need to turn on the drawing of bullseyes at a specific time, create a flag on the DrawingFrame object, and set it when you need them. You will need to call repaint() when the flag is set.
Create a Graphics Object in your class, for which it must have global, not just method-local existence.
Then also have a boolean for flow-of-control purposes:
and override subject Swing Component superclass' update method() asfollows:
Update() clears the all color in an offscreen graphics data buffer to the current background color of the GraphicsObject. And, you must also know the exact three methods done inside Swing Components' paint():
(1) it calls its very own paintComponent(),here is where actual painting of such Component is delegated to;
(2) the method painting its borders; and then last is the painting of its child Component. One last very important and inevitable thing: use a class, nested, named or anonymous, with this overriden Container methods. And pass that class to JFrame's setContentPane(Container actualgraphicsreference) method; this is a must. I hope that I have made my explanatory and informative approach unambiguous. Self-explanatorily, you may now use freefrompaint to paint beyond, and the Operating System's call to your Frame's repaint() will not invoke a "twin Graphics" default raster-clearing operation, which now you have suppressed in going to code as I above instructs and recommends to you. Thank you for an expressive opportunity.
How about creating a offscreen image to paint on while outside of actual paint, and then the actual paint just paints the offscreen image to actual graphics? A kinda double buffering?
Custom painting should RARELY ever be done in the paint() method, especially the paint() method of a JFrame. Custom painting is done by overriding the paintComponent() method of a Swing component, generally a JComponent or JPanel. Read the section from the Swing tutorial on Custom Painting for more information and working examples.
However, im this case you don't event need to do any custom painting. You just create an ImageIcon and add the Icon to a JLabel, then you add the JLabel to a panel. Read the section from the Swing tutorial on How to Use Icons for working examples.
If you can't find the appropriate layout manager to use you can also use absolute positioning. Again you will find a section in the tutorial on using layout managers that explains this in more detail.