[英]Use a timer when a key is pressed
The past week of searching has not brought up any working help for trying to figure out how to do this. 过去一周的搜索没有提供任何有用的帮助,试图找出如何做到这一点。 When a user presses the backspace, it saves the game.
当用户按下退格键时,它会保存游戏。 I set it up that it shows a little box at the top that says "Saving.." and I want that to stay up there for about 2 seconds.
我设置它在顶部显示一个小盒子,上面写着“拯救......”,我想让它在那里停留大约2秒钟。 I can get it to show up while the button is being pressed with this code:
使用此代码按下按钮时,我可以显示它:
if (key.save) {
font = new Font(null, 0, 16);
g.setFont(font);
g.setColor(Color.DARK_GRAY);
g.fillRect(getWidth() / 2 - 40, -1, 80, 35);
g.setColor(Color.BLACK);
g.drawRect(getWidth() / 2 - 40, -1, 80, 35);
g.setColor(Color.white);
g.drawString("Saving..", getWidth() / 2 - 30, 22);
}
But this code won't work, it won't even display the box at the top: 但是这段代码不起作用,甚至不会在顶部显示框:
if (key.save) {
ActionListener action = new ActionListener() {
public void actionPerformed(ActionEvent e) {
Font font = new Font(null, 0, 16);
g.setFont(font);
g.setColor(Color.DARK_GRAY);
g.fillRect(getWidth() / 2 - 40, -1, 80, 35);
g.setColor(Color.BLACK);
g.drawRect(getWidth() / 2 - 40, -1, 80, 35);
g.setColor(Color.white);
g.drawString("Saving..", getWidth() / 2 - 30, 22);
}
};
timer = new Timer(0, action);
timer.start();
}
This is an example of the basic concept of using a list of renderable artifacts which can be updated over time. 这是使用可以随时间更新的可渲染工件列表的基本概念的示例。
The basic idea is there is a central paint loop that is responsible for updating the current state of the UI based on what you want to render. 基本思想是有一个中央绘制循环,负责根据您想要渲染的内容更新UI的当前状态。 This means that any changes to the UI must go through this central loop.
这意味着对UI的任何更改都必须通过此中央循环。
This example just uses Swing, but the concept should be easy to translate. 这个例子只使用Swing,但这个概念应该很容易翻译。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class QuickPaint01 {
public static void main(String[] args) {
new QuickPaint01();
}
public QuickPaint01() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel implements Environment {
private List<Drawable> drawables;
public TestPane() {
drawables = new ArrayList<>(25);
Timer update = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Drawable[] draws = drawables.toArray(new Drawable[drawables.size()]);
for (Drawable drawable : draws) {
if (drawable instanceof Moveable) {
((Moveable)drawable).update(TestPane.this);
}
}
repaint();
}
});
update.setCoalesce(true);
update.setRepeats(true);
update.start();
drawables.add(new Ball());
}
@Override
public void add(Drawable drawable) {
drawables.add(drawable);
}
@Override
public void remove(Drawable drawable) {
drawables.remove(drawable);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Drawable drawable : drawables) {
drawable.draw(this, g2d);
}
g2d.dispose();
}
}
public interface Environment {
public Dimension getSize();
public void add(Drawable drawable);
public void remove(Drawable drawable);
}
public interface Drawable {
public void draw(Environment env, Graphics2D g);
}
public interface Moveable extends Drawable {
public void update(Environment env);
}
public class Ball implements Moveable {
private int radius = 20;
private int x = 0;
private int y = 0;
private int xDelta = 4;
private Shape shape;
public Ball() {
shape = new Ellipse2D.Float(0, 0, radius, radius);
}
@Override
public void update(Environment env) {
x += xDelta;
if (x + radius > env.getSize().width) {
x = env.getSize().width - radius;
xDelta *= -1;
env.add(new Message(env, "<< Bounce", 1));
} else if (x < 0) {
x = 0;
xDelta *= -1;
env.add(new Message(env, "Bounce >> ", 1));
}
y = (env.getSize().height - radius) / 2;
}
@Override
public void draw(Environment env, Graphics2D g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.translate(x, y);
g2d.setColor(Color.BLUE);
g2d.fill(shape);
g2d.dispose();
}
}
public class Message implements Drawable {
private Environment environment;
private String message;
private int delay;
public Message(Environment environment, String message, int delay) {
this.environment = environment;
this.message = message;
this.delay = delay;
Timer timer = new Timer(delay * 1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Message.this.environment.remove(Message.this);
}
});
timer.start();
}
@Override
public void draw(Environment env, Graphics2D g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
FontMetrics fm = g2d.getFontMetrics();
g2d.drawString(message, env.getSize().width - fm.stringWidth(message), 0 + fm.getAscent());
g2d.dispose();
}
}
}
Written in pseudo code you can build a solution using several parts: 用伪代码编写,您可以使用几个部分构建解决方案:
saveMessageIsVisible
which is set to false
false
的字段saveMessageIsVisible
saveMessageIsVisible
to true (and optionally perform invalidate screen) saveMessageIsVisible
设置为true(并可选择执行invalidate屏幕) for perform a task for a given period of time, you could do the following: 要在给定的时间段内执行任务,您可以执行以下操作:
ExecutorService service = Executors.newSingleThreadExecutor();
try {
Runnable r = new Runnable() {
@Override
public void run() {
// task
}
};
Future<?> f = service.submit(r);
f.get(2, TimeUnit.MINUTES); // attempt the task for two minutes
} catch (Exception e) {
//Handele Exception
} finally {
service.shutdown();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.