Java swing sleep命令

时间:2015-05-21 23:01:56

标签: java swing

我正在创建一个带有人工智能的棋盘游戏,而我正试图让人工智能选择将他的游戏部件放入闪存中一两秒,然后再进行所选择的移动。我的尝试如下:

Thread.sleep代码

button.setBackground(Color.pink);
Thread.sleep(800);
button.setBackground((new JButton()).getBackground());
Thread.sleep(800);
button.setBackground(Color.pink);
Thread.sleep(800);
button.setBackground((new JButton()).getBackground());
Thread.sleep(800);

Thread flash = new Thread(new ButtonFlashThread(button));
flash.start();

可赎回

ExecutorService es = Executors.newSingleThreadExecutor();
    Future<Boolean> task = es.submit(new ButtonFlashThread(button));

同时使用类(对于实现Runnable的线程而不是公共布尔调用(),它是public void run())

public class ButtonFlashThread implements Callable<Boolean> {

private int sleepTime = 800;
private JButton button;

public ButtonFlashThread(JButton b) {
    button = b;
}

public Boolean call() {
    for (int i = 0; i < 3; i++) {
        button.setBackground(Color.pink);   
        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        button.setBackground((new JButton()).getBackground());
        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    return false;
}

的invokeLater

Runnable flashON = new Runnable() {
         public void run() { button.setBackground(Color.pink); } };
     Runnable flashOFF = new Runnable() {
         public void run() { button.setBackground((new JButton()).getBackground()); } };
         javax.swing.SwingUtilities.invokeLater(flashON);
         javax.swing.SwingUtilities.invokeLater(flashOFF);
         javax.swing.SwingUtilities.invokeLater(flashON);
         javax.swing.SwingUtilities.invokeLater(flashOFF);

定时器

    ActionListener flashON = new ActionListener(){
        public void actionPerformed(ActionEvent arg0){ button.setBackground(Color.pink); } };
    ActionListener flashOFF = new ActionListener(){
        public void actionPerformed(ActionEvent arg0) { button.setBackground((new JButton()).getBackground()); } };

    int sleep = 800;
    Timer timer = new Timer(sleep, flashON); timer.setRepeats(false); timer.start();
    timer = new Timer(sleep, flashOFF); timer.setRepeats(false); timer.start();
    timer = new Timer(sleep, flashON); timer.setRepeats(false); timer.start();
    timer = new Timer(sleep, flashOFF); timer.setRepeats(false); timer.start();

Thread.Sleep命令冻结了GUI,当按钮闪烁时,所有其他尝试继续使用代码。不是我需要它。我希望按钮闪存和代码暂停,直到按钮完成闪烁,然后才恢复。基本上我正在寻找以下方法:

//Find desired move (done)
//Flash the JButton a few times to indicate selected move
//Do following move (done)

完全按顺序。

编辑1: 以下实施

private void flashButton(JButton button) {      
    class MoveTimerListener implements ActionListener {
        private boolean flashOn = false;
        private int count;
        private int MAX_COUNT = 5;
        private JButton button;

        public MoveTimerListener(JButton b) {
            button = b;
        }

        public void actionPerformed(ActionEvent e) {
            flashOn = !flashOn;
            if (count >= MAX_COUNT) { // MAX_COUNT is an int constant
                // reached max -- stop timer
                ((Timer) e.getSource()).stop();
                flashOn = false;

                aiMove();
                updateGUI();
            }

            if (flashOn)
                button.setBackground(Color.yellow);
            else
                button.setBackground((new JButton()).getBackground());
            count++;
        }
    }

    Timer t = new Timer(5000, new MoveTimerListener(button));
    t.start();
    updateGUI();
}

没有暂停代码,并且在代码完成后很长时间内按钮仍在后台闪烁时让它继续。

编辑2: 我实现了这样的例子:

private void flashButton() {        
    _moveTimer = new Timer(100, new MoveTimerListener());
    _moveTimer.start();
    updateGUI();
}

private class MoveTimerListener implements ActionListener {
    private boolean flashOn = false;
    private int count;

    @Override
    public void actionPerformed(ActionEvent e) {
        flashOn = !flashOn;
        if (count >= 20) {
            ((Timer) e.getSource()).stop();
            flashOn = false;
            _gm.makeMove(aiMove[0], aiMove[1]);
        }

        if (flashOn) {
            _boardButtons[aiMove[0]][aiMove[1]].setBackground(Color.yellow);
        } else {
            _boardButtons[aiMove[0]][aiMove[1]].setBackground((new JButton()).getBackground());
        }
        count++;
    }
}

但似乎代码总是跳过actionPerformed方法。我做错了什么?

编辑3: 不是那么小但可运行的程序。有问题的代码在第95-140行

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.LinkedList;
import java.util.Random;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GameGUI extends JFrame implements MouseListener {

private GameManager _gm;

private JLabel[] _scores;
private JLabel[] _players;
private JPanel _contentPane;
private JButton[] _toolbarButtons;
private JButton[][] _boardButtons;
private Timer _moveTimer;
private int[] aiMove;


public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                GameManager gm = new GameManager();
                //gm.addPlayer(new Player("player", 2, 0));
                gm.addPlayer(new Player("random", 2, 1));
                gm.addPlayer(new Player("max kills ai", 1, 2));
                gm.initBoard(8, 8);
                GameGUI frame = new GameGUI(gm);
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public GameGUI(GameManager gm) {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    _contentPane = new JPanel();
    _boardButtons = new JButton[gm.getBoardSize()[0]][gm.getBoardSize()[1]];
    _gm = gm;
    addWindowGUI(_contentPane);
    setContentPane(_contentPane);
    aiMove();
    updateGUI();
}

private void addWindowGUI(JPanel cp) {
    cp.setLayout(new BoxLayout(_contentPane, BoxLayout.PAGE_AXIS));

    JPanel gameInfo = new JPanel();
    gameInfo.setLayout(new FlowLayout());

    //Game grid
    JPanel gameGrid = new JPanel();
    int buttonSize = 40;
    gameGrid.setLayout(new GridLayout(_gm.getBoardSize()[0], _gm.getBoardSize()[1]));
    for (int i = 0; i < _boardButtons.length; i++)
        for (int j = 0; j < _boardButtons[i].length; j++) {
            _boardButtons[i][j] = new JButton();
            _boardButtons[i][j].setPreferredSize(new Dimension(buttonSize, buttonSize));
            _boardButtons[i][j].addMouseListener(this);
            gameGrid.add(_boardButtons[i][j]);
        }
    gameInfo.add(gameGrid);
    cp.add(gameInfo);
}

public void mouseClicked(MouseEvent e) {
    if (!_gm.getCurrentPlayer().isAI()) {
        //Find desired move and conduct it
        for (int i = 0; i < _boardButtons.length; i++)
            for (int j = 0; j < _boardButtons[i].length; j++)
                if (e.getSource().equals(_boardButtons[i][j]))
                    _gm.makeMove(i,j);

        aiMove();
        updateGUI();
    }
}

public void aiMove() {
    int winner = _gm.isGameOver();
    while (winner == -1 && _gm.getCurrentPlayer().getAI() != 0) {
        updateGUI();
        aiMove = _gm.getNextAIMove();
        flashButton();
        winner = _gm.isGameOver();
    }

    if (winner != -1) {
        // Winner
    }
}

private void flashButton() {        
    _moveTimer = new Timer(100, new MoveTimerListener());
    _moveTimer.start();
    updateGUI();
}

private class MoveTimerListener implements ActionListener {
    private boolean flashOn = false;
    private int count;

    @Override
    public void actionPerformed(ActionEvent e) {
        flashOn = !flashOn;
        if (count >= 20) {
            ((Timer) e.getSource()).stop();
            flashOn = false;
            _gm.makeMove(aiMove[0], aiMove[1]);
        }

        if (flashOn) {
            _boardButtons[aiMove[0]][aiMove[1]].setBackground(Color.yellow);
        } else {
            _boardButtons[aiMove[0]][aiMove[1]].setBackground((new JButton()).getBackground());
        }
        count++;
    }
}

public void mouseEntered(MouseEvent e) {
    if (!_gm.getCurrentPlayer().isAI()) {
        LinkedList<int[]> l = new LinkedList<int[]>();
        for (int i = 0; i < _boardButtons.length; i++)
            for (int j = 0; j < _boardButtons[i].length; j++)
                if (e.getSource().equals(_boardButtons[i][j]))
                    l = _gm.canPlace(i,j);
        for (int i = 0; i < l.size(); i++) {
            int[] temp = l.get(i);
            _boardButtons[temp[0]][temp[1]].setBackground(Color.yellow);
        }
    }
}
private void updateGUI() {
    for (int i = 0; i < _boardButtons.length; i++)
        for (int j = 0; j < _boardButtons[i].length; j++)
            if (_gm.getBoard().stoneAt(i, j) == 1)
                _boardButtons[i][j].setBackground(Color.green);
            else if (_gm.getBoard().stoneAt(i, j) == 2)
                _boardButtons[i][j].setBackground(Color.red);
}
public void mouseExited(MouseEvent arg0) { updateGUI(); }

//Not relevant
public void mousePressed(MouseEvent arg0) { }
public void mouseReleased(MouseEvent arg0) { }


//Other classes
public static class GameManager {
    private int _turn;
    private Player[] _players;
    private GameBoard _board;
    private GameLog _log;

    public int getTurn() { return _turn; }
    public Player[] getPlayers() { return _players; }
    public GameBoard getBoard() { return _board; }

    public GameManager() {
        _turn = 0;
        _players = new Player[0];
    }

    public int[] getNextAIMove() {
        AI ai = new AI();
        return ai.play(_players[_turn].getAI(), _board, _players[_turn].getColour());
    }

    public void initBoard(int m, int n) {
        int[] colours = new int[_players.length];
        for (int i = 0; i < colours.length; i++)
            colours[i] = _players[i].getColour();
        _board = new GameBoard(m, n, colours);
        updateScore();
    }

    public void addPlayer(Player p) {
        Player[] temp = _players;
        _players = new Player[temp.length + 1];
        for (int i = 0; i < temp.length; i++)
            _players[i] = temp[i];
        _players[temp.length] = new Player(p);

        Random rnd = new Random();
        _turn = rnd.nextInt(_players.length);
    }

    private void advanceTurn() {
        _turn++;
        if(_turn == _players.length) 
            _turn = 0;
    }

    public void makeMove(int y, int x) {
        if (_board.place(y, x, _players[_turn].getColour()) != 0) {
            updateScore();
            advanceTurn();
        }
    }

    public LinkedList<int[]> canPlace(int y, int x) {
        return _board.canPlace(y, x, _players[_turn].getColour());
    }

    public int[] getBoardSize() {
        return _board.getSize();
    }

    private void updateScore() {
        int[] scores = new int[_players.length];
        for (int i = 0; i < _board.getSize()[0]; i++)
            for (int j = 0; j < _board.getSize()[1]; j++)
                for (int j2 = 0; j2 < _players.length; j2++)
                    if (_players[j2].getColour() == _board.stoneAt(i, j))
                        scores[j2]++;
        for (int i = 0; i < _players.length; i++) {
            _players[i].setScore(scores[i]);
        }
    }

    public int isGameOver() {
        int winner = 0;
        for (int i = 0; i < _players.length; i++) {
            for (int j = 0; j < _board.getSize()[0]; j++)
                for (int j2 = 0; j2 < _board.getSize()[1]; j2++)
                    if (canPlace(j, j2).size() != 0)
                        return -1;
            advanceTurn();
        }
        for (int i = 1; i < _players.length; i++)
            if (_players[i].getPoints() > _players[winner].getPoints())
                winner = i;
        return winner;
    }
    public Player getCurrentPlayer() {
        return _players[_turn];
    }
}

public static class AI {
    public int[] play(int diff, GameBoard board, int colour) {
        //List all possible moves
        int[] move = new int[2];
        LinkedList<int[]> posibilities = new LinkedList<int[]>();
        for (int i = 0; i < board.getSize()[0]; i++)
            for (int j = 0; j < board.getSize()[1]; j++)
                if (board.canPlace(i, j, colour).size() > 0) {
                    int[] temp = {i, j};
                    posibilities.add(temp);
                }

        //Choose a move according to AI difficulty
        switch (diff) {
        case 1: // Easy - random
            Random r = new Random();
            move = posibilities.get(r.nextInt(posibilities.size()));
            break;

        case 2: // Medium - max kills
            int max = 0, kills = board.canPlace(posibilities.get(0)[0], posibilities.get(0)[1], colour).size();
            for (int i = 1; i < posibilities.size(); i++) {
                int[] temp = posibilities.get(i);
                int tempkills = board.canPlace(temp[0], temp[1], colour).size();
                if (kills < tempkills) {
                    kills = tempkills;
                    max = i;
                }
            }
            move = posibilities.get(max);
            break;

        case 3: // Hard
            break;
        }

        return move;
    }
}

public static class GameBoard {
    private int[][] _board;
    private int _m;
    private int _n;

    public GameBoard(int m, int n, int[] colours) {
        _m = m;
        _n = n;
        _board = new int[m][n];
        for (int i = 0; i < _board.length; i++)
            for (int j = 0; j < _board[i].length; j++)
                _board[i][j] = 0;
        if (_m % 2 == 0 && _n % 2 == 0) {
            _board[m/2][n/2] = _board[m/2 - 1][n/2 - 1] = colours[0];
            _board[m/2][n/2 - 1] = _board[m/2 - 1][n/2] = colours[1];
        }

        int[][] testBoard = {
                {2, 2, 2, 2, 1, 1, 2, 2},
                {2, 1, 2, 2, 1, 1, 1, 2},
                {1, 1, 2, 2, 1, 2, 2, 1},
                {2, 2, 2, 1, 2, 1, 1, 1},
                {2, 2, 1, 2, 1, 1, 1, 2},
                {1, 1, 1, 2, 2, 2, 2, 2},
                {1, 1, 1, 2, 2, 2, 2, 2},
                {1, 1, 1, 2, 1, 1, 1, 0}};
        //_board = testBoard;
    }

    public int[] getSize() {
        int[] size = {_m, _n};
        return size;
    }

    public LinkedList<int[]> canPlace(int y, int x, int colour) {
        LinkedList<int[]> eats = new LinkedList<int[]>();
        if (_board[y][x] != 0) return eats;
        int i;
        if (existsAnotherIn("u", y, x, colour)) {
            i = 1;
            while (isInBounds(y + i, x) && _board[y + i][x] != colour && _board[y + i][x] != 0) {
                int[] temp = {y + i, x};
                eats.add(temp);
                i++;
            }
        }
        if (existsAnotherIn("d", y, x, colour)) {
            i = 1;
            while (isInBounds(y - i, x) && _board[y - i][x] != colour && _board[y - i][x] != 0) {
                int[] temp = {y - i, x};
                eats.add(temp);
                i++;
            }       
        }
        if (existsAnotherIn("l", y, x, colour)) {
            i = 1;
            while (isInBounds(y, x - i) && _board[y][x - i] != colour && _board[y][x - i] != 0) {
                int[] temp = {y, x - i};
                eats.add(temp);
                i++;
            }
        }
        if (existsAnotherIn("r", y, x, colour)) {
            i = 1;
            while (isInBounds(y, x + i) && _board[y][x + i] != colour && _board[y][x + i] != 0) {
                int[] temp = {y, x + i};
                eats.add(temp);
                i++;
            }
        }
        if (existsAnotherIn("ul", y, x, colour)) {
            i = 1;
            while (isInBounds(y + i, x - i) && _board[y + i][x - i] != colour && _board[y + i][x - i] != 0) {
                int[] temp = {y + i, x - i};
                eats.add(temp);
                i++;
            }
        }
        if (existsAnotherIn("ur", y, x, colour)) {
            i = 1;
            while (isInBounds(y + i, x + i) && _board[y + i][x + i] != colour && _board[y + i][x + i] != 0) {
                int[] temp = {y + i, x + i};
                eats.add(temp);
                i++;
            }
        }
        if (existsAnotherIn("dl", y, x, colour)) {
            i = 1;
            while (isInBounds(y - i, x - i) && _board[y - i][x - i] != colour && _board[y - i][x - i] != 0) {
                int[] temp = {y - i, x - i};
                eats.add(temp);
                i++;
            }
        }
        if (existsAnotherIn("dr", y, x, colour)) {
            i = 1;
            while (isInBounds(y - i, x + i) && _board[y - i][x + i] != colour && _board[y - i][x + i] != 0) {
                int[] temp = {y - i, x + i};
                eats.add(temp);
                i++;
            }
        }
        return eats;
    }

    private boolean isInBounds(int i, int j) {
        return i >= 0 && j >= 0 && i < _m && j < _n;
    }

    private boolean existsAnotherIn(String lane, int vo, int ho, int colour) {
        int v = 0, h = 0;

        do {
            if ((v != 0 || h != 0) && _board[vo + v][ho + h] == colour) return true;

            if (lane.contains("u"))         v++;
            else if (lane.contains("d"))    v--;
            if (lane.contains("r"))         h++;
            else if (lane.contains("l"))    h--;
        } while (isInBounds(vo + v, ho + h) && _board[vo + v][ho + h] != 0);
        return false;
    }

    public int place(int y, int x, int colour) {
        LinkedList<int[]> stonesToEat = canPlace(y, x, colour);
        if (!stonesToEat.isEmpty()) {
            _board[y][x] = colour;
            for (int i = 0; i < stonesToEat.size(); i++) {
                int[] place = stonesToEat.get(i);
                _board[place[0]][place[1]] = colour;
            }
        }
        return stonesToEat.size();
    }

    public String toString() {
        String s = "";
        for (int i = 0; i < _board.length; i++) {
            for (int j = 0; j < _board[0].length; j++) {
                s+=_board[i][j]+"\t";
            }
            s += "\n";
        }
        return s;
    }

    public int stoneAt(int i, int j) {
        return _board[i][j];
    }
}

public static class Player {
    private String _name;
    private int _points;
    private int _colour;
    private int _ai;

    public Player(String name, int colour, int ai) {
        _name = name;
        _points = 0;
        _colour = colour;
        _ai = ai;
    }

    public void setScore(int s) {
        _points = s;
    }

    public Player(Player p) {
        _name = p._name;
        _points = p._points;
        _colour = p._colour;
        _ai = p._ai;
    }

    public boolean isAI() {
        return _ai != 0;
    }

    public void addPoints(int add) { _points += add; }

    public int getColour() { return _colour; }

    public String getName() { return _name; }

    public int getPoints() { return _points; }

    public int getAI() { return _ai; }
}

public class GameLog extends GameManager {
    private int _startingPlayer;
    private LinkedList<String> _moves;

    public GameLog(int startPlayer) {
        _startingPlayer = startPlayer;
        _moves = new LinkedList<String>();
    }

    public void addMove(String m) {
        _moves.add(m);
    }

    public int getStartingPlayer() { return _startingPlayer; }

    public LinkedList<String> getMoves() { return _moves; }
}

}

1 个答案:

答案 0 :(得分:3)

你在想这个。只需创建一个单一的Swing Timer ,就是它,然后给它一个状态 - 即,给它的ActionListener字段改变,一个是一个布尔值,表示何时闪烁,你转为true和false,另一个,一个计算闪烁次数的int,在达到一定数量后关闭Timer,然后移动。

这样简单
20:1E:50:3F:8A:3E
20:1E:50:3F:8A:3F
20:1E:50:3F:8A:40
20:1E:50:3F:8A:41
20:1E:50:3F:8A:42
20:1E:50:3F:8A:43

这个的总运行时间是MAX_COUNT *计时器的延迟。

例如,

enter image description here

function generate($prefix, $start, $end){

    $start = str_split($start);
    $end = str_split($end);

    $start_first = $start[0];
    $start_second = $start[1];

    $end_first = $end[0];
    $end_second = $end[1];

    if(is_numeric($start_second)){
        $start_second_numeric = true;
    }
    else{
        $start_second_numeric = false;
    }

    if(is_numeric($end_second)){
        $end_second_numeric = true;
    }
    else{
        $end_second_numeric = false;
    }

    $mac_array = array();

    $range_first = range($start_first, $end_first);

    foreach($range_first as $first_character){

        if($start_second_numeric && $end_second_numeric || !$start_second_numeric && !$end_second_numeric){
            $range_second = range($start_second, $end_second);
        }
        elseif(!$start_second_numeric && $end_second_numeric){
            $range_second = range($start_second, "F");
            $range_third = range("0", $end_second);
        }
        elseif($start_second_numeric && !$end_second_numeric){
            $range_second = range($start_second, "9");
            $range_third = range("A", $end_second);
        }

        foreach($range_second as $second_character){
            $string = $prefix . ":" . $first_character . $second_character;
            array_push($mac_array, $string);
        }

        if(is_array($range_third)){
            foreach($range_third as $second_character){
                $string = $prefix . ":" . $first_character . $second_character;
                array_push($mac_array, $string);
            }
        }

    }

    return $mac_array;
}