So my assignment wants me to create an applet but as an extra I'm supposed to use the paint method to draw a string, for example:
public void paint(Graphics g){
g.drawString("name, name name", 400,100);
}
My problem is that this pretty much prevents the rest of my app from painting.
Related
I am currently programming a game which includes lots of graphical elements. Currently the code looks like this:
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(ImageLoader.gui_iconbar, xToRel(480), yToRel(810), xToRel(960), yToRel(270), null);
g.drawImage(ClientVariables.getSplashart(Main.selectedCharacter, 0), xToRel(495), yToRel(825), xToRel(135), yToRel(240), null);
//... (don't get confused with xToRel, it just makes changes to the drawing position if you move the camera)
}
The problem is: there are TONS of these g.draw(whatever); lines. I want to split them in multiple classes but just making 4 classes and copy paste gameFrame.add(GraphicclassXY); doesn't work, logically. Does anyone know how to fix this issue? (It's not a problem if the solution includes making changes from jlabel to canvas for example)
Create logical non-component classes (that don't extend JLabel, JPanel, JFrame, JComponent or other Swing component), give them a public void draw(Graphics g) method, give the class that does the drawing instances of your logical classes, perhaps within some sort of collection, and iterate through the collection and call draw on your instances within the paintComponent method.
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
}
So I'm trying to learn Java graphics and this bit of code has me perplexed. I don't understand a couple things here:
Why is paintComponenet used twice for the name of the method and as
we call a method from super (JPanel)?
What is Graphics g, isn't it just a reference variable for an object
of Graphics since we don't set it equal to = new Graphics();?
Why does the method name in my class have to be paintComponent to
call upon the method paintComponent from JPanel or super?
The method in my class paintComponent takes the parameter of a
Graphics object but when does paintComponent even get called and
when is the parameter of Graphics inserted?
Essentially I need someone to explain this code to me.
//note this is all in a class that extends JPanel, my JPanel is later placed in
//a JFrame which is run through main
public void paintComponent(Graphics g)
{
int width = getWidth();
int height = getHeight();
super.paintComponent(g);
g.setColor(Color.RED);
g.fillRect(10, 10, 200, 200);
g.setColor(Color.BLUE);
g.drawRect(10, 10, 200, 200);
}
Why is paintComponenet used twice, for the name of the method and as we call a method from super (JPannel)
It's not "used" twice. It is overridden once, but you want to call the parent (JPanel) class's super method so that you're sure that it does its own house-keeping painting, including painting its children and clearing out any dirty bits from the screen.
What is Graphics g, isn't it just a reference variable for an object of Graphics since we don't set it equal to = new Graphics();
It's a Graphics parameter. You don't set it = new Graphics() because the JVM does this for you. It calls the method behind the scenes when needed, and provides the parameter.
Why does the method name in my class have to be paintComponent to call upon the method paintComponent from JPannel or super
It has to override the super's method so that the JVM calls the right method when it wants to draw the GUI.
The method in my class paintComponent takes the parameter of a Graphics object but when does paintComponent even get called and when is the parameter of Graphics inserted.
Again, it is called by the JVM when either your program wants to repaint the GUI, such as when you call repaint() or when the operating system wants to repaint a window such as if a window is minimized and restored.
You really really want to read the graphics tutorials:
Lesson: Performing Custom Painting: introductory tutorial to Swing graphics
Painting in AWT and Swing: advanced tutorial on Swing graphics
1) Why is paintComponenet used twice, for the name of the method and as we call a method from super (JPannel)
Here the line super.paintComponent(...), means we want the JPanel to be drawn the usual Java way first (this usually depends on the opaque property of the said JComponent, if it's true, then it becomes the responsibility on the part of the programmer to fill the content area with a fully opaque color. If it is false, then the programmer is free to leave it untouched. So in order to overcome the hassle assoicated with this contract, super.paintComponent(g) is used, since it adheres to the rules, and performs the same task, depending upon whether the opaque property is true or false).
2) What is Graphics g, isn't it just a reference variable for an
object of Graphics since we don't set it equal to = new Graphics();
and
4) The method in my class paintComponent takes the parameter of a
Graphics object but when does paintComponent even get called and when
is the parameter of Graphics inserted
paintComponent method is where all of your painting code should be placed. It is true that this method will be invoked when it is time to paint, but painting actually begins higher up the class heirarchy, with the paint method (defined by java.awt.Component.) This method will be executed by the painting subsystem whenever you component needs to be rendered. Its signature is:
public void paint(Graphics g)
javax.swing.JComponent extends this class and further factors the paint method into three separate methods, which are invoked in the following order:
protected void paintComponent(Graphics g)
protected void paintBorder(Graphics g)
protected void paintChildren(Graphics g)
The API does nothing to prevent your code from overriding paintBorder and paintChildren, but generally speaking, there is no reason for you to do so. For all practical purposes paintComponent will be the only method that you will ever need to override
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