TransWikia.com

Подвисает перерисовка части интерфейса

Stack Overflow на русском Asked by V-CHO on February 13, 2021

Написал программу по игре шахматного типа. Доска представлена матрицей JButton-ов. При входе в условие else if следующая проблема: первый вызов метода перерисовки updateGUI() не выполняется до конца, т.е. фигура не "переходит"/перерисовывается на указанную клетку сразу, программа почему-то идёт дальше по листингу, вызывая метод вычисления ответного хода компьютера plate.compute() и отрисовывает уже итоговую ситуацию после хода обеих сторон (видимо, по окончанию второго вызова метода updateGUI()) – в момент ожидания GUI как-бы "залипает", а клетка назначения подсвечена стандартным визуальным эффектом от нажатия кнопки.

    for(int r=0;r<4;r++) {
        for(int c=0;c<3;c++) {
            squares[r][c] = new JButton();
            squares[r][c].setSize(200, 200);
            squares[r][c].setBorder(new LineBorder(Color.GRAY));
            squares[r][c].setBackground(Color.decode("#db9356"));
                squares[r][c].addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JButton theButton = (JButton) e.getSource();
                    for(int r=0;r<4;r++) {
                        for(int c=0;c<3;c++) {
                    if(theButton == squares[r][c] & click == 1 & plate.list(squares[r][c].getName())){
                        squares[r][c].setBackground(Color.YELLOW);
                        highlight(r, c);
                        plate.from(r, c, squares[r][c].getName());
                        click = 2;
                        output.setText(Piece.name(squares[r][c].getName()) +" choosen");
                        drop = false;
                        return;
                        }
                    else if(theButton == squares[r][c] & click == 2 & plate.list(squares[r][c].getName())==false){
                        if(plate.to(r, c)){
                            squares[r][c].setBackground(Color.decode("#db9356"));
                            click = 1;
                            if(drop & squares[r][c].getName()==" "){
                                plate.drop();
                            }
                            else{
                                plate.move();
                            }
                            updateGUI();
                            drop = false;
                            plate.compute();
                            updateGUI();
                            return;
                            }

Если вынести вызов plate.compute() и обновление после ответа отдельно во внешний цикл, тогда рисует нормально, но для активации обдумывания хода компьютером нужно щёлкать на пустой клетке, а это не дело, конечно…

Основной вопрос: JButton-ы в принципе не могут по такой логике отрабатывать или я чего-то не знаю / не понимаю по Свингу?

Сам метод обновления, если нужно (посылает запрос в класс-посредник между GUI и AI и получает инфо для перерисовки на основании подложки – матрицы стрингов):

    void updateGUI() {
    
    for(int r=0;r<4;r++) {
        for(int c=0;c<3;c++) {
            squares[r][c].setBackground(Color.decode("#db9356"));
            squares[r][c].setName(plate.refresh(r,c));
            squares[r][c].setIcon(new ImageIcon(getClass().getResource(image(plate.refresh(r,c)))));
        }
    }       
}

One Answer

Я бы так сделал:

Thread t = new Thread(){
 @Override 
 public void run(){ 
 // Отрисовка
 } 
};
t.start();

Хотя я бы не стал использовать кнопки, лучше все рисовать (например на BufferedImage или как сделано здесь или здесь)

Answered by Agzam4 on February 13, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP