2009-05-17 22 views
16

He buscado en la web ejemplos de componentes Swing arrastrables, pero encontré ejemplos incompletos o que no funcionan.Swing: ¿Crear un componente arrastrable ...?

Lo que necesito es un componente oscilación que puede ser arrastrado por el ratón dentro de un otro componente. Mientras está siendo arrastrado, debe ya cambiar su posición, no solo 'saltar' a su destino.

Me gustaría ver ejemplos que funcionen sin API no estándar.

Gracias.

Respuesta

29

propongo un sencillo, pero la solución que funcione bien, se enteró por mí mismo;)

¿Qué hago?

  • Cuando se pulsa el ratón, grabo posición del cursor de en la pantalla, y la posición del componente .
  • Cuando se arrastra el ratón, que se calcula la diferencia entre nuevo y vieja posición del cursor en la pantalla , y mover el componente por esta diferencia de.

Probado con el último JDK 6 unter Linux (OpenSuse, KDE3),
pero bueno, es Java Swing, debería funcionar igual en todas partes.

Aquí va el código:

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

que funciona perfectamente y conciso. Gracias por salvarme el día. – Dhanushka

1

Además, descubrí que se podía crear una JInternalFrame dentro de un JFrame, pero el problema es: siempre se obtiene un título de la ventana molesta bar.

Para desactivar la barra de título, por desgracia, una solución sucia es necesario:

public class MyDraggableComponent extends JInternalFrame { 

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

} 

me falta un método como "someInternalFrame.setWindowTitleBar (falso)" ...
: '(

+2

¡La subclasificación podría proporcionar el método 'setWindowTitleBar()'! – 11684

1

Aquí hay un enfoque más que quizás quieras probar. Creo que está bastante limpio.Sólo tienes que copiar la siguiente clase y utilizar de esta manera:

Uso:

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

Clase:

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); 
    } 
} 
Cuestiones relacionadas