简体   繁体   English

Java JApplet:为什么我的组件没有出现在屏幕上?

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

So I've got this challenge to make one of those spirograph drawrings in an applet. 因此,要在小程序中制作这些呼吸描记器绘图之一,我面临着挑战。 The problem is, I'm new to Java and have absolutely no idea how to get any components appearing on the screen. 问题是,我是Java新手,绝对不知道如何让任何组件出现在屏幕上。 I'm hoping someone can just add an extra line of code to fix this, though I'm really grateful for any answers :) 我希望有人可以添加一行额外的代码来解决此问题,尽管我真的很感谢任何回答:)

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

    }
}
}

Your sleeping the paint method, something you should never do. 您睡觉的绘画方法,这是您永远都不要做的。 It's bad to call Thread.sleep(...) on the Swing event thread, but it's a sin to do it in any painting method. 在Swing事件线程上调用Thread.sleep(...)很不好,但是在任何绘画方法中这样做都是一种罪过。 So now the applet can't draw. 因此,现在小程序无法绘制。 Remember that any painting method must do nothing but painting, and must do it blazingly fast. 请记住,任何绘画方法都只能做绘画,而且必须非常快地完成。 It shouldn't do any program logic, it shouldn't directly do animation, it should just paint. 它不应该执行任何程序逻辑,不应该直接执行动画,而应该绘制。 Use a Swing timer as any similar question will show you how to do. 使用Swing计时器,因为任何类似的问题都会向您展示如何操作。

Also, never draw directly in the applet but instead in the paintComponent method of a JPanel that the applet holds. 另外,永远不要直接在小程序中绘制,而要在小程序所保存的JPanel的paintComponent方法中绘制。

So create your JPanel, override its paintComponent method, and draw using fields of the class. 因此,创建您的JPanel,重写其paintComponent方法,并使用该类的字段进行绘制。 Then change the state of those fields in your Timer and call repaint() on the JPanel. 然后在Timer中更改这些字段的状态,然后在JPanel上调用repaint()。


Edit And yes, you should avoid using null layouts as that's preventing you from easily and adequately adding components to your GUI. 编辑是的,您应该避免使用空布局,因为这会阻止您轻松,适当地向GUI添加组件。 Instead in this situation, a FlowLayout, the default layout for JPanel, would work great. 相反,在这种情况下,FlowLayout(JPanel的默认布局)会很好用。

For example: 例如:

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

      }
   }
}

Which displays as, 显示为

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM