0

I'm trying to move a robot represented by a JLabel into a GridLayout. The move is made but the display of the JLabel is only done for the final finishing square. I would like to see the move from box to box. I try to use javax.swing.Timer but it's not working.

import java.awt.Color;
import java.awt.Component;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.LayoutStyle;
import javax.swing.Timer;

// Robot

public class Robot extends Case implements Serializable {
    private ImageIcon imageRobot;
    private Color couleur;

    public Robot () {
        imageRobot = new ImageIcon("./assets/balle.png");
        setIcon(imageRobot);
    }

    public void seDeplacer (JPanel panel) {
        Robot currentRoot = this;
            int delay = 1000; //milliseconds
              ActionListener taskPerformer = new ActionListener() {
                  public void actionPerformed(ActionEvent evt) {
                        for (int i=0; i<5; i++) {
                        panel.remove(panel.getComponent(i));
                        panel.add(currentRoot, i);
                        panel.doLayout();   
                        }
                  }
              };
              new Timer(delay, taskPerformer).start();

    }

    public void detruire () {

    }

    public void setCouleur (Color couleur) {
        this.couleur=couleur;
    }

    public Color getCouleur () {
        return this.couleur;
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • The trick here is to fill the panel with "blank" components and then change the `ZOrder` of the component to move it. For [example](https://stackoverflow.com/questions/34585343/trying-to-move-jlabels-on-a-jpanel-with-gridlayout/34585504#34585504), [example](https://stackoverflow.com/questions/21032140/moving-jlabel-to-a-different-place-in-the-jpanel-pacman-like-game/21032258#21032258), [example](https://stackoverflow.com/questions/16834765/move-jbutton-with-keyboard-arrows-inside-a-grid-panel/16835242#16835242). – MadProgrammer Nov 14 '19 at 22:16
  • I'd also avoid calling `doLayout` directly and instead would recommend using `invalidate` and `repaint` instead – MadProgrammer Nov 14 '19 at 22:17
  • A Timer replaces looping code. If you want to have 5 moves then you start the Timer after the 5th time you stop the timer. For example: https://stackoverflow.com/questions/31795610/timer-doesnt-stop-trying-to-do-clicks-for-n-steps/31795969#31795969 – camickr Nov 15 '19 at 01:21

2 Answers2

0

This block

public void seDeplacer (JPanel panel) {
        Robot currentRoot = this;
            int delay = 1000; //milliseconds
              ActionListener taskPerformer = new ActionListener() {
                  public void actionPerformed(ActionEvent evt) {
                        for (int i=0; i<5; i++) {
                        panel.remove(panel.getComponent(i));
                        panel.add(currentRoot, i);
                        panel.doLayout();   
                        }
                  }
              };
              new Timer(delay, taskPerformer).start();

says literally "move my robot 5 times every second" thus robots moves 5 in blink of an eye every second.

What you wat is to move robot 1 time every second. To do that you need to introduce delay between robot moves.

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
0

You & the current commentators are over (or under - shrugs) thinking this. It is not necessary to add or remove components or change Z order to move the robot, just change the label text of the place moved from " " and the new label text to `"🤖".

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class MovingBot {

    private JComponent ui = null;
    String bot = new String(Character.toChars(129302));
    Font font;
    JLabel[] labels = new JLabel[100];

    MovingBot() {
        initUI();
    }

    public void initUI() {
        if (ui!=null) return;
        Font[] fonts = GraphicsEnvironment.
                getLocalGraphicsEnvironment().getAllFonts();
        for (Font font : fonts) {
            if (font.canDisplay(129302)) {
                this.font = font.deriveFont(20f);
            }
        }

        ui = new JPanel(new GridLayout(0,20,2,2));
        ui.setBorder(new EmptyBorder(4,4,4,4));

        for (int ii=0; ii<labels.length; ii++) {
            JLabel l = new JLabel(" ");
            l.setFont(font);
            ui.add(l);
            labels[ii] = l;
        }
        labels[0].setText(bot);
        ActionListener moveListener = new ActionListener() {

            int count = 0;

            @Override
            public void actionPerformed(ActionEvent e) {
                int indexLast = count%100;
                labels[indexLast].setText(" ");
                count++;
                int indexCurrent = count%100;
                labels[indexCurrent].setText(bot);
            }
        };
        Timer timer = new Timer(50, moveListener);
        timer.start();
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                MovingBot o = new MovingBot();

                JFrame f = new JFrame(o.getClass().getSimpleName());
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433