在do-while循环中更新计时器上的JButton [英] Updating JButton on a timer in a do-while loop

查看:110
本文介绍了在do-while循环中更新计时器上的JButton的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在do-while循环中重复更新JButton(与计时器一起使用)时遇到了一些麻烦。我正在开发一个简单的游戏,在一个10 * 10网格的瓷砖对象上播放,对应一个带有100个按钮的JButton arrayList。

I'm having some trouble getting a JButton to update repeatedly (used with a timer) in a do-while loop. I'm working on a simple game, played on a 10 * 10 grid of tile objects which correspond to a JButton arrayList with 100 buttons.

程序的这一部分处理简单的寻路(即如果我点击字符,然后是空的图块,字符将在到达目的地的途中穿过每个图块) 。每一步之间都有一个延迟,因此用户可以看到角色的进度。

This part of the program handles simple pathfinding (i.e. if I click on character, then an empty tile, the character will move through each tile on its way to the destination). There is a delay between each step so the user can see the character's progress.

在当前状态下,移动是正确的,但JButton仅在更新时更新角色到达目的地,而不是中间步骤。

In the current state of things, the movement is correct, but the JButton is only updated when the character reaches the destination, not on intermediate steps.

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后重新设置按钮。没有更改。

  1. buttons.get(nextStep).repaint(); (Tried putting a command to repaint the button after setting the imageIcon. No change.

buttons.get(nextStep).revalidate();(否100%确定这是做什么的 - 它是一个潜在的解决方案,但不起作用。

buttons.get(nextStep).revalidate(); (No 100% sure what this does - it came up as a potential solution, but doesn't work.

步骤1& 2合并

Steps 1 & 2 combined

查看swing计时器类 - 每次触发actionEvent时都不会发生移动(仅当选择了字符且目标tile为空时),所以不确定如何将其转换为工作

Looked into the swing timer class - movement doesn't occur everytime an actionEvent is fired, (only if character is selected and target tile is empty) so not sure how I could get this to work

我们非常感谢任何帮助!

Any help would be greatly appreciated!

推荐答案

我真的不确切地知道你在评论中想要知道什么,虽然上面的答案+1,在我看来,这才是真正的原因。看看这个示例程序,简单将您的调用添加到 timerAction 中的 move(...)方法,看起来这对您有用。在这里试试这段代码:

I really dont' know exactly what you wanted to know in your comments, though +1 to the answer above, seems to me that's the real cause. Have a look at this example program, simply add your call to the move(...) method inside the timerAction, seems like that can work for you. Here try this code :

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();
            }
        });
    }
}

这篇关于在do-while循环中更新计时器上的JButton的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆