Swing Icon verschwindet beim Verschieben eines JLabels

olimeck

Mitglied
Als Anfänger stoße ich bei der Programmierung auf folgendes Problem: ein mit einem ImageIcon-Objekt versehenes JLabel verschwindet, sobald ich es verschieben möchte. Woran kann das liegen?


Java:
import java.awt.event.*;

import java.awt.GridBagLayout;



import javax.swing.*;



public class Spielbrett {

    private JFrame frame;

    private Label label;

    private ImageIcon icon;

  

    public static void main(String args[]) {

        new Spielbrett();

    }

  

    public Spielbrett() {

        icon = new ImageIcon("Kreis.png");

        frame = new JFrame();//Neues Frame-Objekt

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//Fenster wird geschlossen, wenn man auf "x" klickt

        frame.setLayout(new GridBagLayout());//Kein Layout hinzugefügt

        label = new Label(icon);//Neues Label-Objekt erstellen

        label.setBounds(50, 50, 100, 100);

        frame.getContentPane().add(label);

      

        frame.setBounds(50,50,1000,1000);//Position des Fensters und Größe festlegen

        frame.setVisible(true);//Fenster sichtbar machen

        label.addMouseMotionListener(new MouseMotionListener() {

            public void mouseMoved(MouseEvent e) {

            }

            public void mouseDragged(MouseEvent e) {

                label.setBounds(label.getMyX() + e.getXOnScreen() - label.getMouseX(), label.getMyY() + e.getYOnScreen() - label.getMouseY(),50,50);

            }

        });

        label.addMouseListener(new MouseListener() {



            @Override

            public void mouseClicked(MouseEvent e) {

              

            }



            @Override

            public void mousePressed(MouseEvent e) {

                label.setMouseX(e.getXOnScreen());

                label.setMouseY(e.getYOnScreen());

                label.setMyX(label.getX());

                label.setMyY(label.getY());

            }



            @Override

            public void mouseReleased(MouseEvent e) {

            }



            @Override

            public void mouseEntered(MouseEvent e) {

              

            }



            @Override

            public void mouseExited(MouseEvent e) {

              

            }

          

        });

      

    }

}

DIE KLASSE Label...

import javax.swing.*;



public class Label extends JLabel{



    private int myX;

    private int myY;

    private int mouseX;

    private int mouseY;

  

    public Label(ImageIcon icon) {

        super(icon);

    }

    public Label(String text){

        super(text);

    }

    public int getMyX() {

        return myX;

    }

    public void setMyX(int x) {

        this.myX = x;

    }

    public int getMyY() {

        return myY;

    }

    public void setMyY(int y) {

        this.myY = y;

    }

    public int getMouseX() {

        return mouseX;

    }

    public void setMouseX(int mouseX) {

        this.mouseX = mouseX;

    }

    public int getMouseY() {

        return mouseY;

    }

    public void setMouseY(int mouseY) {

        this.mouseY = mouseY;

    }

    private static final long serialVersionUID = 1L;



}
 
Lass dir mal die Koordinaten bei jedem mouseDragged ausgeben. Ich bin mir sehr sicher dass deine Rechnung nicht stimmt.

Java:
int x = label.getMyX() + e.getXOnScreen() - label.getMouseX();
int y = label.getMyY() + e.getYOnScreen() - label.getMouseY();

System.out.println(Integer.toString(x) + ":" + Integer.toString(y));
label.setBounds(x, y,50,50);
 
Lass dir mal die Koordinaten bei jedem mouseDragged ausgeben. Ich bin mir sehr sicher dass deine Rechnung nicht stimmt.

Java:
int x = label.getMyX() + e.getXOnScreen() - label.getMouseX();
int y = label.getMyY() + e.getYOnScreen() - label.getMouseY();

System.out.println(Integer.toString(x) + ":" + Integer.toString(y));
label.setBounds(x, y,50,50);

Lass dir mal die Koordinaten bei jedem mouseDragged ausgeben. Ich bin mir sehr sicher dass deine Rechnung nicht stimmt.

Java:
int x = label.getMyX() + e.getXOnScreen() - label.getMouseX();
int y = label.getMyY() + e.getYOnScreen() - label.getMouseY();

System.out.println(Integer.toString(x) + ":" + Integer.toString(y));
label.setBounds(x, y,50,50);
Vielen Dank für den Tipp, ich werde mich morgen gleich ans Werk machen! Bin gespannt, ob ich es hinbekomme. Sieht auf den ersten Blick so aus, als wenn es ein Problem mit der relativen und der absoluten Position auf de Bildschirm wäre... Kann man das so sagen?
 
Das sollte funktionieren:
Java:
        label.addMouseListener(new MouseListener() {
            @Override
            public void mousePressed(MouseEvent e) {
                labelMouseX = label.getMousePosition().x;
                labelMouseY = label.getMousePosition().y;
            }
            
            @Override
            public void mouseClicked(MouseEvent e) {}
            @Override
            public void mouseReleased(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
        } );
        
        label.addMouseMotionListener( new MouseMotionListener() {
            @Override
            public void mouseDragged(MouseEvent e) {
                try {
                    int x = frame.getContentPane().getMousePosition().x - labelMouseX;
                    int y = frame.getContentPane().getMousePosition().y - labelMouseY;
                    label.setLocation(x, y);
                } catch (NullPointerException ex) {}
            }

            @Override
            public void mouseMoved(MouseEvent e) {}
        } );
labelMouseX und labelMouseY sind Instanzvariablen
 
Lass dir mal die Koordinaten bei jedem mouseDragged ausgeben. Ich bin mir sehr sicher dass deine Rechnung nicht stimmt.

Java:
int x = label.getMyX() + e.getXOnScreen() - label.getMouseX();
int y = label.getMyY() + e.getYOnScreen() - label.getMouseY();

System.out.println(Integer.toString(x) + ":" + Integer.toString(y));
label.setBounds(x, y,50,50);
Du hattest Recht, die Koordinaten waren falsch! Vielen Dank für die Hilfe! Von selbst wäre ich da sicherlich ewig nicht draufgekommen! DANKE!
 
Das sollte funktionieren:
Java:
        label.addMouseListener(new MouseListener() {
            @Override
            public void mousePressed(MouseEvent e) {
                labelMouseX = label.getMousePosition().x;
                labelMouseY = label.getMousePosition().y;
            }
           
            @Override
            public void mouseClicked(MouseEvent e) {}
            @Override
            public void mouseReleased(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
        } );
       
        label.addMouseMotionListener( new MouseMotionListener() {
            @Override
            public void mouseDragged(MouseEvent e) {
                try {
                    int x = frame.getContentPane().getMousePosition().x - labelMouseX;
                    int y = frame.getContentPane().getMousePosition().y - labelMouseY;
                    label.setLocation(x, y);
                } catch (NullPointerException ex) {}
            }

            @Override
            public void mouseMoved(MouseEvent e) {}
        } );
labelMouseX und labelMouseY sind Instanzvariablen
 
Hier mal eine klein wenig angepasste Variante, die das Event-Handling in einer separaten Klasse durchführt. Diese erlaubt es prinzipiell, die Komponente auch außerhalb des sichtbaren Bereichs zu verschieben, was aber durch eine entsprechende Prüfung verhindert wird. Natürlich kann der Test entsprechend angepasst werden, z. B. könnte man statt contains auch intersects verwendet werden, dann kann die Komponente zwar teilweise aber nicht vollständig in den nicht-sichtbaren Bereich geschoben werden.

Java:
import java.awt.event.*;
import java.awt.Color;
import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;

import javax.swing.*;

public class Spielbrett {

    public static void main(String args[]) {
        SwingUtilities.invokeLater(() -> new Spielbrett().run());
    }

    public void run() {
        JLabel label = new JLabel("Label");
        label.setBounds(50, 50, 100, 100);
        label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        DragHandler handler = new DragHandler();
        label.addMouseListener(handler);
        label.addMouseMotionListener(handler);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        frame.add(label);
        frame.setBounds(50, 50, 800, 600);
        frame.setVisible(true);
    }

    // Kann zwecks Wiederverwendbarkeit in DragHandler.java ausgelagert werden
    static class DragHandler extends MouseAdapter {
        private Component component;
        private Point dragOffset;

        @Override
        public void mousePressed(MouseEvent e) {
            component = e.getComponent();
            dragOffset = e.getPoint();
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            component = null;
            dragOffset = null;
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            Rectangle bounds = new Rectangle(getLocationOnParent(e), component.getSize());

            // Beispielsweise kann man testen, ob die Komponente vollständig sichtbar ist
            if (component.getParent().getBounds().contains(bounds)) {
                component.setLocation(bounds.getLocation());
            }
        }

        private Point getLocationOnParent(MouseEvent e) {
            // Konvertiere Mauskoordinate in das Koordinatensystem des Parents,
            // da getParent().getMousePosition() null liefert,
            // wenn der Mauszeiger sich außerhalb des Parents befindet.
            Point locationOnParent = e.getLocationOnScreen();
            SwingUtilities.convertPointFromScreen(locationOnParent, component.getParent());
            locationOnParent.translate(-dragOffset.x, -dragOffset.y);
            return locationOnParent;
        }
    }
}
 

Zurück
Oben