JPanel未显示

时间:2016-07-10 19:26:30

标签: java swing jframe jpanel

我在以下课程中遇到一些问题: 我的问题是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);
    }
}

为什么它无法正常工作?

固定。都是由于代码质量不好造成的。

2 个答案:

答案 0 :(得分:2)

你没有看到你的字符串,因为你的y参数太小了 - 它定义了字符串底部的位置,并且由于字符串的最低点位于最顶层,你可以&#39看到了。

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();。这将创建一个新线程,每隔actionPerformed毫秒调用delay方法。

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

}

答案 1 :(得分:2)

您已覆盖paintComponents方法而不是paintComponent(没有“s”)。

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

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

正如文档中提到的那样:

  

最左边字符的基线位于(x,y)位置

您可以执行以下操作以确保文本不会在屏幕外绘制:

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