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());
我遇到以下问题类: 我的问题是 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());