JLabel mit ImageIcon per Button bewegen

freixen

Mitglied
Guten Abend zusammen.
Ich verzweifele gerade an einem kleinen Anfängerprojekt.
Sobald ich auf einen Button klicke, soll sich ein Bild (Image auf JLabel) mittels while-Schleife bewegen.
Die Methode "bewege()" funktioniert nicht über den ActionListener.
Wäre schön, wenn sich das jemand angucken würde. Im Vorraus Vielen Dank!

Code:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Simpel extends JFrame implements ActionListener {
    private JLabel lblEurope = new JLabel ();
    private JLabel lblShip = new JLabel ();
    private Icon icoShip = new ImageIcon("ship1_3.png");
    JButton btn1;

    public Simpel() {
        initComponents();
    }

    public void initComponents() {
        setTitle("simpletest");
        setDefaultCloseOperation(EXIT_ON_CLOSE);            
        setContentPane(new JPanel());
        setLocationRelativeTo(null);
        Icon EuropeIcon = new ImageIcon("Karte.jpg");
        lblEurope.setIcon(EuropeIcon);
        getContentPane().add(lblEurope);
        pack();
        setVisible(true);
        getContentPane().setLayout(null);
       
        Icon icoShip = new ImageIcon("ship1_3.png");
        lblShip.setIcon(icoShip);
        lblShip.setBounds(500, 419, 50, 50);
        lblEurope.add(lblShip);
       
        btn1 = new JButton("BITE ME");
        btn1.addActionListener(this);
        btn1.setBounds(238, 339, 200, 50);
        btn1.setVisible(true);
        lblEurope.add(btn1);

        //bewegen(); //<----------------------------------------------------------------------- das klappt
    }
    public static void main(String[] args) {
        new Simpel(); 
    }

    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == this.btn1){
            bewegen(); //<----------------------------- das klappt nicht (Die Grafik bewegt sich nicht. Die Position wird aber in der Konsole hochgezählt)
        }
    }

    public void bewegen(){
        int x=0;
        int y=100;
        while(x < 1000){
                try {Thread.sleep(10); } catch(Exception ex) {}
                x++;
                lblShip.setLocation(x, y);
                lblShip.repaint();
                System.out.println(x +" "+ y);  // <--------------- --Die Positionanzeige funktioniert über den ActionListener - es bewegt sich aber sonst Nichts
        }
    }
}
 
Ich verzweifele gerade an einem kleinen Anfängerprojekt.
Was daran liegt, dass GUIs nichts für Anfänger sind.

Die Methode "bewege()" funktioniert nicht über den ActionListener.
Dass die Methode aus initComponents() heraus funktioniert, hast Du dem "glücklichen" Umstand zu verdanken, dass sie in Deinem Beispiel vom main-Thread aus aufgerufen wird. Im Allgemeinen blockierst Du den EDT. Du musst die Schleife in einem eigenen Thread ausführen, wobei Änderungen am GUI nur im EDT ausgeführt werden dürfen.

Könnte dann etwa so aussehen:

Java:
    public void bewegen(){
        new Thread(() -> {
            int x=0;
            int y=100;
            while(x < 1000){
                try {Thread.sleep(10); } catch(Exception ex) {}
                x++;
                lblShip.setLocation(x, y);
                lblShip.repaint();
                System.out.println(x +" "+ y);  // <--------------- --Die Positionanzeige funktioniert über den ActionListener - es bewegt sich aber sonst Nichts
            }
        }).start();
    }
 
Vielen lieben Dank!
Eine Nachfrage habe ich noch:
Wenn nun, während die Schleife läuft, wiederholt auf den Button geklickt wird, läuft das Ganze aus dem Ruder.
Kann ich das irgendwie abfangen? Am Einfachsten wäre wohl den Button auszublenden, das scheint mir aber etwas stumpf(?)
 
Da hatte ich wohl zu wenig Schlaf ;-)
Gelöst, indem ich eine Boolean Variable einfüge. Z.B. threadRunning. Und die Methode nur ausführen lassen, wenn threadRunning=false;
Nochmals dickes DANKE!
 

Zurück
Oben