2009-05-17 13 views
16

Przeszukałem internet pod kątem przykładów ruchomych komponentów Swing, , ale znalazłem przykłady niekompletne lub niedziałające.Swing: Tworzenie komponentu, który można przeciągnąć ...?

Co potrzebne jest składnikiem Swing, które mogą być przeciągnięty przez myszy wewnątrz innego składnika. Podczas przeciągania, powinno ono być już ustawione, a nie tylko "przeskoczyć" do miejsca docelowego.

Doceniam przykłady, które działają bez niestandardowych interfejsów API.

Dziękuję.

Odpowiedz

29

proponuję proste, ale rozwiązanie dobrze działa, dowiedział się od siebie;)

Co mam zrobić?

  • Gdy mysz jest wciśnięty, mogę nagrać kursora pozycję na ekranie i w komponentu stanowisko.
  • Gdy mysz jest przeciągany, obliczyć różnicę między nowym i starym kursora pozycji na ekranie i przenieść komponent o tej różnicy.

Testowane z najnowszej JDK 6 unter Linux (openSUSE KDE3)
ale hej, to jest Java Swing, powinny działać równie wszędzie.

Tu idzie kod:

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

public class MyDraggableComponent 
    extends JComponent { 

    private volatile int screenX = 0; 
    private volatile int screenY = 0; 
    private volatile int myX = 0; 
    private volatile int myY = 0; 

    public MyDraggableComponent() { 
    setBorder(new LineBorder(Color.BLUE, 3)); 
    setBackground(Color.WHITE); 
    setBounds(0, 0, 100, 100); 
    setOpaque(false); 

    addMouseListener(new MouseListener() { 

     @Override 
     public void mouseClicked(MouseEvent e) { } 

     @Override 
     public void mousePressed(MouseEvent e) { 
     screenX = e.getXOnScreen(); 
     screenY = e.getYOnScreen(); 

     myX = getX(); 
     myY = getY(); 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { } 

     @Override 
     public void mouseEntered(MouseEvent e) { } 

     @Override 
     public void mouseExited(MouseEvent e) { } 

    }); 
    addMouseMotionListener(new MouseMotionListener() { 

     @Override 
     public void mouseDragged(MouseEvent e) { 
     int deltaX = e.getXOnScreen() - screenX; 
     int deltaY = e.getYOnScreen() - screenY; 

     setLocation(myX + deltaX, myY + deltaY); 
     } 

     @Override 
     public void mouseMoved(MouseEvent e) { } 

    }); 
    } 

} 

public class Main { 

    public static void main(String[] args) { 
    JFrame f = new JFrame("Swing Hello World"); 

    // by doing this, we prevent Swing from resizing 
    // our nice component 
    f.setLayout(null); 

    MyDraggableComponent mc = new MyDraggableComponent(); 
    f.add(mc); 

    f.setSize(500, 500); 

    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    f.setVisible(true); 
    } 

} 
+0

I działa idealnie i zwięzły. Dziękuję za uratowanie mojego dnia. – Dhanushka

1

Ponadto, okazało się, że można stworzyć JInternalFrame wewnątrz JFrame, ale problemem jest to: masz zawsze irytujące okno tytuł pasek.

Aby wyłączyć pasek tytułu, niestety, brudna obejście jest konieczne:

public class MyDraggableComponent extends JInternalFrame { 

    public MyDraggableComponent() { 
    InternalFrameUI thisUI = getUI(); 
    if (thisUI instanceof BasicInternalFrameUI) { 
     ((BasicInternalFrameUI) thisUI).setNorthPane(null); 
    } 

} 

Tęsknię metody takie jak "someInternalFrame.setWindowTitleBar (fałszywego)" ...
: "(

+2

Podklasy mogą zapewnić metodę 'setWindowTitleBar()'! – 11684

1

Oto jeszcze jedno podejście, które możesz chcieć wypróbować. Myślę, że jest całkiem czysty.Wystarczy skopiować następujące klasy i używać go tak:

Zastosowanie:

DragListener dl = new DragListener(componentOrWindowToBeMoved); dl.addHandle(componentToPickWithTheMouse);

Klasa:

import java.awt.Component; 
import java.awt.MouseInfo; 
import java.awt.Point; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 

public class DragListener extends MouseAdapter { 

    private final Component COMPONENT_TO_DRAG; 
    private final int MOUSE_BUTTON; 
    private Point mousePosition; 
    private Point sourceLocation; 
    private Point locationOnScreen; 
    private int buttonPressed; 

    public DragListener(final Component componentToDrag) { 
     this(componentToDrag, MouseEvent.BUTTON1); 
    } 

    public DragListener(final Component componentToDrag, final int mouseButton)       { 
     this.COMPONENT_TO_DRAG = componentToDrag; 
     this.MOUSE_BUTTON = mouseButton; 
    } 

    @Override 
    public void mousePressed(final MouseEvent e) { 
     this.buttonPressed = e.getButton(); 
     this.mousePosition = MouseInfo.getPointerInfo().getLocation(); 
     this.sourceLocation = new Point(); 
    } 

    @Override 
    public void mouseDragged(final MouseEvent e) { 
     if (this.buttonPressed == MOUSE_BUTTON) { 
      this.locationOnScreen = e.getLocationOnScreen(); 
      this.sourceLocation = this.COMPONENT_TO_DRAG.getLocation(this.sourceLocation); 
      this.sourceLocation.translate((int) (this.locationOnScreen.getX() - this.mousePosition.getX()), (int) (this.locationOnScreen.getY() - this.mousePosition.getY())); 
      this.COMPONENT_TO_DRAG.setLocation(this.sourceLocation); 
      this.mousePosition = MouseInfo.getPointerInfo().getLocation(); 
     } 
    } 

    public void addHandle(Component handle) { 
     handle.addMouseListener(this); 
     handle.addMouseMotionListener(this); 
    } 
}