Java JApplet : Why aren't my components appearing on screen?

标签 java swing user-interface applet japplet

所以我面临着在小程序中制作其中一个呼吸描记器图画的挑战。问题是,我是 Java 新手,完全不知道如何让任何组件出现在屏幕上。我希望有人可以添加一行额外的代码来解决这个问题,尽管我真的很感激任何答案:)

import javax.swing.JApplet;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.Toolkit;


public class SpaceCadets3_WB extends JApplet {

int numOfPoints = 1080;
int[] x = new int[numOfPoints];
int[] y = new int[numOfPoints];
int x1, x2, y1, y2, width, height, animationSleep = 0;
int R = 75;
int r = 10;
int O = 75;
JTextField changeNumOfPoints = new JTextField(15);

public SpaceCadets3_WB() {

}

public void start() {
    this.setSize(600, 600);
    this.setBackground(new Color(100,100,255));
    this.getContentPane().setLayout(null);
    this.getContentPane().add(changeNumOfPoints);
    changeNumOfPoints.setVisible(true);
    changeNumOfPoints.setLocation(width - changeNumOfPoints.getSize().width - 25, 25);
    }

public void calculatePoints(){
    width = SpaceCadets3_WB.this.getWidth();
    height = SpaceCadets3_WB.this.getHeight();
    for(int t = 0; t<numOfPoints; t++){
        x[t] = (int) ((R+r)*Math.cos(t) - (r+O)*Math.cos(((R+r)/r)*t) + width/2);
        y[t] = (int) ((R+r)*Math.sin(t) - (r+O)*Math.sin(((R+r)/r)*t) + height/2);
    }
}

public void paint(Graphics g){
    g.setColor(Color.RED);
    calculatePoints();
    for(int i = 0; i<numOfPoints;i++){
        x1 = x[i];
        x2 = x[i+1];
        y1 = y[i];
        y2 = y[i+1];
        g.drawLine(x1, y1, x2, y2);

        try {
            Thread.sleep(animationSleep);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
}

最佳答案

你在绘画方法上 sleep ,这是你不应该永远做的事情。在 Swing 事件线程上调用 Thread.sleep(...) 是不好的,但在任何绘画方法中这样做都是一种罪过。所以现在小程序无法绘制。请记住,任何绘画方法都必须只做绘画,而且必须速度极快。它不应该执行任何程序逻辑,它不应该直接执行动画,它应该只是绘画。使用 Swing 计时器,因为任何类似的问题都会向您展示如何操作。

此外,切勿直接在小程序中进行绘制,而应在小程序所拥有的 JPanel 的 PaintComponent 方法中进行绘制。

因此,创建您的 JPanel,重写其 PaintComponent 方法,并使用该类的字段进行绘制。然后更改计时器中这些字段的状态并在 JPanel 上调用 repaint()。

<小时/>

编辑 是的,您应该避免使用空布局,因为这会阻止您轻松、充分地向 GUI 添加组件。相反,在这种情况下,FlowLayout(JPanel 的默认布局)会很好用。

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ExecutionException;

import javax.swing.*;

@SuppressWarnings("serial")
public class SpaceCadets extends JApplet {
   @Override
   public void init() {
      try {
         SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
               SpaceCadetsPanel panel = new SpaceCadetsPanel();
               getContentPane().add(panel);
               setSize(SpaceCadetsPanel.PREF_W, SpaceCadetsPanel.PREF_H);
            }
         });
      } catch (InvocationTargetException | InterruptedException e) {
         e.printStackTrace();
      }
   }
}

@SuppressWarnings("serial")
class SpaceCadetsPanel extends JPanel {
   public static final int PREF_W = 600;
   public static final int PREF_H = 600;
   public final static int TOTAL_POINTS = 1080;
   private static final int R = 75;
   private static final int R2 = 10;
   private static final int O = 75;
   private static final Color DRAW_COLOR = Color.RED;
   private static final int ANIMATION_DELAY = 20;
   private Point[] pts;
   private JSpinner pointCountSpinner = new JSpinner(new SpinnerNumberModel(
         800, 100, 1080, 1));
   private JButton doItButton = new JButton(new DoItBtnAction("Do It!"));
   private BufferedImage bufImg = new BufferedImage(PREF_W, PREF_H,
         BufferedImage.TYPE_INT_ARGB);
   private Timer timer;
   public int imageIndex;
   private CalcWorker calcWorker;
   public Graphics2D g2;

   public SpaceCadetsPanel() {
      System.out.println(pointCountSpinner.getEditor().getClass());
      add(pointCountSpinner);
      add(doItButton);
      setBackground(Color.white);
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (bufImg != null) {
         g.drawImage(bufImg, 0, 0, this);
      }
   }

   class DoItBtnAction extends AbstractAction {
      public DoItBtnAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         imageIndex = 0;
         if (timer != null && timer.isRunning()) {
            timer.stop();
         }
         if (g2 != null) {
            g2.dispose();
         }
         pts = new Point[0];
         bufImg = new BufferedImage(PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
         g2 = bufImg.createGraphics();
         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);
         g2.setColor(DRAW_COLOR);
         int totalPoints = 0;
         totalPoints = ((Integer) pointCountSpinner.getValue()).intValue();

         timer = new Timer(ANIMATION_DELAY, new TimerListener(totalPoints));
         calcWorker = new CalcWorker(totalPoints);
         calcWorker.addPropertyChangeListener(new CalcWorkerListener());
         calcWorker.execute();
      }
   }

   class CalcWorker extends SwingWorker<Point[], Void> {
      private int totalPoints;

      public CalcWorker(int totalPoints) {
         this.totalPoints = totalPoints;
      }

      @Override
      protected Point[] doInBackground() throws Exception {
         Point[] pts2 = new Point[totalPoints];
         for (int i = 0; i < pts2.length; i++) {
            int x = (int) ((R + R2) * Math.cos(i) - (R2 + O)
                  * Math.cos(((R + R2) / R2) * i) + PREF_W / 2);
            int y = (int) ((R + R2) * Math.sin(i) - (R2 + O)
                  * Math.sin(((R + R2) / R2) * i) + PREF_H / 2);
            pts2[i] = new Point(x, y);
         }
         return pts2;
      }
   }

   class CalcWorkerListener implements PropertyChangeListener {
      @Override
      public void propertyChange(PropertyChangeEvent evt) {
         if (SwingWorker.StateValue.DONE == evt.getNewValue()) {
            try {
               pts = calcWorker.get();
               timer.start();
            } catch (InterruptedException | ExecutionException e) {
               e.printStackTrace();
            }
         }
      }
   }

   class TimerListener implements ActionListener {
      private int totalPoints;

      public TimerListener(int totalPoints) {
         this.totalPoints = totalPoints;
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         int x1 = pts[imageIndex].x;
         int y1 = pts[imageIndex].y;
         int x2 = pts[imageIndex + 1].x;
         int y2 = pts[imageIndex + 1].y;
         g2.drawLine(x1, y1, x2, y2);
         repaint();
         imageIndex++;

         if (imageIndex == totalPoints - 1) {
            ((Timer) e.getSource()).stop();
         }

      }
   }
}
<小时/>

显示为,

enter image description here

关于Java JApplet : Why aren't my components appearing on screen?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26491937/

相关文章:

java - 乘以大长整型会导致精度损失

java - swing 避免重写 jframe 选项

java - 在JavaFX中同时进行场景和舞台交互

Ruby - 未知方法初始化

java - Cassandra 使用 LocalDate 截断毫秒

java - Log4j 不工作

java - ( Android ) 网页 View 刷新按钮

java - 为什么应该使用 awt.Dimension 类?

使用现有 JProgressBar 的 Java ProgressMonitorInputStream

python - 在 python 中创建类似于 MS 计算器的 GUI 计算器