【问题标题】:Using Thread with paint java将线程与油漆 java 一起使用
【发布时间】:2013-05-02 20:23:43
【问题描述】:

我正在用 Java 开发跳棋游戏,但偶然发现了一个问题。 我正在尝试创建的是,当按下棋盘格时,它前面的可用 2 个点应变为灰色 2 秒。

变灰很容易,但是当我希望它在 2 秒后使用 Thread.sleep(2000) 变回时,我注意到它在实际睡眠之前首先在此开关中完成其余的情况(所以它把新鲜的灰色方块立即变回黑色)

出了什么问题?提前致谢!

switch (bord[ypos][xpos]) {
                case 0:

                    break;
                case 1:

                    break;
                case 2:

                    if (bord[ypos + 1][xpos - 1] == 1) {
                        bord[ypos + 1][xpos - 1] = 4;

                    }
                    if (bord[ypos + 1][xpos + 1] == 1) {
                        bord[ypos + 1][xpos + 1] = 4;

                    }
                    repaint();
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                    }
                    if (bord[ypos + 1][xpos - 1] == 4) {
                        bord[ypos + 1][xpos - 1] = 1;
                    }
                    if (bord[ypos + 1][xpos + 1] == 4) {
                        bord[ypos + 1][xpos + 1] = 1;
                    }
                    break;
                case 3:

                    break;
            }

用计时器试试(我是新手,所以请不要用力捂脸)

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dammen;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;
import javax.swing.Timer;

/**
 *
 * @author Boyen
 */
public class Board extends JPanel implements MouseListener {

    boolean test;
    boolean black = false;
    boolean redpiece = false;
    boolean bluepiece = true;
    Timer timer;
    private int[][] bord = {{0, 2, 0, 2, 0, 2, 0, 2},
        {2, 0, 2, 0, 2, 0, 2, 0},
        {0, 2, 0, 2, 0, 2, 0, 2},
        {1, 0, 1, 0, 1, 0, 1, 0},
        {0, 1, 0, 1, 0, 1, 0, 1},
        {3, 0, 3, 0, 3, 0, 3, 0},
        {0, 3, 0, 3, 0, 3, 0, 3},
        {3, 0, 3, 0, 3, 0, 3, 0}};

    public Board(Dammen parent) {
        addMouseListener(this);
        timer = new Timer(100,taskPerformer);
        timer.setRepeats(false);
    }

    public void start() {
    }

    public void paint(Graphics g) {
        super.paint(g);

        Dimension size = getSize();

        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                switch (bord[i][j]) {
                    case 0:
                        g.setColor(Color.WHITE);
                        break;
                    case 1:
                        g.setColor(Color.BLACK);
                        break;
                    case 2:
                        g.setColor(Color.RED);
                        break;
                    case 3:
                        g.setColor(Color.BLUE);
                        break;
                    case 4:
                        g.setColor(Color.gray);
                        break;
                }
                g.fillRect((size.width / 8) * j, (size.height / 8) * i, size.width / 8, size.height / 8);
            }

        }
    }
    int mouseX, mouseY;

    @Override
    public void mouseClicked(MouseEvent e) {


        mouseX = e.getX();
        mouseY = e.getY();

        zoekmogelijkespots(mouseX, mouseY);

    }
    ActionListener taskPerformer = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {

        }
  };

    public void zoekmogelijkespots(int mouseX, int mouseY) {

            Dimension size = getSize();
            System.out.println(mouseX + "," + mouseY);
            int xpos;
            int ypos;
            xpos = (int) (mouseX / (size.width / 8));
            ypos = (int) (mouseY / (size.height / 8));
            System.out.println(ypos + "," + xpos);
            System.out.println(bord[ypos][xpos]);
            switch (bord[ypos][xpos]) {
                case 0:

                    break;
                case 1:

                    break;
                case 2:

                    if (bord[ypos + 1][xpos - 1] == 1) {
                        bord[ypos + 1][xpos - 1] = 4;

                    }
                    if (bord[ypos + 1][xpos + 1] == 1) {
                        bord[ypos + 1][xpos + 1] = 4;

                    }
                    repaint();
                    timer.start();
                    if (bord[ypos + 1][xpos - 1] == 4) {
                        bord[ypos + 1][xpos - 1] = 1;
                    }
                    if (bord[ypos + 1][xpos + 1] == 4) {
                        bord[ypos + 1][xpos + 1] = 1;
                    }
                    break;
                case 3:

                    break;
            }


    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }
}

【问题讨论】:

  • 您的游戏是在事件线程还是其他线程上运行?
  • @durron597 线程.sleep(2000);是整个代码中唯一与线程有关的行,如果你想知道的话(这是朋友建议的)
  • 不要阻塞 EDT(事件调度线程)——当这种情况发生时,GUI 将“冻结”。而不是调用Thread.sleep(n) 实现单次Swing Timer。有关详细信息,请参阅Concurrency in Swing
  • 据我了解,计时器仅用于重复性任务?这是在行动,不过我可能错了。
  • @Boyen:安德鲁回答了 1139 个摇摆问题,获得了 3373 票。在挥杆方面你可以相信他。顺便说一句,你问的是一个他可能获得 2000 票赞成的问题,因为它每天都会被问两次。

标签: java multithreading swing switch-statement event-dispatch-thread


【解决方案1】:

你可以使用 Swing javax.swing.Timer 来实现你想要的......

if (bord[ypos + 1][xpos - 1] == 1) {
    bord[ypos + 1][xpos - 1] = 4;
}
if (bord[ypos + 1][xpos + 1] == 1) {
    bord[ypos + 1][xpos + 1] = 4;
}
repaint();
Timer timer = new Timer(2000, new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        if (bord[ypos + 1][xpos - 1] == 4) {
            bord[ypos + 1][xpos - 1] = 1;
        }
        if (bord[ypos + 1][xpos + 1] == 4) {
            bord[ypos + 1][xpos + 1] = 1;
        }
    }
});
timer.setRepeats(false);
timer.start();

【讨论】:

    【解决方案2】:

    除了Thread.sleep(2000);,你可以这样做(注意,我无法测试这个):

    public static class GrayWorker extends SwingWorker<Object, Object> {
        private final int xpos;
        private final int ypos;
        private final int[][] bord;
        public GrayWorker(int[][] bord, int xpos, int ypos) {
            this.bord = bord; this.xpos = xpos; this.ypos = ypos;
        }
    
        @Override
        public Object doInBackground() {
            Thread.sleep(2000);
            return null;
        }
    
        @Override
        protected void done() {
            if (bord[ypos + 1][xpos - 1] == 4) {
                bord[ypos + 1][xpos - 1] = 1;
            }
            if (bord[ypos + 1][xpos + 1] == 4) {
                bord[ypos + 1][xpos + 1] = 1;
            }
        }
    }
    

    然后,在你的另一堂课上,做:

    GrayWorker worker = new GrayWorker(bord, xpos, ypos);
    worker.execute();
    

    【讨论】:

    • +1 是一种有趣的方法,但 javax.swing.Timer 会是一个更简单的解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多