Reputation: 77
I have this bit of code that's supposed to draw a rectangle on a JFrame
but when I run the program on Eclipse, it just opens the frame, but does not draw the circle on it.
Here is the code:
import javax.swing.*;
import java.awt.*;
public class Infout {
Infout(){
JFrame frame = new JFrame();
frame.setSize(300, 400);
frame.setTitle("An Empty Frame");
frame.setDefaultCloseOperation(3);
frame.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Infout m = new Infout();
m.paint(null);
}
public void paint(Graphics g)
{
g.drawRect(5, 5, 105, 105);
}
}
Can someone please tell me why it's not working properly?
Upvotes: 4
Views: 26661
Reputation: 13022
I believe what you are looking to do is call frame.repaint();
instead. This still doesn't sort your problem however, because your paint()
method isn't actually Overriding the JFrame
's paint()
method because your class does not extend JFrame
, it is just creating a JFrame
in the constructor.
So, you can either do a last minute override and move your paint method into that (as per polypiel's answer), or (I personally think more eloquently) you can have your class extend JFrame, like so;
import javax.swing.*;
import java.awt.*;
public class Infout extends JFrame{
Infout(){
setSize(300, 400);
setTitle("An Empty Frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
Infout m = new Infout();
m.repaint();
}
@Override
public void paint(Graphics g)
{
g.drawRect(5, 5, 105, 105);
}
}
As other's have pointed out however paintComponent()
is a better choice of override, and you should remember to make an appropriate call to super()
at the beginning of the new overridden method. You will have to then create a new JPanel
to put inside your JFrame
because JFrame
does not have a paintComponent()
method to override.
To do this you could remove your paint()
method from your class entirely and add the following last minute override into your constructor:
setLayout(new BorderLayout());
add(new JPanel(){
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawRect(5, 5, 105, 105);
}
}, BorderLayout.CENTER);
For extensibility and good object orientated design however, you may be better off in the long term defining your own JPanel
subclass and overriding the paintComponent(Graphics)
method there. Sorry for waffling, I hope this helps.
Upvotes: 2
Reputation: 2341
The should overwrite the paint method of the JFrame
. A paint method in Infout
is useless.
import javax.swing.*;
import java.awt.*;
public class Infout {
Infout(){
JFrame frame = new JFrame() {
@Override public void paint(Graphics g) {
g.drawRect(5, 5, 105, 105);
}
};
frame.setSize(300, 400);
frame.setTitle("An Empty Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Infout m = new Infout();
// You shouldn't need to call repaint
}
}
Upvotes: 1
Reputation: 4421
Don't call the paint externally and call the super.paint in your paint() method.
public void paint(Graphics g)
{
super.paint(g);
//....
}
and remove m.paint(null).
Upvotes: 0
Reputation: 168845
You have managed to completely break the paint chain by calling:
m.paint(null);
It should be:
m.repaint();
As a result of a call to repaint()
, the paint(Graphics)
method will be called automatically, but with a valid graphics object.
Note that it is typically considered better to override the paintComponent(Graphics)
method of a JPanel
that is added to a JFrame
(or a window, or an applet, or a dialog..).
The thing to do when overriding either method, is to call the super method before doing anything else.
Upvotes: 2