Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在KeyListener Java中每隔100毫秒更新SWT中的画布_Java_Canvas_Swt_Sleep_Redraw - Fatal编程技术网

如何在KeyListener Java中每隔100毫秒更新SWT中的画布

如何在KeyListener Java中每隔100毫秒更新SWT中的画布,java,canvas,swt,sleep,redraw,Java,Canvas,Swt,Sleep,Redraw,我正在编写一个程序,每次按键后更新画布,方法是重新生成数据结构(立方体),然后将其绘制到画布上。如果用户每100毫秒输入“S”,我希望画布在每次旋转(旋转=程序生成的解决方案字符串的一个字符)后显示立方体,并将其重新绘制到屏幕上,我尝试了几种不同的方法,但无法使其工作。这是我的KeyListener代码: canvas.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEve

我正在编写一个程序,每次按键后更新画布,方法是重新生成数据结构(立方体),然后将其绘制到画布上。如果用户每100毫秒输入“S”,我希望画布在每次旋转(旋转=程序生成的解决方案字符串的一个字符)后显示立方体,并将其重新绘制到屏幕上,我尝试了几种不同的方法,但无法使其工作。这是我的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);
}
private static void drawFace(GC-GC、int-startwidth、int-startdepth、int-celldim、Color[]Color、byte[]Face){
gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_-WHITE));
int x=起始宽度;
int y=起始深度;
//画立方体的面

对于(int i=0;i您不能在这样的循环中进行更新,因为您必须让主SWT
显示。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
,在这个例程中,所有实际的绘图都应该在控件的绘制侦听器中。

当前它执行整个for循环、sleep和all,但不更新画布,然后在完成后重新绘制(因此没有中间步骤)谢谢你的回答,那么这个Display.timerExec可以进入我的密钥侦听器吗?是的,你可以在侦听器中调用它。嘿,很抱歉再次打扰,但我尝试了这个,但仍然没有运气,它仍然执行完整的解算,然后重新绘制多维数据集。也就是说,不按移动更新移动。我使用额外的行Display.getDefault().timerExec进行了尝试(1000,这个);但这导致了同样的事情发生,然后在.for(String move:moves){Display.getDefault().timerExec(1000,new Runnable(){@Override public void run(){GC GC=new GC(canvas);cube.performAlgorithm(move,false);drawCube(rect,GC);canvas.redraw();System.out.println(move);}})之后进入无限循环您在keylistener中调用timerExec一次。当延迟代码运行时,您将在最后再次调用它,直到完成移动数-您必须将代码添加到我的示例中以跟踪移动数。我还告诉过您只需进行
重绘
。您必须使用PaintListener进行实际绘制。非常感谢您的帮助,现在就让它工作吧!