Java 在 JFrame 中绘制矩形不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22402131/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Draw Rectangle in JFrame not working
提问by AbSaintDane
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.
我有这段代码应该在 a 上绘制一个矩形,JFrame
但是当我在 Eclipse 上运行该程序时,它只是打开了框架,但没有在其上绘制圆圈。
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?
有人可以告诉我为什么它不能正常工作吗?
采纳答案by Rudi Kershaw
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.
我相信你要做的是打电话frame.repaint();
。但是,这仍然不能解决您的问题,因为您的paint()
方法实际上并没有覆盖JFrame
'spaint()
方法,因为您的类没有扩展JFrame
,它只是JFrame
在构造函数中创建了一个。
So, you can eitherdo 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;
因此,您可以进行最后一分钟的覆盖并将您的绘制方法移动到该方法中(根据 polypiel 的回答),或者(我个人认为更有说服力)您可以让您的类扩展 JFrame,就像这样;
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.
然而正如其他人指出的那样paintComponent()
,重写是更好的选择,您应该记住super()
在新的重写方法的开头进行适当的调用。然后您将不得不创建一个新JPanel
的放入您的内部,JFrame
因为JFrame
没有paintComponent()
覆盖的方法。
To do this you could remove your paint()
method from your class entirely and add the following last minute override into your constructor:
为此,您可以paint()
从类中完全删除您的方法,并将以下最后一分钟的覆盖添加到您的构造函数中:
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.
但是,对于可扩展性和良好的面向对象设计,从长远来看,您最好定义自己的JPanel
子类并覆盖paintComponent(Graphics)
那里的方法。抱歉胡说八道,我希望这会有所帮助。
回答by Andrew Thompson
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 validgraphics object.
作为对 调用的结果repaint()
,该paint(Graphics)
方法将被自动调用,但具有有效的图形对象。
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..).
请注意,通常认为重写添加到 a (或窗口、小程序或对话框..)paintComponent(Graphics)
的 a的方法更好。JPanel
JFrame
The thing to do when overriding either method, is to call the super method before doing anything else.
覆盖任一方法时要做的事情是在执行任何其他操作之前调用 super 方法。
回答by Shriram
Don't call the paint externally and call the super.paint in your paint() method.
不要在外部调用paint 并在paint() 方法中调用super.paint。
public void paint(Graphics g)
{
super.paint(g);
//....
}
and remove m.paint(null).
并删除 m.paint(null)。
回答by polypiel
The should overwrite the paint method of the JFrame
. A paint method in Infout
is useless.
应该覆盖JFrame
. 一个paint方法Infout
是没用的。
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
}
}