So I have a college project to make paint program using swing , I need to clear Graphics object and but from a method in an outside class and then draw all shapes again (refreshing the graphics object) as I'm passing the graphics object through this method .
the class is responsible for saving all shapes i draw on this graphics (in an ArrayList ) .
SO how can I do this if I can't call Super.paintComponent that exists in the Jpanel class .
as I'm passing the graphics object through this method .
You should NOT be passing the Graphics object. The paintComponent() method (or any method is invokes) should always use the Graphics object passed to the paintComponent() method.
SO how can I do this if I can't call Super.paintComponent that exists in the Jpanel class .
In the class where you do the custom painting you create a clear() method. This will simply remove all the Shape objects from the ArrayList and then invoke repaint().
See the DrawOnComponent example from Custom Painting Approaches that demonstrates how this is done.
Found a very simple answer which is "Draw white rectangle, then draw shapes again"
that would simply solve my problem :)
Related
I am attempting to make a "Pong" game, and I am struggling to draw the Rectangle that will be the "Racket". I have attempted to use Java2D graphics, but it just doesn't want to work for me. The 2 links below will show the "Racket" class and "Window" class. The Racket class is where I draw the Racket for the game, and the Window class is where I make the JFrame. Racket Class Window Class
It's supersimple. How could your Window class know that it should draw your
Racket?
I tell you what todo but I won't provide code, because you only posted an image.
Extend JFrame instead of just instantiating it (or JPanel for reusage purposes)
Override the paint method (don't forget the super.paint(g) call)
Create an instance of Racket as a member of Window class
Call racketInstance.paint(g)
These are the simplest steps to follow if you want it to be drawn. But for your whole target this is not the best approach.
You must extend JPanel and override the method paint(Graphics g). In this method, you must draw the Racket.
In your class Window, add your JPanel subclass instead of a standard javax.swing.JPanel.
I'm new to making GUIs in Java. As I understand, there's a class called Graphics which is in charge of drawing shapes in a JPanel. When my application starts, I call the paintComponent method, which draws the board of the game I'm programming, and the paintComponent method takes a Graphics g as input. However, later on, I want to update the board, so how do I tell the same g that drew the board at the start of the game to draw something else when the user does something like clicking?
I believe this should have a very simple answer.
Every JComponent (Swing component) has a repaint() method, just call it to tell the DrawingManager to redraw your component.
All your drawing code should be in paintComponent method, that means that you don't draw anything anywhere else (you draw only in the flow of invocation of paintComponent, you can have drawing code structured in methods of course).
This method needs to have access to the state that indicates what and where should be drawn. It is because the OS could request repainting, and then only the painting methods from JComponent are called.
When you invoke repaint() on your JComponent, then in short time the paintComponent() method of the component on which you requested repainting will be called by the drawing thread, and you should draw only in this drawing thread.
Try repaint() or revalidate(), it should work.
I call the paintComponent method
No, you should never call the paintComponent() method directly. Swing will call the method for you when the component needs to be repainted.
I want to update the board
Then you need a "setter" method. Think of other Swing components. They have methods like "setForeground(), setBackground(), setText()" etc.
So if you want to change your component then you need to create appropriate setter method to change the properties of your class. Then in the method you save the property and simply invoke repaint() and Swing will repaint your component. So now your paintComponent() method needs to check the property you just set to do the appropriate painting.
public void setSomeProperty(Obect someProperty)
{
this.someProperty = someProperty;
repaint();
}
....
protected void paintComponent(Graphics g)
{
super.paintComponent();
// paint the board
if (someProperty != null)
// paint the property
}
I came across this code. I thought I alleviate this confusion before I run into any hiccups along the way in programming. I am having trouble understanding whether the paint or the actionPerformed method gets executed first in Board class. I hope my java comments are correctly stated.
The thing is, I took introductory Java in the summer and graphics was only introduced towards the end of the course. The class used ImageIcon and we never touched the drawImage method and Image abstract class. I also do not understand the paint method at all. This code is more involved than the Java graphics lecture I had. Based on the Java API, the paint method originated from the JComponent class which is JPanel's superclass.
So what is this parameter Graphics g that the paint method takes in all about and how should I think about it? How does the paint method know which object of a graphics class to paint. I looked at the Java API and it says Graphics is an abstract class. How can g be an object if its data type is abstract? I am saying g is an object because the code is calling the drawImage method on the object g.
On a side note, does repaint method mean erase the content in the JPanel and redraw the entire component like rendering?
public class Board extends JPanel implements ActionListener{
private Image apple;
private int apple_x;
private int apple_y;
// over-riding the paint method from the JComponent Class
public void paint(Graphics g){
// recursively call the paint method
super.paint(g);
g.drawImage(apple, apple_x, apple_y, this);
}
// does this method gets called first or the top one?
public void actionPerformed(ActionEvent e) {
repaint();
}
}
Drawing in Java (and basically all current windowing systems) follows the Hollywood principle:
You don't call me; I call you.
I.e. you can tell the system that a certain area will need to be redrawn (repaint()). But you'll have to wait until the system calls you to do the drawing. In Java, the system will call the paint() method and will pass you a Graphics instance to use for drawing.
So the order of event is:
actionPerformed()
paint()
Graphics is often called a graphics context. It's an object used for drawing. Depending on the system and the current requirements, the drawing might go directly on the screen or into an offscreen buffer that is later copied to the screen. The Graphics instance takes care of the details.
Someone can correct me if I am wrong.
Yes, graphics is an abstract class. But an instance of any class that inherits Graphics (such as Graphics2D) can be passed as graphics. If I recall correctly this is call upcasting. g is passed by the UI thread that called paint(), either because the object was invalidated, or has to be updated.
The graphics object is a reference to the actual bitmap that appears to the user.
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 have a canvas that is drawing everything in a paintComponent() method.
Is it possible to draw outside of paintComponent (without calling a method within paintComponent?)
If so how do you go about doing this?
It depends what you mean and why you need it. For example, it is possible to create a BufferedImage, get the Graphics2D object, Graphics.paint() everything that should be on the image, then drop the image into a JLabel.
But since I do not know what you are trying to achieve (as opposed to what you are trying to do) I cannot know if that answer solves the unstated problem.
I found out how to solve this issue.
What I did was make JPanel an inner class to my JFrame class.
In JPanels paintComponent I had it calling a method from the outer class which did some updating of the graphics, by passing paintComponents Graphics2D object.
This has allowed me to paint "outside" of paintComponent, just as I needed.