【问题标题】:Java swing.JFrame only paints content on resize of windowJava swing.JFrame 仅在调整窗口大小时绘制内容
【发布时间】:2016-04-25 16:05:21
【问题描述】:

我有以下程序。它应该在绿色地面上打印红色文本。当程序打开时,我只看到绿色背景,但看不到上面的红色文字。调整窗口大小并重新计算后,将出现红色文本。

如果我在窗口中使用 JPanel 并在那里添加组件,它可以正常工作。如果颜色是在paintComponent中设置的,那么一切正常。

那么问题出在哪里,如果我直接在 JFrame 上绘制。我错过了第一个“更新”还是什么?看起来在第一次绘制窗口时缺少一些信息(附加文本),程序只有在重新计算和重绘窗口后才会意识到这些信息。

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;

public class PaintAWT extends JFrame {

    PaintAWT() {
        this.setSize(600, 400);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        // Set background color:
        // If you don't paint the background, one can see the red text.
        // If I use setBackground I only see a green window, until it is
        // resized, then the red text appears on green ground
        this.getContentPane().setBackground(new Color(0,255,0));

        // Set color of text
        g.setColor(new Color(255,0,0));

        // Paint string
        g.drawString("Test", 50, 50);
    }

    public static void main(String[] args) {
        new PaintAWT();
    }

}

【问题讨论】:

  • 对于初学者,您应该覆盖paintComponent,而不是paint。我个人建议扩展JPanel 而不是JFrame。您还需要一种方法来控制对repaint 的调用,因为根据 Swing 的逻辑,容器通常只会在需要时(即调整窗口大小时)重新绘制。

标签: java swing jframe paint


【解决方案1】:

您不应该在绘画方法中设置组件的属性。绘画方法仅用于绘画。不要使用 setBackground()。

您应该在创建框架时设置内容窗格的背景。

当您进行自定义绘制时,您还应该重写 getPreferredSize() 方法以返回组件的大小。

您也不应该扩展 JFrame。仅在向类添加功能时才扩展类。

首先阅读 Custom Painting 上的 Swing 教程部分,了解更多信息和工作示例。这些示例将向您展示如何更好地构建代码以遵循 Swing 约定。

【讨论】:

    【解决方案2】:

    您应该将 setBackground 移至构造函数。在paint方法中设置背景是一种不好的方法。

    import java.awt.Color;
    import java.awt.Graphics;
    
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    
    public class PaintAWT extends JFrame {
    
        PaintAWT() {
            this.setSize(600, 400);
            this.setLocationRelativeTo(null);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            // Set background color:
            // If you don't paint the background, one can see the red text.
            // If I use setBackground I only see a green window, until it is
            // resized, then the red text appears on green ground
            this.getContentPane().setBackground(new Color(0,255,0));
            this.setVisible(true);
        }
    
        @Override
        public void paint(Graphics g) {
            super.paint(g);
    
    
            // Set color of text
            g.setColor(new Color(255,0,0));
    
            // Paint string
            g.drawString("Test", 50, 50);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new PaintAWT();
                }
            });
        }
    
    }
    

    【讨论】:

    • 您不应该扩展 JFrame 来进行自定义绘画。你不应该重写paint()。
    • 那么改变背景颜色怎么样?如果我把它放在构造函数而不是paint方法中,它是固定的,不是吗?
    猜你喜欢
    • 2011-09-29
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    • 2011-04-02
    • 2013-09-19
    • 2012-07-24
    相关资源
    最近更新 更多