java - JFrame 不添加来自单独类的图形

标签 java swing

我是 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/

相关文章:

java - 限制 JTable + 下一个/上一个按钮中显示的行

java - Swing 键盘没有反应

java - Integer.parseInt(String str) java.lang.NumberFormatException : Errors

java - 如何更改Json格式?

java - 连接四个 WinCheck

java - 如何主动更新图像的位置?

java - java中使用Slider旋转对象

java - 数组中的动态第二维

java - 运行 caliper 命令行

java - 在3个二维数组中找到相似的行