java - 尝试在 Java 中使用 MouseListeners 绘制矩形会导致程序崩溃并且不会生成异常

标签 java applet awt mouselistener

小程序应该绘制基于使用 MouseListener 拖出的矩形,同时球在小程序周围弹跳。监听器似乎可以工作,打印出鼠标正在工作的位置,并且球工作得很好。但是,一旦程序运行并且拖动鼠标,小程序/浏览器就会卡住,并且不会向控制台输出。

这是所有代码。我只想发布绘图方法,但我认为它可能不仅仅在那里。

import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.util.Vector;

public class Bounce2 extends Applet implements ActionListener, AdjustmentListener, MouseListener, MouseMotionListener, Runnable
{
  //runtime variables
  boolean running = false;
  boolean kill = false;

  //buttons
  Button runbutton = new Button("Run");
  Button pausebutton = new Button("Pause");
  Button quitbutton = new Button("Quit");

  //text
  Label speedlabel = new Label("Speed");
  Label sizelabel = new Label("Size");

  Panel drawingpanel;

  //scrollbars
  private final int barHeight = 20, SLIDER_WIDTH = 10, MAXSPEED = 110, MINSPEED = 0, MAX_SIZE = 110, MIN_SIZE = 10;
  Scrollbar speedbar = new Scrollbar(Scrollbar.HORIZONTAL, MAXSPEED/2, SLIDER_WIDTH, MINSPEED, MAXSPEED);
  Scrollbar sizebar = new Scrollbar(Scrollbar.HORIZONTAL, MAX_SIZE/2, SLIDER_WIDTH, MIN_SIZE, MAX_SIZE);

  //drawn objs
  Ball ball;
  int size = 50;
  private Graphics obj;
  Image offscreen = null;
  Point loc = new Point(100,100); //location of the ball
  private Thread ballThread;

  //boundaries
  int boundx = 640;
  int boundy = 400;

  //directions
  int dx = 1; //1 = left, -1 = right
  int dy = 1; //1 = up, -1 = down

  //speed
  int speed = MAXSPEED/2;
  int delay = MAXSPEED - speed;

  //rectangle vector and associated things
  Vector r = new Vector();
  boolean flag = false;
  Point start, cur, end;

  //initialize the applet and draw everything
  public void init()
  {
    double colWeight[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//15 cols
    double rowWeight[] = {1,1,1,1,1,1,1,1,1,1}; //10 rows
    int colWidth[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//15 cols
    int rowHeight[] = {1,1,1,1,1,1,1,1,1,1}; //10 rows
    GridBagConstraints c = new GridBagConstraints();
    GridBagLayout gbl = new GridBagLayout();
    gbl.rowHeights = rowHeight;
    gbl.rowWeights = rowWeight;
    gbl.columnWeights = colWeight;
    gbl.columnWidths = colWidth;
    c.anchor = GridBagConstraints.CENTER;

    setBounds(0,0,480,640);
    setLayout(new BorderLayout());
    Panel controlpanel = new Panel();
    controlpanel.setLayout(gbl);
    controlpanel.setSize(640,80);

    drawingpanel = new Panel();
    drawingpanel.setSize(640,400);
    ball = new Ball();
    drawingpanel.setLayout(new BorderLayout());
    drawingpanel.add("Center",ball);

    //speed scrollbar
    c.weightx = 1;
    c.weighty = 1;
    c.gridwidth = 3;
    c.gridheight = 1;
    c.gridx = 1;
    c.gridy = 7;
    c.fill= GridBagConstraints.HORIZONTAL;
    gbl.setConstraints(this.speedbar,c);

    //run button
    c.weightx = 1;
    c.weighty = 1;
    c.gridwidth = 2;
    c.gridheight = 1;
    c.gridx = 5;
    c.gridy = 7;
    c.fill= GridBagConstraints.HORIZONTAL;
    gbl.setConstraints(this.runbutton,c);

    //pause button
    c.weightx = 1;
    c.weighty = 1;
    c.gridwidth = 2;
    c.gridheight = 1;
    c.gridx = 8;
    c.gridy = 7;
    c.fill= GridBagConstraints.HORIZONTAL;
    gbl.setConstraints(this.pausebutton,c);

    //size scrollbar
    c.weightx = 1;
    c.weighty = 1;
    c.gridwidth = 3;
    c.gridheight = 1;
    c.gridx = 11;
    c.gridy = 7;
    c.fill= GridBagConstraints.HORIZONTAL;
    gbl.setConstraints(this.sizebar,c);

    //speed text label
    c.weightx = 1;
    c.weighty = 1;
    c.gridwidth = 3;
    c.gridheight = 1;
    c.gridx = 1;
    c.gridy = 8;
    c.fill= GridBagConstraints.HORIZONTAL;
    gbl.setConstraints(this.speedlabel,c);

    //size text label
    c.weightx = 1;
    c.weighty = 1;
    c.gridwidth = 3;
    c.gridheight = 1;
    c.gridx = 11;
    c.gridy = 8;
    c.fill= GridBagConstraints.HORIZONTAL;
    gbl.setConstraints(this.sizelabel,c);

    //quit button
    c.weightx = 1;
    c.weighty = 1;
    c.gridwidth = 3;
    c.gridheight = 1;
    c.gridx = 6;
    c.gridy = 9;
    c.fill= GridBagConstraints.HORIZONTAL;
    gbl.setConstraints(this.quitbutton,c);

    //add to the screen
    controlpanel.add(this.speedbar);
    controlpanel.add(this.runbutton);
    controlpanel.add(this.pausebutton);
    controlpanel.add(this.sizebar);
    controlpanel.add(this.speedlabel);
    controlpanel.add(this.sizelabel);
    controlpanel.add(this.quitbutton);

    //add listners
    speedbar.addAdjustmentListener(this);
    runbutton.addActionListener(this);
    pausebutton.addActionListener(this);
    sizebar.addAdjustmentListener(this);
    quitbutton.addActionListener(this);
    ball.addMouseListener(this);
    ball.addMouseMotionListener(this);

    //add the panels
    add("South", controlpanel);
    add("Center", drawingpanel);

    //drawing paramaters
    loc = new Point(loc.x+dx, loc.y+dy);
  }

  public void start()
  {
    if (ballThread == null)
    {
      ballThread = new Thread(this);
      ballThread.start();
    }
  }

  public void run()
  {
    Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    while (!kill)
    {
      if (running)
      {
        ball.repaint();
      }
      try
      {
        Thread.sleep(delay);
      }
      catch(InterruptedException e){System.err.println("Interrupted.");}
    }
    stop();
  }

  public void paint(Graphics g)
  {
    super.paint(g);
  }

  //class to handle animations
  class Ball extends Canvas
  {     
    public void move()
    {
      //if it will hit the right or left, flip the x direction and set it
      if (loc.x+size >= boundx || loc.x <= 0)
      { dx *= -1; }
      loc.x += dx;
      //if it will hit the top or bottom, flip the y direction and set it
      if (loc.y+size >= boundy || loc.y <= 0)
      { dy *= -1; }
      loc.y += dy;
    }

    public void update(Graphics g)
    {
      super.update(g);
      Graphics buffer;
      if (offscreen == null)
      {
        offscreen = createImage(getWidth(), getHeight());
      }
      buffer = offscreen.getGraphics();
      buffer.setColor(getBackground());
      buffer.fillRect(loc.x,loc.y,boundx, boundy);
      mypaint(buffer);
      g.drawImage(offscreen, 0, 0, this);

    }

    public void mypaint(Graphics g)
    {
      //update loc
      move();

      //draw
      g.setColor(Color.BLACK);
      g.drawOval(loc.x, loc.y, size, size);
      g.fillOval(loc.x, loc.y, size, size);

      if (flag)
      {
        if (!r.isEmpty())
        {
            int i = 0;
            while (i <= r.size())
            {
                g.drawRect(start.x,start.y,(cur.x-start.x),(cur.y-start.y));
                g.setColor(Color.gray);
                g.fillRect(start.x,start.y,(cur.x-start.x),(cur.y-start.y));
            }
          System.err.println(start + ", " + cur);
        }
      }
    }
  }


    public void mouseClicked(MouseEvent m)
    {
        Point p = m.getPoint();
        //if p intersects rect in r, remove all r
    }

    public void mousePressed(MouseEvent m)
    {
        flag = true;
        start = m.getPoint();
    }

    public void mouseDragged(MouseEvent m)
    {
        if (flag == true)
        {
            cur = m.getPoint();
        }
    }

    public void mouseReleased(MouseEvent m)
    {
        end = m.getPoint();
        flag = false;
    r.add(new Rectangle(start.x,start.y,end.x,end.y));
    } 

    public void mouseEntered(MouseEvent m){}
    public void mouseExited(MouseEvent m){}
    public void mouseMoved(MouseEvent m){}

  public void actionPerformed(ActionEvent e)
  {
    Object source = e.getSource();
    if (source == this.runbutton)
    {
      running = true;
    }
    else if (source == this.pausebutton)
    {
      running = false;
    }
    else if (source == this.quitbutton)
    {
      //kill processes
      kill = true;
      //remove listeners
      stop();
    }
  }

  public void adjustmentValueChanged(AdjustmentEvent e)
  {
    Object source = e.getSource();
    //set the new size.
    if (source == sizebar)
    {
      //check for clipping
      int newsize = sizebar.getValue();

      // x
      if (loc.x+newsize >= boundx)
      {
        newsize = boundx - loc.x - 1;
        sizebar.setValue(newsize);
      }

      // y
      if (loc.y+newsize >= boundy + 100)
      {
        newsize = boundy+100 - loc.y - 1;
        sizebar.setValue(newsize);
      }
      size = newsize;
    }
    if (source == speedbar)
    {
      speed = speedbar.getValue();
      delay = MAXSPEED - speed;
    }
  }

  public void stop()
  {
    this.speedbar.removeAdjustmentListener(this);
    this.runbutton.removeActionListener(this);
    this.pausebutton.removeActionListener(this);
    this.sizebar.removeAdjustmentListener(this);
    this.quitbutton.removeActionListener(this);
    this.removeMouseListener(this);
    this.removeMouseMotionListener(this);
    Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
  }
}   

最佳答案

好吧,这就是你的问题......

int i = 0;
while (i <= r.size()) {
    g.drawRect(start.x, start.y, (cur.x - start.x), (cur.y - start.y));
    g.setColor(Color.gray);
    g.fillRect(start.x, start.y, (cur.x - start.x), (cur.y - start.y));
}

你有一个无限循环。 i永远不会是 0 ...

当我们挑剔它时i <= r.size()也会引起问题,如Vector基于 0(即 0-size() - 1)。

尝试一些类似的事情;

for (int i = 0; i < r.size(); i++) {
    g.drawRect(start.x, start.y, (cur.x - start.x), (cur.y - start.y));
    g.setColor(Color.gray);
    g.fillRect(start.x, start.y, (cur.x - start.x), (cur.y - start.y));
}

相反

关于java - 尝试在 Java 中使用 MouseListeners 绘制矩形会导致程序崩溃并且不会生成异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13170463/

相关文章:

java - 有什么方法可以轻松地在 Java Applet 中显示非常大的图像(使用较少的部分)?

java - 如何更改 java.awt.Graphics 绘制对象的方式?

java - KeyListener 仅有时有效

java - 当两个文本字段为空时禁用按钮

java - 如何将 jfree 图表作为小程序运行?

java - 如何将 Java 小程序从 IDE 加载到网站上?

java - 如何设置动态填充的多级下拉框表单?

java - 从 Maven 文件夹结构的主/资源文件夹中选取文件时出现问题

java - 任何使用大字符串并返回 InputStream 的实用程序类/方法?

java - 在浮点上下文中解决整数除法