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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 15:32:25  来源:igfitidea点击:

Draw Rectangle in JFrame not working

javaswingjframe

提问by AbSaintDane

I have this bit of code that's supposed to draw a rectangle on a JFramebut 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 JFramein 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 JPanelto put inside your JFramebecause JFramedoes 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 JPanelsubclass 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 JPanelthat is added to a JFrame(or a window, or an applet, or a dialog..).

请注意,通常认为重写添加到 a (或窗口、小程序或对话框..)paintComponent(Graphics)的 a的方法更好。JPanelJFrame

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 Infoutis 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
    }
}