JFrame 不从单独的类添加图形 [英] JFrame not adding graphics from separate class

查看:22
本文介绍了JFrame 不从单独的类添加图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Swing 很陌生,而且我的 JFrame 中没有显示图形.我应该看到的是一个蓝色矩形在框架中缓慢向下移动,其后面是纯白色背景.然而,当我运行我的主类时,我看到的只是一个普通的 JFrame.这是我的代码:

I'm quite new to swing, and I'm having an issue with graphics not showing up in my JFrame. What I should be seeing is a blue rectangle slowly moving downwards through the frame, and behind it is a plain white background. However, when I run my main class, all I see is a plain JFrame. This is my code:

执行

public class Execute {

public static void main (String[ ] args) {
    GUI gui = new GUI();
    gui.createFrame(800,600);

    ElevatorOne e1 = new ElevatorOne();
    e1.addElevatorOne();
}
}

ElevatorOne 类(初始化和添加图形的地方)

ElevatorOne class (Where the graphics should be initialized and added)

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;

And finally, my GUI class (where frame is created) import 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);
}

}

推荐答案

虽然你得到了一个被接受的答案,但我确实对这个答案有异议,并觉得有必要增加我的两分钱:

While you've got an accepted answer, I do take issue with that answer and feel impelled to add my two cents:

  • 我认为您拥有一个 GUI 类然后让 Elevator1 扩展它没有任何意义.如果您希望 Elevator1 使用 JFrame,那么让它创建一个 JFrame,因为确实不需要或从您的继承中受益.
  • 我自己,我会让 Elevator1 扩展 JPanel,然后让它在自己的 paintComponent 方法中绘制,从而消除了 drawElevatorOne 内部类的需要(应该命名为 DrawElevatorOne 以遵守 Java 命名约定).
  • 您正在 Swing GUI 中使用 Thread.sleep,这样做风险极高.这样做的唯一原因是因为它在主线程中被调用.如果您的代码被正确创建并设置为在 Swing 事件线程中启动和创建 GUI 组件,这将会并且应该失败,因为它会使 Swing 事件线程进入睡眠状态.不要这样做,不要在有在 Swing 事件线程中被调用的任何风险的方法中调用 Thread.sleep.
  • 改为使用 Swing Timer 来管理您的延迟.
  • 不要忘记(几乎)总是在您的override 中调用super.paintComponent(g) 方法.不这样做会破坏 Swing 绘制链并冒着难以调试的严重副作用.
  • I see no purpose to your having a GUI class and then having Elevator1 extend it. If you want Elevator1 to use a JFrame, then have it create a JFrame as there really is no need or benefit from your inheritance.
  • Myself, I'd have Elevator1 extend JPanel and then have it draw in its own paintComponent method, thus eliminating the need for drawElevatorOne inner class (which should be named DrawElevatorOne to adhere to Java naming conventions).
  • You are using Thread.sleep in a Swing GUI which is extremely risky to do. The only reason this works is because it is being called in the main thread. If your code were properly created and set up to start and create GUI components in the Swing event thread, this would and should fail since it would put the Swing event thread to sleep. Don't do this, don't call Thread.sleep in a method that has any risk of being called in the Swing event thread.
  • Instead use a Swing Timer to manage your delay.
  • Don't forget to (almost) always call the super.paintComponent(g) method within your oeverride. To not do this breaks the Swing painting chain and risks significant hard to debug side effects.

例如:

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

这篇关于JFrame 不从单独的类添加图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆