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

时间:2014-10-21 16:45:10

标签: java swing user-interface applet japplet

所以我有一个挑战,就是在applet中制作一个这样的螺旋形画。问题是,我是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();
        }

    }
}
}

1 个答案:

答案 0 :(得分:5)

你在睡觉的方法,你应该从不做的事情。在Swing事件线程上调用Thread.sleep(...)是不好的,但在任何绘制方法中执行它都是一种罪过。所以现在小程序无法绘制。请记住,除了绘画之外,任何绘画方法都必须做什么,而且必须非常快速地完成。它不应该做任何程序逻辑,它不应该直接做动画,它应该只是绘画。使用Swing计时器,因为任何类似的问题都会告诉你如何做。

此外,永远不要直接在applet中绘制,而是在applet所持有的JPanel的paintComponent方法中绘制。

因此,创建JPanel,覆盖其paintComponent方法,并使用该类的字段进行绘制。然后更改Timer中这些字段的状态,并在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