我是 swing 的新手,我遇到了图形未显示在我的 JFrame 中的问题。我应该看到的是一个蓝色矩形在框架中缓慢向下移动,在它后面是纯白色背景。但是,当我运行我的主类时,我看到的只是一个普通的 JFrame。这是我的代码:
执行
类
public class Execute {
public static void main (String[ ] args) {
GUI gui = new GUI();
gui.createFrame(800,600);
ElevatorOne e1 = new ElevatorOne();
e1.addElevatorOne();
}
}
ElevatorOne
类(应在其中初始化和添加图形)
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class ElevatorOne extends GUI{
int y = 100;
public void addElevatorOne() {
drawElevatorOne drawE1 = new drawElevatorOne();
frame.getContentPane().add(drawE1);
for(int i = 0; i < 130; i++) {
y++;
drawE1.repaint();
try {
Thread.sleep(50);
} catch (Exception ex) { }
}
}
@SuppressWarnings("serial")
class drawElevatorOne extends JPanel{
public void paintComponent(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLUE);
g.drawRect(200,y,40,60);
}
}
}
最后,我的 GUI
类(创建 frame
的地方)
导入 javax.swing.JFrame;
public class GUI {
JFrame frame = new JFrame();
public void createFrame(int x, int y) {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setResizable(false);
frame.setSize(x, y);
}
}
最佳答案
虽然您已经接受了一个答案,但我确实对该答案有异议,并觉得有必要加上我的两分钱:
- 我认为您拥有一个 GUI 类然后让 Elevator1 扩展它没有任何意义。如果您希望 Elevator1 使用 JFrame,那么让它创建一个 JFrame,因为您确实不需要继承,也没有从中受益。
- 我自己,我会让 Elevator1 扩展 JPanel,然后让它在自己的 paintComponent 方法中绘制,从而消除 drawElevatorOne 内部类的需要(应该命名为
DrawElevatorOne
以遵守 Java 命名约定). - 您正在 Swing GUI 中使用 Thread.sleep,这样做的风险极大。这样做的唯一原因是因为它在主线程中被调用。如果您的代码已正确创建并设置为在 Swing 事件线程中启动和创建 GUI 组件,那么这将并且应该失败,因为它会使 Swing 事件线程进入 hibernate 状态。不要这样做,不要在有任何在 Swing 事件线程中调用风险的方法中调用 Thread.sleep。
- 改为使用 Swing Timer 来管理您的延迟。
- 不要忘记(几乎)总是在您的 oeverride 中调用
super.paintComponent(g)
方法。不这样做会破坏 Swing 绘画链,并冒着难以调试副作用的风险。
例如:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class ElevatorTest {
private static final int PREF_W = 800;
private static final int PREF_H = 600;
private static void createAndShowGui() {
MyElevator mainPanel = new MyElevator(PREF_W, PREF_H);
JFrame frame = new JFrame("Elevator Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
// start everything on the Swing event thread
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyElevator extends JPanel {
private static final Color BACKGROUND = Color.white;
private static final int ELEVATOR_X = 200;
private static final int ELEVATOR_W = 40;
private static final int ELEVATOR_H = 60;
private static final int TIMER_DELAY = 50;
public static final int MAX_ELEVATOR_Y = 130;
private static final Color ELEVATOR_COLOR = Color.blue;
private int prefW;
private int prefH;
private int elevatorY = 0;
public MyElevator(int prefW, int prefH) {
this.prefW = prefW;
this.prefH = prefH;
setBackground(BACKGROUND);
new Timer(TIMER_DELAY, new TimerListener()).start();
}
@Override
protected void paintComponent(Graphics g) {
// Don't forget to call the super method
super.paintComponent(g);
g.setColor(ELEVATOR_COLOR);
g.fillRect(ELEVATOR_X, elevatorY, ELEVATOR_W, ELEVATOR_H);
}
// to help size our GUI properly
@Override
public Dimension getPreferredSize() {
Dimension superSz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSz;
}
int w = Math.max(superSz.width, prefW);
int h = Math.max(superSz.height, prefH);
return new Dimension(w, h);
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (elevatorY >= MAX_ELEVATOR_Y) {
// if elevator at max, stop thimer
((Timer) e.getSource()).stop();
} else {
// advance elevator and draw it
elevatorY++;
repaint();
}
}
}
}
关于java - JFrame 不添加来自单独类的图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30902987/