2009-05-17 10 views
16

Ho cercato nel web esempi di componenti di oscillazione trascinabili, ma ho trovato esempi incompleti o non funzionanti.Oscillazione: creazione di un componente trascinabile ...?

cosa ho bisogno è un componente swing che può essere trascinato dal mouse all'interno di un altro componente. Mentre viene trascinato, dovrebbe essere già cambiare la sua posizione, non solo 'saltare' alla sua destinazione.

Apprezzerei gli esempi che funzionano senza API non standard.

Grazie.

risposta

29

propongo un semplice, ma la soluzione ben funzionante, scoperto da solo;)

Cosa devo fare?

  • Quando viene premuto il mouse, registro posizione del cursore sullo schermo e posizione del componente .
  • Quando il mouse viene trascinato, a calcolare la differenza tra nuovi e vecchi cursore posizione sullo schermo, e spostare il componente da questa differenza.

testato con ultima JDK 6 unter Linux (OpenSuse, KDE3),
ma hey, è Java Swing, dovrebbe funzionare altrettanto ovunque.

Qui va il codice:

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

mi funziona perfettamente e concisa. Grazie per aver salvato la mia giornata. – Dhanushka

1

Inoltre, ho scoperto che si potrebbe creare un JInternalFrame all'interno di un JFrame, ma il problema è: si ottiene sempre un titolo della finestra fastidiosa bar.

Per disattivare la barra del titolo, purtroppo, una sporca soluzione è necessario:

public class MyDraggableComponent extends JInternalFrame { 

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

} 

mi manca un metodo come "someInternalFrame.setWindowTitleBar (false)" ...
: '(

+2

La sottoclasse potrebbe fornire il metodo 'setWindowTitleBar()'! – 11684

1

Ecco un altro approccio che potreste voler provare, penso che sia abbastanza pulito.Basta copiare il seguente classe e usarlo in questo modo:

Usage:

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

Classe:

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); 
    } 
} 
Problemi correlati