首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在并发循环中在计时器上更新JButton

在并发循环中在计时器上更新JButton
EN

Stack Overflow用户
提问于 2012-05-31 14:10:41
回答 2查看 910关注 0票数 3

在并发循环中,让JButton重复更新(与计时器一起使用)有一些问题。我正在做一个简单的游戏,在一个10 * 10的瓷砖对象网格上玩,它对应着一个带有100个按钮的JButton arrayList。

程序的这一部分处理简单的路径查找(即,如果我单击字符,然后是一个空的瓷砖,字符将在其到达目的地的过程中通过每个瓷砖)。每个步骤之间都有一个延迟,这样用户就可以看到字符的进度。

在当前的情况下,移动是正确的,但是只有当字符到达目标时才更新JButton,而不是中间的步骤。

代码语言:javascript
复制
public void move(int terrainTile)
{
    int currentPosition = actorList.get(selectedActor).getPosition();
    int movementValue = 0;
    int destination = terrainTile;
    int destinationX = destination / 10;
    int destinationY = destination % 10;

    do
    {
        currentPosition = actorList.get(selectedActor).getPosition();  // Gets PC's current position (before move)
        System.out.println("Old position is " + currentPosition);
        int currentX = currentPosition / 10;
        int currentY = currentPosition % 10;


        if(actorList.get(selectedActor).getCurrentAP() > 0)
        {
            movementValue = 0;

            if(destinationX > currentX)
            {
                movementValue += 10;
            }

            if(destinationX < currentX)
            {
                movementValue -= 10;
            }

            if(destinationY > currentY)
            {
                movementValue += 1;
            }

            if(destinationY < currentY)
            {
                movementValue -= 1;
            }

            int nextStep = currentPosition + movementValue;

            myGame.setActorIdInTile(currentPosition, -1);  //Changes ActorId in PC current tile back to -1
            scrubTiles(currentPosition);

            actorList.get(selectedActor).setPosition(nextStep);  //  Sets new position in actor object
            System.out.println("Actor " + selectedActor + " " + actorList.get(selectedActor).getName() + " position has been updated to " + nextStep);

            myGame.setActorIdInTile(nextStep, selectedActor); // Sets ActorId in moved to Tile
            System.out.println("Tile " + nextStep + " actorId has been updated to " + selectedActor);

            buttons.get(nextStep).setIcon(new ImageIcon(actorList.get(selectedActor).getImageName()));

            // If orthagonal move AP-4
            if(movementValue == 10 || movementValue == -10 || movementValue == 1 || movementValue == -1)
            {
                actorList.get(selectedActor).reduceAP(4);
            }
            // If diagonal move AP-6
            else
            {
                actorList.get(selectedActor).reduceAP(6);
            }

            System.out.println(actorList.get(selectedActor).getName() + " has " + actorList.get(selectedActor).getCurrentAP() + " AP remaining");

            try
            {
                Thread.sleep(500);    // one second
            }
            catch (Exception e){} 

            buttons.get(nextStep).repaint();

        }

        else
        {
            System.out.println(actorList.get(selectedActor).getName() + " has insufficient AP to move");
            break;
        }

    }while(destination != (currentPosition + movementValue));

我试过的是:

  1. buttons.get(nextStep).repaint();(尝试在设置imageIcon后放置一个命令来重新绘制按钮。No change.
  2. buttons.get(nextStep).revalidate();(No 100%肯定这是一种潜在的解决方案,但不起作用。
  3. 步骤1&2 combined
  4. Looked进入swing计时器类-不是每次触发actionEvent时都会发生移动(只有当字符被选中并且目标瓷砖为空时),所以不确定如何才能使其工作

任何帮助都将不胜感激!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-31 16:41:01

我真的不知道你在评论中到底想知道什么,尽管上面的答案是+1,但在我看来,这才是真正的原因。看看这个示例程序,只需在move(...)中添加对timerAction方法的调用,这似乎对您是有效的。在这里,尝试下面的代码:

代码语言:javascript
复制
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GridExample
{
    private static final int SIZE = 36;
    private JButton[] buttons;
    private int presentPos;
    private int desiredPos;
    private Timer timer;
    private Icon infoIcon = 
                UIManager.getIcon("OptionPane.informationIcon");

    private ActionListener timerAction = new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            buttons[presentPos].setIcon(null);
            if (desiredPos < presentPos)
            {
                presentPos--;
                buttons[presentPos].setIcon(infoIcon);
            }
            else if (desiredPos > presentPos)
            {
                presentPos++;
                buttons[presentPos].setIcon(infoIcon);
            }
            else if (desiredPos == presentPos)
            {
                timer.stop();
                buttons[presentPos].setIcon(infoIcon);
            }
        }
    };

    public GridExample()
    {
        buttons = new JButton[SIZE];
        presentPos = 0;
        desiredPos = 0;
    }

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("Grid Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setLayout(new GridLayout(6, 6, 5, 5));
        for (int i = 0; i < SIZE; i++)
        {
            final int counter = i;
            buttons[i] = new JButton();
            buttons[i].setActionCommand("" + i);
            buttons[i].addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent ae)
                {
                    desiredPos = Integer.parseInt(
                                    (String) buttons[counter].getActionCommand());
                    timer.start();              
                }
            });
            contentPane.add(buttons[i]);
        }
        buttons[presentPos].setIcon(infoIcon);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        timer = new Timer(1000, timerAction);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new GridExample().createAndDisplayGUI();
            }
        });
    }
}
票数 2
EN

Stack Overflow用户

发布于 2012-05-31 14:17:22

这是因为在UI线程中执行do {}。要解决这个问题,您应该使用SwingWorker或javax.swing.Timer

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10835322

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档