java 如何让方法在后台持续运行直到程序结束?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11168925/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to keep a method running continuously in background until the program ends?
提问by md1hunox
I want to know, how to keep a method running in the background. ie. this method starts when the program starts and keeps executing its statements until the program is closed. For ex. lets say i have a method "gravity()" which continuously decrements a certain value while the program is running. Right now for trying this out im using the following program, wherein im trying to pull the duke down (gravity) when no keys are pressed. but is not happening.
我想知道,如何让方法在后台运行。IE。此方法在程序启动时开始并一直执行其语句,直到程序关闭。例如。假设我有一个方法“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();
}
});
}
}
Thank you.
谢谢你。
回答by Francisco Spaeth
In the simplest way, you could have something like this:
以最简单的方式,你可以有这样的事情:
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();
}
}
}
}
}
Edit
编辑
Added sample with swing worker:
添加了带有摇摆工人的示例:
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();
}
}
}
}
}
回答by vedant
"SWING isn't thread safe" as you may have seen in may of the Java Docs.
“SWING 不是线程安全的”,正如您在 Java Docs 中看到的那样。
Best way is to use a SwingWorker class. It provides functionality for calculation of results or performance of tasks that have long execution times.
最好的方法是使用SwingWorker 类。它提供用于计算执行时间较长的任务的结果或性能的功能。