mit Maus verschiebbares Panel

Diskutiere mit Maus verschiebbares Panel im AWT, Swing, JavaFX & SWT Bereich.
B

blz

Hallo,
ich habe mich durchs Internet gewurstet und auch einige Beispiele gefunden, bei denen man Panels mit der Maus verschieben kann.
Allein - sie funktionieren nicht ganz oder ich verstehe sie nicht ganz.
Ich habe mir daraus nun selbst ein Minimalbeispiel (mit zunächst nur einem Panel) gebastelt, das in groben Zügen funktioniert.
Ich hätte dazu aber einige Fragen:

  1. Meine Idee wäre, einfach dem panel, das ich verschieben will, einen MouseListener hinzuzufügen. Es klappt aber nur, wenn ich auch noch einen MousemotionListener hinzufüge. Warum?
  2. Irgendetwas scheint bei der Berechnung der Position des Mauszeigers nicht zu passen. Ich habe diese Berechnungen auch nur deshalb so, weil sie in fast allen Beispielen, die ich gefunden habe, so waren. Ich kann sie aber nicht ganz nachvollziehn, v. a. nicht, warum immer mit getxonscreen() gearbeitet wird. So wie ich diese Methode verstehe, liefert sie einen Wert von der linken oberen Ecke des Bildschirms aus. Aber dann dürfte doch diese Berechnung nicht mehr klappen, wenn ich das Fenster verschiebe?
    Meine Idee wäre:
    In Mousepressed:
    1. Position des Zeigers innerhalb des zu verschiebenden Panels abfragen.
    2. Position des Panels innerhalb des Programmfensters abfragen.
      --> Abstand d vom Mauszeiger zu der Ecke links oben des verschiebbaren Panels ausrechnen

in MouseDragged:
1. Position des Mauszeigers innerhalb des Programmfensters abfragen
2. Dann davon d abziehen und dahin das verschiebbare Panel setzen.

Vielen Dank!

Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

class FrameWithMoveables extends JFrame {

    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
    private MyPanel actPanel;   
    private MouseHandler mh = new MouseHandler();

    public FrameWithMoveables() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(0, 0, 500, 500);
        setResizable(false);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(null);
        setContentPane(contentPane);       

        MyPanel panel = new MyPanel(new Point2D.Float(60, 100), new Dimension(70, 70), Color.RED);
        panel.addMouseListener(new MouseHandler());
        panel.addMouseMotionListener(mh);
    }

    private class MouseHandler extends MouseAdapter {
        int dx;
        int dy;
        
        @Override
        public void mouseDragged(MouseEvent arg0) {           
            if (arg0.getComponent() == actPanel) {
                actPanel.setLocation((arg0.getXOnScreen() - dx), (arg0.getYOnScreen() - dy));               
            }
        }

        @Override
        public void mouseMoved(MouseEvent arg0) {
        }

        @Override
        public void mousePressed(MouseEvent arg0) {
            actPanel = (MyPanel) arg0.getSource();           
            dx = arg0.getXOnScreen() - actPanel.getX();
            System.out.println(arg0.getXOnScreen());
            System.out.println(actPanel.getX());
            System.out.println(dx);
            dy = arg0.getYOnScreen() - actPanel.getY();
        }

        @Override
        public void mouseReleased(MouseEvent arg0) {           
            dx=0;
            dy=0;
        }

        @Override
        public void mouseEntered(MouseEvent arg0) {
        }
    }
    

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    FrameWithMoveables frame = new FrameWithMoveables();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
 
B

blz

Eine Frage habe ich mittlerweile selbst lösen können, dank dieser hervorragenden Erklärung:
https://javabeginners.de/Ereignisbehandlung/Mausereignisse.php

Ich muss den MouseListener hinzufünge für z. B. die Methode mousePressed,
den MouseMotionListener für z. B. die Methode mouseDragged

Da derMouseAdapter beide Interfaces implementiert, ist nur das eine Objekt nötig (also sinnlos oben, ich könnte immer mh hinzufügen), es sind aber beide Hinzufügungen (einmal als MotionListener, einmal als MouseListener) nötig.
Schönes Klassendiagramm:
http://www.scalingbits.com/java/javakurs2/swing/adapter
 
B

blz

Erfreut stelle ich nun fest, dass sich dadurch auch das Problem der Mauszeigerposition erledigt hat :)
Dann scheint die Berechnung zu stimmen.
Also scheint getXOnScreen() nicht die Position auf dem gesamten Bildschirm auszugeben (so habe ich es wohl fälschlich aus der api herausgelesen), sondern nur die Position innerhalb des aktuellen Programms.
Denn dann stimmt die Berechnung mit meinem obigen Vorschlag überein.

Ein Problem bleibt:
Das Panel wird bei schneller Bewegung immer ein bisschen gestaucht ... Woran kann das liegen?
Hier noch einmal der vollständige Code:

Java:
package blah_mit_Randerkennung2;


import java.awt.Color;

import java.awt.Dimension;
import java.awt.EventQueue;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

class FrameWithMoveables extends JFrame {

    /**
     *
     */
    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
    private MyPanel actPanel;   
    private MyMouseAdapter mh = new MyMouseAdapter();

    public FrameWithMoveables() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(0, 0, 500, 500);
        setResizable(false);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(null);
        setContentPane(contentPane);       

        MyPanel panel = new MyPanel(new Point2D.Float(60, 100), new Dimension(60, 60), Color.PINK);
        panel.addMouseListener(mh);
        panel.addMouseMotionListener(mh);

//        MyPanel panel1 = new MyPanel(new Point2D.Float(120, 150), new Dimension(60, 60), Color.RED);
//        panel1.addMouseListener(new MouseHandler());
//        panel1.addMouseMotionListener(mh);
//
//        MyPanel panel2 = new MyPanel(new Point2D.Float(200, 250), new Dimension(60, 60), Color.blue);
//        panel2.addMouseListener(new MouseHandler());
//        panel2.addMouseMotionListener(mh);

//        contentPane.addMouseListener(mh);
//        contentPane.addMouseMotionListener(mh);
          contentPane.add(panel);
//        contentPane.add(panel1);
//        contentPane.add(panel2);
    }

    private class MyMouseAdapter extends MouseAdapter {
        int dx;
        int dy;
        
        @Override
        public void mouseDragged(MouseEvent arg0) {           
            if (arg0.getComponent() == actPanel) {
                actPanel.setLocation((arg0.getXOnScreen() - dx), (arg0.getYOnScreen() - dy));               
            }
        }

        @Override
        public void mouseMoved(MouseEvent arg0) {
        }

        @Override
        public void mousePressed(MouseEvent arg0) {
            actPanel = (MyPanel) arg0.getSource(); 
            // Differenz aus der x-Mauszeigerposition innerhalb des Programmfensters und der x-Position des zu verschiebenen Panels
            // --> Ergibt die x-Entfernung des Mauszeigers von der linken oberen Ecke des Panels
            dx = arg0.getXOnScreen() - actPanel.getX();
            System.out.println(arg0.getXOnScreen());
            System.out.println(actPanel.getX());
            System.out.println(dx);
            // analog
            dy = arg0.getYOnScreen() - actPanel.getY();
        }

        @Override
        public void mouseReleased(MouseEvent arg0) {           
            dx=0;
            dy=0;
        }

        @Override
        public void mouseEntered(MouseEvent arg0) {
        }
    }
    

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    FrameWithMoveables frame = new FrameWithMoveables();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
 
Thema: 

mit Maus verschiebbares Panel

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben