Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
190 views
in Technique[技术] by (71.8m points)

java - Updating JButton on a timer in a do-while loop

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.

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

What I've tried:

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

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

  3. Steps 1 & 2 combined

  4. 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!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is because you are doing your do { } while in the UI thread. To solve this, you should use a SwingWorker, or a javax.swing.Timer


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...