如何在 KeyListener Java 中每 100 毫秒更新一次 SWT 中的 canvas
How to update a canvas in SWT every 100 milliseconds inside a KeyListener Java
我正在编写一个程序,在每次按键后通过重新生成数据结构(立方体)然后将其绘制到 canvas 上来更新 canvas。如果用户输入 'S' 我希望 canvas 每 100 毫秒在每一回合后显示立方体(turn = 程序生成的解决方案字符串的一个字符)并将其重绘到屏幕上,已经尝试了几次不同的方法,但无法让它发挥作用。这是我的 KeyListener 代码:
canvas.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
GC gc = new GC(canvas);
Rectangle rect = canvas.getClientArea();
String alg = ""+e.character;
cube.performAlgorithm(alg, false);
drawCube(rect,gc);
if(e.character=='S'){
Cube cube2 = new Cube(cube);
String solution = Solutions.longsolve(cube2, "Fridrich", false);
String[] moves = new String[solution.length()];
moves = solution.split("(?!^)");
for(String move : moves){
cube.performAlgorithm(move, false);
try {
drawCube(rect,gc);
canvas.redraw();
canvas.update();
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
//System.out.println(solution);
}
gc.dispose();
}
});
还有我的 drawFace 和 drawCube 代码,感谢这可能不是解决我问题的好方法,但我对使用 SWT 还很陌生。
private static void drawFace(GC gc, int startwidth, int startdepth, int celldim, Color[] colour, byte[][] Face){
gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
int x = startwidth;
int y = startdepth;
//draw face of the cube
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
Rectangle rect = new Rectangle(x, y, celldim, celldim);
gc.setBackground(colour[Face[i][j]]);
gc.fillRectangle(rect);
gc.drawRectangle(rect);
x += celldim;
//only draw a box
}
x = startwidth;
y+=celldim;
}
}
private static void drawCube(Rectangle clientArea, GC gc){
int startdepth = 10;
int celldim = (((clientArea.height)-(startdepth*2))/12);
int startwidth = (int) ((int)(clientArea.width/2)-(1.5*celldim));
Color[] colours = {gc.getDevice().getSystemColor(SWT.COLOR_GREEN),gc.getDevice().getSystemColor(SWT.COLOR_RED),
gc.getDevice().getSystemColor(SWT.COLOR_BLUE),gc.getDevice().getSystemColor(SWT.COLOR_GRAY),
gc.getDevice().getSystemColor(SWT.COLOR_BLACK),gc.getDevice().getSystemColor(SWT.COLOR_YELLOW)};
gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
int x = startwidth;
int y = startdepth;
drawFace(gc, x, y, celldim,colours,cube.Uface);
y += (3*celldim);
drawFace(gc, x, y, celldim,colours,cube.Fface);
x -= (3*celldim);
drawFace(gc, x, y, celldim,colours,cube.Lface);
x += (6*celldim);
drawFace(gc, x, y, celldim,colours,cube.Rface);
x -= (3*celldim);
y += (3*celldim);
drawFace(gc, x, y, celldim,colours,cube.Dface);
y += (3*celldim);
drawFace(gc, x, y, celldim,colours,cube.Bface);
}
您不能像那样在循环中进行更新,因为您必须让主 SWT Display.readAndDispatch
循环 运行 因为这是实际更新屏幕的内容。
改为使用Display.timerExec
每100ms执行一次循环:
Display.getDefault().timerExec(100, new Runnable() {
@Override
public void run() {
canvas.redraw();
// Run again - TODO add logic to stop after correct number of moves
Display.getDefault().timerExec(100, this);
}
});
您应该只调用 redraw
在此例程中,所有实际绘图都应该在控件上的绘制侦听器中。
我正在编写一个程序,在每次按键后通过重新生成数据结构(立方体)然后将其绘制到 canvas 上来更新 canvas。如果用户输入 'S' 我希望 canvas 每 100 毫秒在每一回合后显示立方体(turn = 程序生成的解决方案字符串的一个字符)并将其重绘到屏幕上,已经尝试了几次不同的方法,但无法让它发挥作用。这是我的 KeyListener 代码:
canvas.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
GC gc = new GC(canvas);
Rectangle rect = canvas.getClientArea();
String alg = ""+e.character;
cube.performAlgorithm(alg, false);
drawCube(rect,gc);
if(e.character=='S'){
Cube cube2 = new Cube(cube);
String solution = Solutions.longsolve(cube2, "Fridrich", false);
String[] moves = new String[solution.length()];
moves = solution.split("(?!^)");
for(String move : moves){
cube.performAlgorithm(move, false);
try {
drawCube(rect,gc);
canvas.redraw();
canvas.update();
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
//System.out.println(solution);
}
gc.dispose();
}
});
还有我的 drawFace 和 drawCube 代码,感谢这可能不是解决我问题的好方法,但我对使用 SWT 还很陌生。
private static void drawFace(GC gc, int startwidth, int startdepth, int celldim, Color[] colour, byte[][] Face){
gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
int x = startwidth;
int y = startdepth;
//draw face of the cube
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
Rectangle rect = new Rectangle(x, y, celldim, celldim);
gc.setBackground(colour[Face[i][j]]);
gc.fillRectangle(rect);
gc.drawRectangle(rect);
x += celldim;
//only draw a box
}
x = startwidth;
y+=celldim;
}
}
private static void drawCube(Rectangle clientArea, GC gc){
int startdepth = 10;
int celldim = (((clientArea.height)-(startdepth*2))/12);
int startwidth = (int) ((int)(clientArea.width/2)-(1.5*celldim));
Color[] colours = {gc.getDevice().getSystemColor(SWT.COLOR_GREEN),gc.getDevice().getSystemColor(SWT.COLOR_RED),
gc.getDevice().getSystemColor(SWT.COLOR_BLUE),gc.getDevice().getSystemColor(SWT.COLOR_GRAY),
gc.getDevice().getSystemColor(SWT.COLOR_BLACK),gc.getDevice().getSystemColor(SWT.COLOR_YELLOW)};
gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
int x = startwidth;
int y = startdepth;
drawFace(gc, x, y, celldim,colours,cube.Uface);
y += (3*celldim);
drawFace(gc, x, y, celldim,colours,cube.Fface);
x -= (3*celldim);
drawFace(gc, x, y, celldim,colours,cube.Lface);
x += (6*celldim);
drawFace(gc, x, y, celldim,colours,cube.Rface);
x -= (3*celldim);
y += (3*celldim);
drawFace(gc, x, y, celldim,colours,cube.Dface);
y += (3*celldim);
drawFace(gc, x, y, celldim,colours,cube.Bface);
}
您不能像那样在循环中进行更新,因为您必须让主 SWT Display.readAndDispatch
循环 运行 因为这是实际更新屏幕的内容。
改为使用Display.timerExec
每100ms执行一次循环:
Display.getDefault().timerExec(100, new Runnable() {
@Override
public void run() {
canvas.redraw();
// Run again - TODO add logic to stop after correct number of moves
Display.getDefault().timerExec(100, this);
}
});
您应该只调用 redraw
在此例程中,所有实际绘图都应该在控件上的绘制侦听器中。