2009-05-17 3 views
16

Я искал в Интернете примеры перетаскиваемых компонентов Swing, , но я нашел либо неполные, либо неработающие примеры.Swing: Создание перетаскиваемого компонента ...?

Что мне нужно, это свинг компонент, который может быть тащили мышью внутри другого компонента. При перетаскивании он должен уже изменить свою позицию, а не просто «перейти» к месту назначения.

Мне бы очень понравились примеры, которые работают без нестандартных API.

спасибо.

ответ

29

Я предлагаю простой, но хорошо работает решение, выяснил сам;)

Что мне делать?

  • Когда мышь нажата, я записываю позицию курсора на экране и положение компонента.
  • Когда мышь перетаскивается, рассчитать разницу между новыми и позиции старого курсора на экране и переместите компонент этой разностью.

Испытан с последним JDK 6 унтер Linux (OpenSuse, KDE3)
но эй, это Java Swing, должна работать одинаково везде.

Здесь идет код:

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

Я прекрасно работает и кратким. Спасибо, что спасли мой день. – Dhanushka

1

Кроме того, я обнаружил, что один может создать JInternalFrame внутри JFrame, но проблема: вы получаете всегда раздражает заголовок окна бар.

Чтобы отключить строку заголовка, к сожалению, грязный обходной необходимо:

public class MyDraggableComponent extends JInternalFrame { 

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

} 

Я очень скучаю метод, как "someInternalFrame.setWindowTitleBar (ложной)" ...
: '(

+2

Подкласс может предоставить метод 'setWindowTitleBar()'! – 11684

1

Вот еще один подход, который вы можете попробовать. Я думаю, что он довольно чистый.Просто скопируйте следующий класс и использовать его как это:

Использование:

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

Класс:

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); 
    } 
} 
Смежные вопросы