我的程序创建了随机着色和大小大小的蠕虫,这些蠕虫在JFrame / JPanel上扩展。随着时间的流逝,蠕虫在随机方向上不断扩展。单击新蠕虫后,新蠕虫便会出现在屏幕上的某个位置。

我的问题出现的地方:

我无法理解如何杀死蠕虫。当我单击kill worm按钮时,我希望蠕虫在屏幕上消失(或停止增长),并将其从arraylist中删除。我什至不知道如何开始这样做。我个人认为删除arraylist的实例是最好的方法,但是我将如何从屏幕上实际删除蠕虫。

下面是我的代码:

主类:

package Main;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) {
    ThreadFrame myFrame = new ThreadFrame();
    myFrame.setSize(new Dimension(640, 480));
    myFrame.setLocationRelativeTo(null);
    myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    myFrame.setTitle("Worms! - Jonathan Perron");
    myFrame.setVisible(true);
    myFrame.setResizable(false);
}
}


ThreadFrame类:

package Main;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ThreadFrame extends JFrame implements ActionListener {

int index = 0;
JButton btnNewWorm, btnKillWorm;
JPanel myPanel2 = new JPanel();
ArrayList<DrawThread> worms = new ArrayList<DrawThread>();

public JPanel getMyPanel2(){
    return this.myPanel2;
}

public ThreadFrame() {
    JPanel myPanel = new JPanel();
    btnNewWorm = new JButton("New Worm");
    btnKillWorm = new JButton("Kill Worm");
    myPanel.setBounds(0, 400, 640, 80);
    myPanel.setLayout(new FlowLayout());
    myPanel2.setSize(new Dimension(640, 400));
    myPanel2.setLayout(null);
    myPanel2.setBackground(Color.WHITE);
    btnNewWorm.setBounds(100, 410, 200, 30);
    btnKillWorm.setBounds(340, 410, 200, 30);
    add(btnNewWorm);
    add(btnKillWorm);
    add(myPanel2);
    add(myPanel);
    btnNewWorm.addActionListener(this);
    btnKillWorm.addActionListener(this);
}

public void actionPerformed(ActionEvent AE) {
    if(AE.getSource() == btnNewWorm){
        DrawThread dw = new DrawThread(myPanel2);
        worms.add(dw);
        System.out.println("New worm!");
    }
    if(AE.getSource() == btnKillWorm){
        //stop worms from growing or complete disappear from JFrame
        System.out.println("Kill worm!");
    }
}

}


DrawThread类:

package Main;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.util.Random;
import javax.swing.JPanel;

public class DrawThread extends Thread implements Runnable{

Random rand = new Random();
JPanel panel2 = new JPanel();
Graphics2D g, graph;
private int sleepTime, wormDiameter, hue, saturation, brightness, randomWidth, randomHeight;

public DrawThread(int sleepTime, int wormDiameter, int hue, int saturation, int brightness, int randomWidth, int randomHeight, JPanel myPanel2) {
    this.sleepTime = sleepTime;
    this.wormDiameter = wormDiameter;
    this.brightness = brightness;
    this.hue = hue;
    this.saturation = saturation;
    this.randomWidth = randomWidth;
    this.randomHeight = randomHeight;
    g = (Graphics2D) myPanel2.getGraphics();
}

public void setColor(int hue){
    this.hue = hue;
}

public int getSleepTime(){
    return sleepTime;
}

public void setSleepTime(int sleepTime){
    this.sleepTime = sleepTime;
}
public DrawThread(JPanel myPanel2){

    //get panel dimensions
    int panelWidth = myPanel2.getWidth();
    int panelHeight = myPanel2.getHeight();

    //worm location
    randomWidth = rand.nextInt(panelWidth);
    randomHeight = rand.nextInt(panelHeight);

    //worm size
    wormDiameter = rand.nextInt(7)+3;

    //worm color
    hue = rand.nextInt(255);
    saturation = rand.nextInt(255);
    brightness = rand.nextInt(255);
    Color color = new Color(hue, saturation, brightness);

    //sleep
    sleepTime = rand.nextInt(80) + 20;

    //Graphics
    g = (Graphics2D) myPanel2.getGraphics();
    g.setColor(color);
    Ellipse2D.Double ellipse2D = new Ellipse2D.Double(randomWidth, randomHeight, wormDiameter, wormDiameter);
    g.fill(ellipse2D);
    Thread thread1 = new Thread(new DrawThread(sleepTime, wormDiameter, hue, saturation, brightness, randomWidth, randomHeight, myPanel2));
    thread1.start();
}

public void run(){
    try {
        while(true) {
            Thread.sleep(sleepTime);
            Color color = new Color(hue, saturation, brightness);
            g.setColor(color);
            int addedHeight = 0, addedWidth = 0;
            int random = rand.nextInt(8);

            //determining the worms next move location
            if(random == 0){ addedWidth = 0;  addedHeight = 1;  } //North
            if(random == 1){ addedWidth = 1;  addedHeight = 1;  } //North-East
            if(random == 2){ addedWidth = 1;  addedHeight = 0;  } //East
            if(random == 3){ addedWidth = 1;  addedHeight = -1; } //South-East
            if(random == 4){ addedWidth = 0;  addedHeight = -1; } //South
            if(random == 5){ addedWidth = -1; addedHeight = -1; } //South-West
            if(random == 6){ addedWidth = -1; addedHeight = 0;  } //West
            if(random == 7){ addedWidth = -1; addedHeight = 1;  } //North-West

            //Prevent worms from getting off the screen
            if(randomHeight >= 480){ addedHeight = -1; }
            if(randomHeight <= 0){ addedHeight = 1; }
            if(randomWidth >= 640){ addedWidth = -1; }
            if(randomWidth <= 0){ addedWidth = 1; }

            randomWidth += addedWidth;
            randomHeight += addedHeight;
            Ellipse2D.Double e = new Ellipse2D.Double(randomWidth, randomHeight, wormDiameter, wormDiameter);
            g.fill(e);
            }
    }
    catch (InterruptedException e) {
        System.out.println("ERROR!");
    }
}

public String toString() {
    String result = "SleepTime: " + sleepTime + "\nWorm Diameter: " + wormDiameter
            + "\nHue: " + hue + "\nSaturation: " + saturation + "\nBrightness: "
            + brightness + "\nWidth: " + randomWidth + "\nHeight: " + randomHeight;
    return result;
}
}


任何帮助是极大的赞赏! :)

编辑:这是我的老师给编写此程序的作业。

================================================== ========================

在本次作业中,我们将编写一个在窗口中绘制“蠕虫”图像的程序。的
蠕虫会随着时间的增长而向随机方向移动。每个蠕虫将具有不同的颜色,并且
以不同的速度增长。一个单独的Thread对象将管理每个蠕虫的绘制。这是一个
两个蠕虫长出一段时间后窗口的外观示例。

写一个名为ThreadFrame的类,该类扩展了JFrame。此类应包含一个主要方法,
创建此类的一个实例。这将产生一个外观类似于您所看到的GUI
以上。将窗口设置为640 x 480像素,并且不允许用户调整其大小。将两个JPanels添加到
内容窗格,在中心区域将绘制线程的白色窗格,在其中的灰色窗格
南部地区持有标有“ New Worm”和“ Kill Worm”的JButton。

将动作侦听器添加到“新蠕虫”按钮,以便在单击它时创建一个新实例
类DrawThread(稍后将描述)的类,将其添加到ArrayList并启动它。添加动作
侦听器“杀害蠕虫”按钮,以便单击该按钮时,它会从中删除第一个DrawThread
ArrayList并中断它。

DrawThread类扩展了Thread,并完成了程序的大部分工作。这堂课会画
在ThreadFrame的上部面板上,因此必须将此面板的引用传递给构造函数
从ThreadFrame调用此构造方法时,使用DrawThread。构造函数应执行
以下任务:

将JPanel引用(作为参数接收)分配给该对象的实例变量。
获取JPanel的图形上下文(使用getGraphics方法),将其强制转换为Graphics2D类型,然后
将其分配给实例变量。
确定此JPanel的宽度和高度,然后保存这些值。
创建一个Color对象,使用三个参数的随机选择值来设置红色,绿色和
蓝色强度,然后将此对象分配给实例变量。
随机选择此线程的睡眠时间,介于20到100毫秒之间。这将决定
图像增长的速度。

最佳答案

关于您的指示


  写一个名为ThreadFrame的类,该类扩展了JFrame。此类应包含一个创建该类实例的main方法。这将产生一个GUI,其外观类似于您在上面看到的外观。将窗口设置为640 x 480像素,并且不允许用户调整其大小。在内容窗格中添加两个JPanel,在中间区域绘制一个线程的白色面板,在南部区域保留一个标记为“新蠕虫”和“杀死蠕虫”的JButton的灰色面板。


好,你知道了


  在“ New Worm”按钮上添加一个动作侦听器,以便在单击它时会创建一个名为DrawThread(稍后将描述)的类的新实例,将其添加到ArrayList并启动它。


同样,您已完成此操作。


  在“杀死蠕虫”按钮上添加一个动作侦听器,以便在单击它时将其从ArrayList中删除第一个DrawThread并中断它。


分解:


从ArrayList获取最新的蠕虫-您将使用两个ArrayList方法size()get(...)来实现此目的。试试看。
然后中断线程。从数组列表中获取对象后,您将需要在其上调用Thread方法,而我猜测您将能够找出哪种方法正确(请阅读此说明,即“和中断它”)? ;)




编辑
请注意,他的建议不好,如果我需要,我不会聘请您的讲师或课程主管作为Swing程序员。



编辑
只是为了笑,这是另一种编码这种事情的方法。请注意,它不满足您的作业要求(这是我毫不犹豫地发布它的原因之一),但是它显示了我认为更好的Swing行为:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.*;

public class MyWormMain {

   private static void createAndShowGui() {
      MyWormDrawPanel drawPanel = new MyWormDrawPanel();
      MyWormButtonPanel btnPanel = new MyWormButtonPanel(drawPanel);

      JFrame frame = new JFrame("Worms");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(drawPanel, BorderLayout.CENTER);
      frame.getContentPane().add(btnPanel.getMainPanel(), BorderLayout.SOUTH);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

@SuppressWarnings("serial")
class MyWormDrawPanel extends JPanel {
   private static final int PREF_W = 640;
   private static final int PREF_H = 480;
   private static final Color BACKGROUND = Color.WHITE;
   private static final int TIMER_DELAY = 50;
   private List<MyWorm> wormList = new ArrayList<>();
   private Timer wormTimer;
   private Random random = new Random();

   public MyWormDrawPanel() {
      setBackground(BACKGROUND);
      wormTimer = new Timer(TIMER_DELAY, new WormTimerListener());
      wormTimer.start();
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      for (MyWorm worm : wormList) {
         worm.draw(g2);
      }
   }

   public void addWorm() {
      int r = random.nextInt(128) + 128;
      int g = random.nextInt(128) + 128;
      int b = random.nextInt(128) + 128;

      int rand = random.nextInt(3);
      switch (rand) {
      case 0:
         r /= 3;
         break;
      case 1:
         g /= 3;
         break;
      case 2:
         b /= 3;

      default:
         break;
      }
      Color color = new Color(r, g, b);

      int x = random.nextInt(PREF_W);
      int y = random.nextInt(PREF_H);
      Point head = new Point(x, y);
      wormList.add(new MyWorm(color, head, PREF_W, PREF_H));
   }

   public void killWorm() {
      if (wormList.size() > 0) {
         wormList.remove(wormList.size() - 1);
      }
   }

   private class WormTimerListener implements ActionListener {
      public void actionPerformed(ActionEvent e) {
         for (MyWorm worm : wormList) {
            worm.grow();
         }
         repaint();
      };
   }
}

@SuppressWarnings("serial")
class MyWormButtonPanel {
   private static final int GAP = 15;
   private JPanel mainPanel = new JPanel();
   private MyWormDrawPanel drawPanel;

   public MyWormButtonPanel(MyWormDrawPanel drawPanel) {
      this.drawPanel = drawPanel;
      mainPanel.setLayout(new GridLayout(1, 0, GAP, GAP));
      mainPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
      mainPanel.add(new JButton(new AddWormAction("Add Worm", KeyEvent.VK_A)));
      mainPanel.add(new JButton(new KillWormAction("Kill Worm", KeyEvent.VK_K)));
   }

   public JComponent getMainPanel() {
      return mainPanel;
   }

   private class AddWormAction extends AbstractAction {

      public AddWormAction(String name, int mnemonic) {
         super(name);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         drawPanel.addWorm();
      }
   }

   private class KillWormAction extends AbstractAction {

      public KillWormAction(String name, int mnemonic) {
         super(name);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         drawPanel.killWorm();
      }
   }

}

class MyWorm {
   private static final int MAX_DIR = 360;
   private static final int SEG_WIDTH = 20;
   private static final int MAX_RAND_DIR = 60;
   private Color color;
   private List<Point> body = new ArrayList<>();
   private Random random = new Random();
   private int direction;
   private int maxX;
   private int maxY;

   public MyWorm(Color color, Point head, int maxX, int maxY) {
      this.color = color;
      body.add(head);
      direction = random.nextInt(MAX_DIR);
      this.maxX = maxX;
      this.maxY = maxY;
   }

   public void grow() {
      Point lastPt = body.get(body.size() - 1);
      int x = lastPt.x
            + (int) (SEG_WIDTH * 3 * Math.cos(Math.toRadians(direction)) / 4.0);
      int y = lastPt.y
            + (int) (SEG_WIDTH * 3 * Math.sin(Math.toRadians(direction)) / 4.0);

      if (x < 0) {
         x = maxX - 1;
      }
      if (x > maxX) {
         x = 0;
      }
      if (y < 0) {
         y = maxY - 1;
      }
      if (y > maxY) {
         y = 0;
      }

      Point nextPoint = new Point(x, y);
      direction += random.nextInt(MAX_RAND_DIR) - MAX_RAND_DIR / 2;

      body.add(nextPoint);
   }

   public void draw(Graphics2D g2) {
      Graphics2D g2b = (Graphics2D) g2.create();
      g2b.setColor(color);
      for (Point p : body) {
         int x = p.x - SEG_WIDTH / 2;
         int y = p.y - SEG_WIDTH / 2;
         int width = SEG_WIDTH;
         int height = SEG_WIDTH;
         g2b.fillOval(x, y, width, height);
      }
      g2b.dispose();
   }

}

07-26 09:27