java - JPanel 导致侧面有额外空间?

标签 java swing while-loop jpanel delay

我制作了一个简单的程序,它使用 drawString() 在 JPanel 上绘图,然后重新绘制以将背景更改为随机颜色。它工作正常,除了 JPanel 右侧和底部的约 10 像素空间,它们仍然是默认颜色。我认为这个问题可能是由于我使用 pack()getPrefferedSize() 的方式而发生的。感谢任何解决此问题的帮助或建议。

生日.java

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Birthday {

    DrawString panel = new DrawString();

    public Birthday() {
        JFrame f = new JFrame();

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(panel);
        f.setTitle("Happy Birthday!");
        f.setLocation(10, 10);
        f.pack();

        f.setVisible(true);
        f.setResizable(false);

        Timer timer = new Timer(500, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                panel.repaint();
            }
        });
        timer.start();
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Birthday();
            }
        });
    }
}

DrawString.java

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JPanel;

public class DrawString extends JPanel {

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

        int width = getWidth();
        int height = getHeight();

        int x = 350;
        int y = 250;
        int red   = random(0,255);
        int green = random(0,255);
        int blue  = random(0,255);
        Color black = new Color(0,0,0);

        Color newColor = new Color(red,green,blue);
        g.setColor(newColor);
        g.fillRect(0,0,1000,500);
        g.setColor(black);
        g.setFont(new Font(null,Font.BOLD,40));
        g.drawString("Happy Birthday!",x,y);
    }

    public static int random(int min, int max)
    {
        int range = max - min + 1;
        int number = (int) (range * Math.random() + min);
        return number;
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(1000, 500);
    }
}

最佳答案

  1. 永远不想显式调用paintComponent。相反,如果您希望面板重新绘制,您可以调用 panel.repaint(),面板会隐式调用它自己的 paintComponent 方法。

  2. 不要在 main 方法中执行所有操作,您会发现使用 static 引用会遇到很多问题。

  3. 不要使用Thread.sleep(),它会阻塞 Event Dispatch Thread .,因为您应该在其中运行 Swing 应用程序。请改用 java.swing.Timer。请参阅this example用于计时器使用。

  4. 如 3 中所述,从 EDT 运行 Swing 应用程序,如下所示

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                new MyApp();
            }
        });
    }
    
  5. 不要设置框架的大小。而是覆盖 DrawingPanelgetPreferredSize()pack() 框架。

  6. 您可以使用 setLocationRelativeTo(null)

    使框架居中
  7. 应该养成使用 @Override 注释的习惯,以确保正确覆盖。

<小时/>

附加到 2。您养成的习惯是从构造函数中完成工作,然后在 main 中调用构造函数。这是对代码的重构,修复了上述所有问题。您可以运行它。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Birthday {

    DrawString panel = new DrawString();

    public Birthday() {
        JFrame f = new JFrame();

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(panel);
        f.setTitle("Happy Birthday!");
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        f.setResizable(false);

        Timer timer = new Timer(500, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                panel.repaint();
            }
        });
        timer.start();
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Birthday();
            }
        });
    }
}

class DrawString extends JPanel {

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

        int width = getWidth();
        int height = getHeight();

        int x = 350;
        int y = 250;
        int red = random(0, 255);
        int green = random(0, 255);
        int blue = random(0, 255);
        Color black = new Color(0, 0, 0);

        Color newColor = new Color(red, green, blue);
        g.setColor(newColor);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(black);
        g.setFont(new Font(null, Font.BOLD, 40));
        g.drawString("Happy Birthday!", x, y);
    }

    public static int random(int min, int max) {
        int range = max - min + 1;
        int number = (int) (range * Math.random() + min);
        return number;
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(1000, 500);
    }
}

关于java - JPanel 导致侧面有额外空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21562638/

相关文章:

java - 无法使用 Java 中的 ProcessBuilder 运行 exe 文件

java - Netbeans JAR 未正常运行/打开

java - 如何在java getResources()中给出相对路径

java - 如何使用嵌入式 JavaFx 小程序更新 Swing 中的饼图 - 空点异常

c++ - Char数据类型和while循环

java - "dereferencing"在Java中有正式或权威的定义吗?

java - 无法理解的运行时错误

c++ - 计数器函数不建立在先前返回的值之上

linux - Bash 循环不工作

java - 如何使 JCombobox 具有更改其他 JCombobox 上的项目的功能