【问题标题】:Draw Rectangle in JFrame not working在JFrame中绘制矩形不起作用
【发布时间】:2014-03-14 10:17:28
【问题描述】:

我有这段代码应该在JFrame 上绘制一个矩形,但是当我在 Eclipse 上运行该程序时,它只是打开了框架,但没有在其上绘制圆圈。

代码如下:

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);
    }
}

谁能告诉我为什么它不能正常工作?

【问题讨论】:

标签: java swing jframe


【解决方案1】:

我相信您想要做的是致电frame.repaint();。但是,这仍然不能解决您的问题,因为您的paint() 方法实际上并没有覆盖JFramepaint() 方法,因为您的类没有扩展JFrame,它只是在创建JFrame构造函数。

因此,您可以要么在最后一分钟覆盖并将您的paint方法移入其中(根据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);
    }

}

正如其他人指出的那样,paintComponent() 是一个更好的覆盖选择,您应该记住在新的覆盖方法开始时对 super() 进行适当的调用。然后,您必须创建一个新的 JPanel 以放入您的 JFrame 中,因为 JFrame 没有要覆盖的 paintComponent() 方法。

为此,您可以从您的类中完全删除您的 paint() 方法,并将以下最后一分钟覆盖添加到您的构造函数中:

    setLayout(new BorderLayout());
    add(new JPanel(){
        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            g.drawRect(5, 5, 105, 105);
        }
    }, BorderLayout.CENTER);

但是,对于可扩展性和良好的面向对象设计,从长远来看,您最好定义自己的 JPanel 子类并在那里覆盖 paintComponent(Graphics) 方法。抱歉扯淡了,希望对您有所帮助。

【讨论】:

  • 自定义绘画需要在JComponentpaintComponent()中执行,调用super()方法。
  • @alex2410 - 一次一个问题,他们的 OP 需要了解他们做错了什么以及为什么他们当前的代码首先不起作用。我将编辑我的答案以建议 paintComponent() 是一个更好的覆盖选择。
  • 如果OP不问这个问题,你需要建议他用更好的方法来避免将来出现问题。
  • 添加一个带有paintComponent的示例,我会放弃你的投票。
  • @alex2410 - 添加了paintComponent(Graphics) 的适当代码示例:)
【解决方案2】:

你已经成功地通过调用:

m.paint(null); 

应该是:

m.repaint();

由于调用repaint()paint(Graphics) 方法将被自动调用,但带有一个有效图形对象。

请注意,覆盖JPanelpaintComponent(Graphics) 方法通常被认为更好,该方法添加到JFrame(或窗口、小程序或对话框......)。

重写任一方法时要做的事情是在执行其他任何操作之前调用超级方法。

【讨论】:

    【解决方案3】:

    应该覆盖JFrame 的绘制方法。 Infout中的paint方法没用。

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

    【讨论】:

    • "frame.setDefaultCloseOperation(3);" 定义常量时不要使用幻数。
    • 这就是@Override注解有用的原因
    • 自定义绘画需要在JComponentpaintComponent()中执行,调用super()方法。
    【解决方案4】:

    不要在外部调用paint,而是在你的paint()方法中调用super.paint。

    public void paint(Graphics g)
    {
     super.paint(g);
    //....
    
    }
    

    并删除 m.paint(null)。

    【讨论】:

    • 自定义绘画需要在JComponentpaintComponent()中执行,调用super()方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多