停止计时器在java Swing

问题描述:

我刚刚在Swing中开始使用Timer。我编写的程序基本上将矩形上下移动到屏幕上的特定点,我使用计时器使其缓慢而平稳地运行。但是我试图阻止它时遇到了问题。这是下面的代码:矩形的停止计时器在java Swing

升降级变化y位置:

public void moveUp(int destination){ 
     speed++; 
     if(speed>5){ 
      speed = 5; 
     } 
     System.out.println("Speed is: "+speed); 
     yPos -= speed; 
     if(yPos < destination){ 
      yPos = destination; 
      isStop = true; 
     } 
     setPos(xPos, yPos); 
    } 

而这得到了TimerMouseListener类:

this.addMouseListener(new MouseListener() { 

     @Override 
     public void mouseReleased(MouseEvent arg0) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void mousePressed(MouseEvent e) { 
      if (e.getButton() == MouseEvent.BUTTON1) { 
       Timer timer = new Timer(100, new ActionListener() { 

        @Override 
        public void actionPerformed(ActionEvent e) { 
         liftArray.get(0).moveUp(rowDisctance/2); 
         repaint(); 
        } 
       }); 
       timer.start(); 
      } 

     } 
+4

这有什么错定时器#停止? – MadProgrammer 2014-09-11 07:59:22

+2

该类需要保留对'mousePressed'方法中创建的'Timer'的引用,以按照@MadProgrammer的建议进行操作.. – 2014-09-11 08:02:01

+0

您可以检查run方法中isStopped标志的状态并在此停止计时器,可以从ActionEvent源属性获取对Timer的引用 – MadProgrammer 2014-09-11 08:04:01

如果我确实理解了你,你正在寻找类似这样的东西,你需要两个定时器来控制上下机制,timer1向下移动,timer2向上移动,反之亦然。您需要停止timer1,然后在timer1内您需要启动timer2,以下是代码和动画。

enter image description here

到您的对话框(矩形)构造函数中添加字段

Point rv; 

设定的初始位置

rv= rectangle.this.getLocation(); 

您的按钮操作进行

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {           
    timer1.setInitialDelay(0); 
    timer1.start(); 
    jTextArea1.append("Timer 1 Started Moving Down\n"); 
} 

复制粘贴在java中这两个Timer1和Timer2类似方法

private Timer timer1 = new Timer(10, new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     rv.y++; 



     if (rv.y == 500) { 
      timer1.stop(); 
      jTextArea1.append("Timer 1 Stopped\n"); 
      jTextArea1.append("Timer 2 Started Moving Up\n"); 
      timer2.setInitialDelay(0); 
      timer2.start(); 

     } 

     rectangle.this.setLocation(rv.x , rv.y); 
     rectangle.this.repaint(); 

    } 
}); 



private Timer timer2 = new Timer(5, new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     rv.y--; 

     if (rv.y == 200) { 
      timer2.stop(); 
      jTextArea1.append("Timer 2 Stopped\n"); 
     } 
      rectangle.this.setLocation(rv.x , rv.y); 
     rectangle.this.repaint(); 
    } 
}); 
+0

谢谢heapssss :) – user3600620 2014-09-11 13:11:29

+0

不用客气 – mussdroid 2014-09-11 13:17:00

+1

实际上,你只需要一个定时器,用一个delta值来决定运动的方向,这样就不会有两个定时器同时运行的可能性 – MadProgrammer 2014-09-12 22:04:15

直观了解与这个问题入手,我已经编码了一个小例子:

enter image description here

当您启动它时,会创建两个矩形。当您在绘图区域上单击鼠标左键时,它们开始移动。

当到达目标行时,运动将停止。

逻辑取决于Rectangle类中的状态。当计时器事件处理程序运行,每一个矩形的状态被检查,定时器停止,如果达到了所有的矩形有isStopped状态:从Rectangle类

 public void mousePressed(MouseEvent e) { 
      if (e.getButton() == MouseEvent.BUTTON1) { 
       timer = new Timer(100, new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         /** 
         * Variable isStopped is used to track, if any 
         * rectangle didn't reach the destination yet 
         */ 
         boolean isStopped = true; 

         for(int i = 0; i < count; i++){ 
          rectangles[i].moveUp(destination); 
          if (!rectangles[i].isStopped()) { 
           isStopped = false; 
          } 
         } 
         drawPanel.repaint(); 

         /** 
         * With all rectangles having arrived at destination, 
         * the timer can be stopped 
         */ 
         if (isStopped) { 
          timer.stop(); 
         } 
        } 
       }); 
       timer.start(); 
      } 
     } 

摘译 - 在这里,你看,怎么isStopped状态被处理 - 内部为private isStop变量 - 可以使用isStopped getter进行检索。

/** 
* Moves the rectangle up until destination is reached 
* speed is the amount of a single movement. 
*/ 
public void moveUp(int destination) { 
    if (speed < 5) { 
     speed++; 
    } 

    y -= speed; 

    if (y < destination) { 
     y = destination; 
     isStop = true; 
    } 
} 

public boolean isStopped() { 
    return isStop; 
} 

这里是整个程序:

主程序MovingRectangle,创建绘图区域并提供控制:对于所述移动形状

package question; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

public class MovingRectangle extends JPanel { 
    /** 
    * The serial version uid. 
    */ 
    private static final long serialVersionUID = 1L; 

    private Rectangle[] rectangles = new Rectangle[10]; 
    private int count; 
    private int destination; 

    private JPanel controlPanel; 
    private DrawingPanel drawPanel; 
    private JButton stop; 

    private Timer timer; 

    public static void main(String[] args){ 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame("Rectangles"); 
       frame.setContentPane(new MovingRectangle()); 
       frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       frame.pack(); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public MovingRectangle(){ 
     /** Imaginary horizontal line - the destination */ 
     destination = 200; 

     /** Create the control panel for the left side containing the buttons */ 
     controlPanel = new JPanel(); 
     controlPanel.setPreferredSize(new Dimension(120, 400)); 

     /** Create the button */ 
     stop = new JButton("Stop"); 
     stop.addActionListener(new ButtonListener()); 
     controlPanel.add(stop); 

     /** Create a hint how to start the movement. */ 
     JTextArea textHint = new JTextArea(5, 10); 
     textHint.setEditable(true); 
     textHint.setText("Please click on the drawing area to start the movement"); 
     textHint.setLineWrap(true); 
     textHint.setWrapStyleWord(true); 
     controlPanel.add(textHint); 

     /** Add control panel to the main panel */ 
     add(controlPanel); 

     /** Create the drawing area for the right side */ 
     drawPanel = new DrawingPanel(); 

     /** Add the drawing panel to the main panel */ 
     add(drawPanel); 

     /** With a left mouse button click the timer can be started */ 
     drawPanel.addMouseListener(new MouseListener() { 
      @Override 
      public void mousePressed(MouseEvent e) { 
       if (e.getButton() == MouseEvent.BUTTON1) { 
        timer = new Timer(100, new ActionListener() { 
         @Override 
         public void actionPerformed(ActionEvent e) { 
          /** 
          * Variable isStopped is used to track, if any 
          * rectangle didn't reach the destination yet 
          */ 
          boolean isStopped = true; 

          for(int i = 0; i < count; i++){ 
           rectangles[i].moveUp(destination); 
           if (!rectangles[i].isStopped()) { 
            isStopped = false; 
           } 
          } 
          drawPanel.repaint(); 

          /** 
          * With all rectangles having arrived at destination, 
          * the timer can be stopped 
          */ 
          if (isStopped) { 
           timer.stop(); 
          } 
         } 
        }); 
        timer.start(); 
       } 
      } 

      @Override 
      public void mouseReleased(MouseEvent arg0) { 
      } 

      @Override 
      public void mouseClicked(MouseEvent e) { 
      } 

      @Override 
      public void mouseEntered(MouseEvent e) { 
      } 

      @Override 
      public void mouseExited(MouseEvent e) { 
      } 
     }); 

     /** Add two rectangles to the drawing area */ 
     addRectangle(100, 30, 0, 370, new Color(255, 0, 0)); 
     addRectangle(120, 50, 200, 350, new Color(0, 0, 255)); 
    } 

    private void addRectangle(final int widthParam, final int heightParam, final int xBegin, final int yBegin, final Color color) { 
     /** Add a new rectangle, if array not filled yet */ 
     if (count < rectangles.length) { 
      rectangles[count] = new Rectangle(widthParam, heightParam, xBegin, yBegin, color); 
      count++; 
      drawPanel.repaint(); 
     } 
    } 

    /** This inner class is used to handle the button event. */ 
    private class ButtonListener implements ActionListener { 
     public void actionPerformed(ActionEvent e){ 
      if (e.getSource() == stop){ 
       timer.stop(); 
      } 
     } 
    } 

    /** This inner class provides the drawing panel */ 
    private class DrawingPanel extends JPanel{ 
     /** The serial version uid. */ 
     private static final long serialVersionUID = 1L; 

     public DrawingPanel() { 
      this.setPreferredSize(new Dimension(400, 400)); 
      setBackground(new Color(200, 220, 255)); 
     } 

     public void paintComponent(Graphics g){ 
      super.paintComponent(g); 

      /** Draw destination line */ 
      g.setColor(new Color(150, 150, 150)); 
      g.drawLine(0, destination, 400, destination); 

      /** Draw rectangles */ 
      for(int i = 0; i < count; i++){ 
       rectangles[i].display(g); 
      } 
     } 
    } 
} 

Rectangle类

package question; 

import java.awt.Color; 
import java.awt.Graphics; 

public class Rectangle { 
    private int x, y, width, height; 
    private Color color; 
    private boolean isStop = false; 
    private int speed = 0; 

    public Rectangle(final int widthParam, final int heightParam, final int xBegin, final int yBegin, final Color colorParam) { 
     width = widthParam; 
     height = heightParam; 
     this.x = xBegin; 
     this.y = yBegin; 
     this.color = colorParam; 
    } 

    public void display(Graphics g){ 
     g.setColor(this.color); 
     g.fillRect(this.x, this.y, this.width, this.height); 
    } 

    /** 
    * Moves the rectangle up until destination is reached 
    * speed is the amount of a single movement. 
    */ 
    public void moveUp(int destination) { 
     if (speed < 5) { 
      speed++; 
     } 

     y -= speed; 

     if (y < destination) { 
      y = destination; 
      isStop = true; 
     } 
    } 

    public boolean isStopped() { 
     return isStop; 
    } 
}