2012-06-23 58 views
2

我想知道,如何讓一個方法在後臺運行。即。此方法在程序啓動時開始,並在程序關閉之前持續執行其語句。 例如。可以說我有一個方法「gravity()」,它在程序運行時不斷遞減某個值。 現在正在嘗試使用下面的程序,其中即時嘗試拉沒有按下公爵(重力),當沒有按鍵。但沒有發生。如何在程序結束之前讓方法在後臺連續運行?

import java.awt.*; 
import java.awt.event.*; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.net.*; 
import java.util.HashMap; 
import java.util.Map; 
import javax.imageio.ImageIO; 
import javax.swing.*; 

public class MoveIcon extends JPanel { 

    private static final long serialVersionUID = 1L; 
    private static final String IMAGE_PATH = "http://duke.kenai.com/misc/Bullfight.jpg"; 
    private static final String IMAGE_PATH_PLAYER = "http://duke.kenai.com/iconSized/duke4.gif"; 
    public static final int STEP = 3; 
    private static final int TIMER_DELAY = STEP * 8; 
    private BufferedImage bkgrndImage = null; 
    private BufferedImage playerImage = null; 
    private Map<Direction, Boolean> directionMap = new HashMap<Direction, Boolean>(); 
    private int playerX = 0; 
    private int playerY = 0; 

    enum Direction { 

     UP(KeyEvent.VK_UP, 0, -1), DOWN(KeyEvent.VK_DOWN, 0, 1), 
     LEFT(KeyEvent.VK_LEFT, -1, 0), RIGHT(KeyEvent.VK_RIGHT, 1, 0); 
     private int keyCode; 
     private int xDirection; 
     private int yDirection; 

     private Direction(int keyCode, int xDirection, int yDirection) { 
      this.keyCode = keyCode; 
      this.xDirection = xDirection; 
      this.yDirection = yDirection; 
     } 

     public int getKeyCode() { 
      return keyCode; 
     } 

     public int getXDirection() { 
      return xDirection; 
     } 

     public int getYDirection() { 
      return yDirection; 
     } 
    } 

    public MoveIcon() { 
     try { 
      URL bkgrdImageURL = new URL(IMAGE_PATH); 
      URL playerImageURL = new URL(IMAGE_PATH_PLAYER); 
      bkgrndImage = ImageIO.read(bkgrdImageURL); 
      playerImage = ImageIO.read(playerImageURL); 
      setPreferredSize(new Dimension(bkgrndImage.getWidth(), bkgrndImage.getHeight())); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     for (Direction direction : Direction.values()) { 
      directionMap.put(direction, false); 
     } 
     setKeyBindings(); 
     Timer timer = new Timer(TIMER_DELAY, new TimerListener()); 
     timer.start(); 
    } 

    private void setKeyBindings() { 
     InputMap inMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); 
     ActionMap actMap = getActionMap(); 
     for (final Direction direction : Direction.values()) { 
      KeyStroke pressed = KeyStroke.getKeyStroke(direction.getKeyCode(), 0, false); 
      KeyStroke released = KeyStroke.getKeyStroke(direction.getKeyCode(), 0, true); 
      inMap.put(pressed, direction.toString() + "pressed"); 
      inMap.put(released, direction.toString() + "released"); 
      actMap.put(direction.toString() + "pressed", new AbstractAction() { 

       private static final long serialVersionUID = 1L; 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        directionMap.put(direction, true); 
       } 
      }); 
      actMap.put(direction.toString() + "released", new AbstractAction() { 

       private static final long serialVersionUID = 1L; 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        directionMap.put(direction, false); 
       } 
      }); 
     } 

    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (bkgrndImage != null) { 
      g.drawImage(bkgrndImage, 0, 0, null); 
     } 
     if (playerImage != null) { 
      g.drawImage(playerImage, playerX, playerY, null); 
     } 
    } 

    private class TimerListener implements ActionListener { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      boolean moved = false; 
      for (Direction direction : Direction.values()) { 
       if (directionMap.get(direction)) { 
        playerX += STEP * direction.getXDirection(); 
        playerY += STEP * direction.getYDirection(); 
        moved = true; 
       } 
      } 
      if (moved) { 
       int x = playerX - 2 * STEP; 
       int y = playerY - 2 * STEP; 
       int w = playerImage.getWidth() + 4 * STEP; 
       int h = playerImage.getHeight() + 4 * STEP; 
       MoveIcon.this.repaint(x, y, w, h); // !! repaint just the player 
      } 
     } 
    } 

    private static void createAndShowUI() { 
     JFrame frame = new JFrame("MoveIcon"); 
     frame.getContentPane().add(new MoveIcon()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 

謝謝。

+2

有一個線程將持續運行該方法 – GETah

回答

5

在最簡單的方式,你可以有這樣的事情:

import javax.swing.JFrame; 

public class TestBackgroudMethod { 

    public static void main(final String[] args) { 

     MyBackgroudMethod thread = new MyBackgroudMethod(); 
     thread.setDaemon(true); 
     thread.start(); 

     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       JFrame jFrame = new JFrame(); 
       jFrame.setSize(200, 200); 
       jFrame.setVisible(true); 
      } 
     }); 
    } 

    public static class MyBackgroudMethod extends Thread { 

     @Override 
     public void run() { 
      while (true) { 
       System.out.println("Executed!"); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

    } 

} 

編輯


新增樣本擺動工人:

import javax.swing.JFrame; 
import javax.swing.SwingWorker; 

public class TestBackgroudMethod { 

    public static void main(final String[] args) { 

     new SwingBackgroupWorker().execute(); 

     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       JFrame jFrame = new JFrame(); 
       jFrame.setSize(200, 200); 
       jFrame.setVisible(true); 
      } 
     }); 
    } 

    public static class SwingBackgroupWorker extends SwingWorker<Object, Object> { 

     @Override 
     protected Object doInBackground() throws Exception { 
      while (true) { 
       java.awt.EventQueue.invokeLater(new Runnable() { 
        public void run() { 
         System.out.println("executed"); 
         // here the swing update 
        } 
       }); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

    } 

} 
+1

您必須將後臺線程標記爲守護進程,否則JVM(以及應用程序)將無法正常終止。 –

+0

好點,糾正! –

+0

@Spaeth謝謝,這就是我正在尋找的。 – md1hunox

2

「SWING ISN」 t線程安全「,正如您可能在Java文檔中看到的那樣。最好的方法是使用SwingWorker class。它提供了計算執行時間長的任務的結果或性能的功能。

相關問題