JPanel 未显示

JPanel is not shown

我遇到以下问题类: 我的问题是 JPanel 没有在 JFrame 上呈现。

这是源代码:

MainFrame.class

import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainFrame extends JFrame {

    JPanel panel;

    public MainFrame() {
        setTitle("TestFrame");
        setLayout(null);
        setSize(800, 450);
        setLocation(400, 225);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        panel = new TestPanel();
        getContentPane().add(panel);
        panel.setLocation(0, 0);
        panel.setSize(64, 64);
        panel.setVisible(true);

        setLocationRelativeTo(null);
        setVisible(true);
    }

    public void start() {
        while(true) {
            panel.repaint();

            try {
                Thread.sleep(20);
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        MainFrame frame = new MainFrame();
        frame.start();
        System.exit(-1);
    }
}

TestPanel.class

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

public class TestPanel extends JPanel {

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

        g.setColor(Color.BLUE);
        g.drawString("Test", 0, 0);
    }
}

为什么不能正常使用?

已修复。都是因为代码质量不好。

您没有看到您的字符串,因为您的 y 参数太小 - 它定义了字符串底部的位置,并且由于字符串的最低点位于最顶部,您看不到看到了。

package test;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.*;

public class TestPanel extends JPanel{

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.blue);
        g.drawString("Hello", 0, 10);
    }

    public static void main (String[] args) {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new TestPanel());
        frame.setSize(100, 100);
        frame.setVisible(true);

    }

}

此外,我真的不喜欢你的 start 方法,即使你还没有使用它。您可能想要做的是让面板实现 ActionListener,并在初始化代码的某处创建一个计时器 - Timer t = new Timer (delay, this); t.setRepeats(true); t.start();。这将创建一个新线程,每 delay 毫秒调用一次 actionPerformed 方法。

package test;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class TestPanel extends JPanel implements ActionListener{

    private int red = 0;
    private Timer t;

    TestPanel() {
        t = new Timer(20, this);
        t.setRepeats(true);
        t.start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(new Color (red, 0, 0));
        g.drawString("Hello", 0, 10);

    }

    public static void main (String[] args) {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new TestPanel());
        frame.setSize(100, 100);
        frame.setVisible(true);

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        red = (red + 2) % 255;
        repaint();
    }

}

您已经覆盖了 paintComponents 方法而不是 paintComponent(没有 "s")。

您的无限循环 while(true) 正在阻塞 EDT 线程,这将冻结 GUI。您需要 运行 在新线程上或更好的解决方案是使用 javax.swing.Timer 刷新面板。

此外,正如@CoderinoJavarino 提到的,您需要将 drawString(....) 调用中的 y 坐标设置为更大的值。

如文档中所述:

The baseline of the leftmost character is at position (x, y)

您可以这样做以确保文本不会绘制到屏幕外:

g.drawString("Test", 0, g.getFontMetrics().getHeight());