2012-01-27 11 views
12

Próbowałem utworzyć dowolny komponent, który można przeciągnąć, po prostu dodając detektory myszy i używając funkcji setLocation z java.awt.Component. Zacząłem od JButton, aby sprawdzić, czy to możliwe, jak myślałem.Elementy komponentu Java z myszą

Oto przykładowy kod dla co próbuję zrobić:

import java.awt.*; 
import javax.swing.*; 

public class DragButton extends JButton{ 

private volatile int draggedAtX, draggedAtY; 

public DragButton(String text){ 
    super(text); 
    setDoubleBuffered(false); 
    setMargin(new Insets(0, 0, 0, 0)); 
    setSize(25, 25); 
    setPreferredSize(new Dimension(25, 25)); 

    addMouseListener(new MouseAdapter(){ 
     public void mousePressed(MouseEvent e){ 
      draggedAtX = e.getX() - getLocation().x; 
      draggedAtY = e.getY() - getLocation().y; 
     } 
    }); 

    addMouseMotionListener(new MouseMotionAdapter(){ 
     public void mouseDragged(MouseEvent e){ 
      setLocation(e.getX() - draggedAtX, e.getY() - draggedAtY); 
     } 
    }); 
} 

public static void main(String[] args){ 
    JFrame frame = new JFrame("DragButton"); 
    frame.setLayout(null); 
    frame.getContentPane().add(new DragButton("1")); 
    frame.getContentPane().add(new DragButton("2")); 
    frame.getContentPane().add(new DragButton("3")); 
    frame.setSize(300, 300); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true); 
    } 
} 

Jakoś to nie działa prawidłowo i nie rozumiem dlaczego. Rzeczywisty przebyta odległość to połowa odległości od ruchu myszy i migocze wokół tej odległości podczas przeciągania, tak jakby dwie pozycje myszy konkurowały o MouseMotionListener.

Czy ktokolwiek może pomóc huśtawce? =) Bardzo dziękuję z góry.

Edit:

Ok, więc problem był taki, że nie wiedział, że zdarzenie będzie refire w każdej lokalizacji myszy z pozycji podlegającej względną do wypalania JComponent (!). To jest poprawiony i działający kod:

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

public class DragButton extends JButton{ 

    private volatile int draggedAtX, draggedAtY; 

    public DragButton(String text){ 
     super(text); 
     setDoubleBuffered(false); 
     setMargin(new Insets(0, 0, 0, 0)); 
     setSize(25, 25); 
     setPreferredSize(new Dimension(25, 25)); 

     addMouseListener(new MouseAdapter(){ 
      public void mousePressed(MouseEvent e){ 
       draggedAtX = e.getX(); 
       draggedAtY = e.getY(); 
      } 
     }); 

     addMouseMotionListener(new MouseMotionAdapter(){ 
      public void mouseDragged(MouseEvent e){ 
       setLocation(e.getX() - draggedAtX + getLocation().x, 
         e.getY() - draggedAtY + getLocation().y); 
      } 
     }); 
    } 

    public static void main(String[] args){ 
     JFrame frame = new JFrame("DragButton"); 
     frame.setLayout(null); 
     frame.getContentPane().add(new DragButton("1")); 
     frame.getContentPane().add(new DragButton("2")); 
     frame.getContentPane().add(new DragButton("3")); 
     frame.setSize(300, 300); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 

Dziękuję Adel za twoje wysiłki i mKorbel za link.

+0

Zobacz również [ 'ChessBoard'] (http://stackoverflow.com/a/2562685/230513). – trashgod

+1

Tak, szklana szyba to z pewnością sposób, w jaki można się tutaj udać, ale starałem się, aby przykład był tak prosty, jak to tylko możliwe, ale nadal można go kompilować. Mam nadzieję, że to nie zmyli przyszłych czytelników. UŻYJ GLASSPANE! (Lub [panel warstwowy] (http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html) ze swoim DRAG_LAYER). – Stephan

Odpowiedz

11

Musisz się przenieść z JComponent, tęsknię tej definicji w pustkach mousePressed/mouseDragged; w innych rękach, nie ma nic lepszego, jak @[camickr][1] doskonały kod dla ComponentMover.

+0

O mój boże, dziękuję bardzo za ten link! Pierwsze kilka trafień sprawiło, że uderzyłem się w głowę. ^^ Edytowałem mój post, aby pokazać poprawny kod. – Stephan

+0

@Stephan: Nie zaniedbuj odpowiedzi w górę, które uznałeś za użyteczne. – trashgod

+0

Cóż, nie mogłem, całkiem niedawno. ;) – Stephan

2

Dlaczego zamiast tego nie używasz interfejsu java Transferable?

Oto tutorial jak to zrobić: http://www.javaworld.com/javaworld/jw-03-1999/jw-03-dragndrop.html

+0

Czy java.awt.dnd obsługuje animację ruchomą komponentów? Nie potrzebuję części upuszczania danych z Drag and Drop (no cóż, potrzebuję tego, ale jest to niewielki problem), a nie samej animacji. Większość samouczków, które znalazłem, opisuje tylko część przenoszenia danych, w której tylko kursor wskazuje przeciągnięcie i upuszczenie. Chcę, aby cały komponent się poruszył. (sry za mój angielski ^^) – Stephan

+0

@Stephan Transferable pochodzi z pakietu _java.awt.datatransfer_ Więc może obsługiwać przeciąganie i upuszczanie w _awt_ –

+0

Sry, ale to nie odpowiada na moje pytanie, jednak znalazłem działający przykład przeciągnięcia i upuść animację (!) za pomocą java.awt.dnd i java.awt.datatransfer: [link] (http://weblogs.java.net/blog/gfx/archive/2005/10/drag_and_drop_e.html). Praca z nim nie jest fajna, ponieważ łączył tylko swój kod źródłowy. – Stephan

4
import javax.swing.*; 
import java.awt.event.*;  

public class movingButton extends JFrame{ 

    private JButton button ; 

    public movingButton() 
    { 
    super("Position helper"); 
     super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     super.setSize(500,520); 
     super.setVisible(true); 
     super.setLayout(null); 
     button = new JButton ("drag me "); 
     add(button); 
     button.setBounds(100, 100, 150, 40);   
     button.addMouseMotionListener(new MouseAdapter(){ 

      public void mouseDragged(MouseEvent E) 
      { 
       int X=E.getX()+button.getX(); 
       int Y=E.getY()+button.getY; 
       button.setBounds(X,Y,150,40); 
      } 
     }); 
    } 

    public static void main (String x[]) 
    {   
     new movingButton(); 
    } 
} 
+0

Działa i adekwatnie do tego, co muszę zrobić, ale wskaźnik myszy jest przesunięty względem rzeczywistego komponentu podczas przeciągania? Jakieś pomysły? – unekwu

0

Lepiej jest, jeśli zrobiłbyś

int X=E.getX() + button.getX(); 
int Y=E.getY() + button.getY(); 
+0

Nie sądzę, że twoja odpowiedź jest właściwa - po pierwsze nie podajesz żadnego komentarza dotyczącego używania tego fragmentu, a po drugie używasz innego rozmiaru liter. –

Powiązane problemy