2014-12-02 2 views
2

좋아, 그럼 내가 설정 한 것은 다음과 같습니다. Java 용 javax.swing을 사용하는 1.7 프로젝트가 있습니다. 이 튜토리얼은 다음 튜토리얼 이외의 첫 번째 프로젝트이며, 테이블 상단에 익숙한 사용자를위한 주도적 인 추적 프로그램입니다. JPanel을 확장 한 클래스 (그리고 Comparable <> 구현)를 사용하여 동적으로 추가하고 각 클래스에 다른 데이터를 추가 할 수 있습니다.자바의 드래그 앤 드롭으로 패널의 순서를 바꿉니다.

패널이 레이아웃에 추가되고 y 위치는 이미 몇 개의 패널이 있는지에 따라 달라집니다. 또한 ArrayList에 추가되어 순서대로 정렬됩니다. 목록을 클래스 속성 중 하나로 정렬 할 수 있습니다.

지금 내가 겪고있는 것은 수동으로 드래그 앤 드롭하여 레이아웃과 ArrayList에서 순서를 변경할 수있게하려는 것입니다. 클래스에 저장된 값을 잃어 버리기 때문에 제거하고 다시 추가 할 수는 없습니다.

  • 이 너무 오래 마우스 버튼을 누름으로서, 패널이 마우스로 드래그 할 필요가 속한 :이를 위해

    나는 다음을 수행 할 필요가있는 JButton를했다.

  • 마우스를 놓으면 마우스의 위치를 ​​확인하고 필요한 경우 그 자리로 가야합니다.

So for example

는 좀 드롭 드래그 튜토리얼을 시도했지만 나는 내가 원하는로 조정할 수 있습니다 하나를 찾을 수 없습니다.

편집 1 : 이것은 내가 시도한 것입니다.

MouseListener listener = new DragMouseAdapter(); 
dragButton.addMouseListener(listener); 
dragButton.setTransferHandler(new TransferHandler("text")); 

그리고

class DragMouseAdapter extends MouseAdapter { 
    public void mousePressed(MouseEvent e) { 
     JComponent c = (JComponent) e.getSource(); 
     TransferHandler handler = c.getTransferHandler(); 
     handler.exportAsDrag(c, e, TransferHandler.COPY); 
     // TODO make it a swap location drag and drop 
    } 
} 

이 튜토리얼에서이었고, 그것이 성공적으로 텍스트를 변경하고 있지만, 모두가 내가 원하는 것을 전혀하지 않고 I가 그것을 변경하는 방법을 모른다 내가 원하는 것을해라.

편집 2 : This tutorial은 작동하지 않는 것을 제외하고는 내가하고 싶은 것을 설명합니다. 다음과 같은 오류가 발생합니다 :

Step 1 of 7: Mouse pressed. Going to export our RandomDragAndDropPanel so that it is draggable. 
Step 2 of 7: Returning the acceptable TransferHandler action. Our RandomDragAndDropPanel accepts Copy only. 
Step 3 of 7: Casting the RandomDragAndDropPanel as Transferable. The Transferable RandomDragAndDropPanel will be queried for acceptable DataFlavors as it enters drop targets, as well as eventually present the target with the Object it transfers. 
Step 4 of 7: Querying for acceptable DataFlavors to determine what is available. Our example only supports our custom RandomDragAndDropPanel DataFlavor. 
Problem lazy loading: RandomDragAndDropPanel 
java.lang.ClassNotFoundException: RandomDragAndDropPanel 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Unknown Source) 
    at java.awt.datatransfer.DataFlavor.tryToLoadClass(Unknown Source) 
    at java.awt.datatransfer.DataFlavor.initialize(Unknown Source) 
    at java.awt.datatransfer.DataFlavor.<init>(Unknown Source) 
    at DnD.DragAndDropPanelsDemo.getDragAndDropPanelDataFlavor(DragAndDropPanelsDemo.java:197) 
    at DnD.RandomDragAndDropPanel.getTransferDataFlavors(DragAndDropPanelsDemo.java:392) 
    at sun.awt.datatransfer.DataTransferer.getFormatsForTransferable(Unknown Source) 
    at sun.awt.dnd.SunDragSourceContextPeer.startDrag(Unknown Source) 
    at java.awt.dnd.DragSource.startDrag(Unknown Source) 
    at java.awt.dnd.DragSource.startDrag(Unknown Source) 
    at java.awt.dnd.DragGestureEvent.startDrag(Unknown Source) 
    at javax.swing.TransferHandler$DragHandler.dragGestureRecognized(Unknown Source) 
    at java.awt.dnd.DragGestureRecognizer.fireDragGestureRecognized(Unknown Source) 
    at javax.swing.TransferHandler$SwingDragGestureRecognizer.gestured(Unknown Source) 
    at javax.swing.TransferHandler.exportAsDrag(Unknown Source) 
    at DnD.DraggableMouseListener.mousePressed(DragAndDropPanelsDemo.java:456) 
    at java.awt.Component.processMouseEvent(Unknown Source) 
    at javax.swing.JComponent.processMouseEvent(Unknown Source) 
    at java.awt.Component.processEvent(Unknown Source) 
    at java.awt.Container.processEvent(Unknown Source) 
    at java.awt.Component.dispatchEventImpl(Unknown Source) 
    at java.awt.Container.dispatchEventImpl(Unknown Source) 
    at java.awt.Component.dispatchEvent(Unknown Source) 
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) 
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) 
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) 
    at java.awt.Container.dispatchEventImpl(Unknown Source) 
    at java.awt.Window.dispatchEventImpl(Unknown Source) 
    at java.awt.Component.dispatchEvent(Unknown Source) 
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
    at java.awt.EventQueue.access$200(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue$4.run(Unknown Source) 
    at java.awt.EventQueue$4.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue.dispatchEvent(Unknown Source) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.run(Unknown Source) 
+0

, 당신은 당신의 시도를 게시 할 수주십시오? – BackSlash

+0

그 내용을 편집 하겠지만 문제는 대부분 내 코드가 작동하지 않는다는 것이 아니라 코드가 무엇인지 잘 모릅니다. –

답변

3

다음은 드래그 앤 드롭으로 패널 순서를 변경하는 예제입니다 (정렬은 지원하지 않음).

enter image description here

  1. DragMouseAdapter#mouseDragged(...)

    : 검색 드래그 패널, 폼 부모 패널과 열린 커서 창을 제거합니다.
  2. DragMouseAdapter#mouseReleased(...) : 드롭 위치 검색, 끌기 패널 삽입, 커서 창 닫기. 우리는 당신이 잘못 무엇인지 찾을 수 있도록
import java.awt.*; 
import java.awt.dnd.*; 
import java.awt.event.*; 
import java.net.*; 
import java.util.*; 
import javax.swing.*; 

public class RearrangeOrderOfPanelsTest2 { 
    public JComponent makeUI() { 
    Box box = Box.createVerticalBox(); 
    DragMouseAdapter dh = new DragMouseAdapter(); 
    box.addMouseListener(dh); 
    box.addMouseMotionListener(dh); 

    int idx = 0; 
    for (JComponent c : Arrays.asList(
      new JLabel("<html>111<br>11<br>11"), 
      new JButton("2"), new JCheckBox("3"), new JTextField(14))) { 
     box.add(createToolbarButton(idx++, c)); 
    } 
    JPanel p = new JPanel(new BorderLayout()); 
    p.add(box, BorderLayout.NORTH); 
    return p; 
    } 

    private static JComponent createToolbarButton(int i, JComponent c) { 
    JLabel l = new JLabel(String.format(" %04d ", i)); 
    l.setOpaque(true); 
    l.setBackground(Color.RED); 
    JPanel p = new JPanel(new BorderLayout()); 
    p.setBorder(BorderFactory.createCompoundBorder(
        BorderFactory.createEmptyBorder(5, 5, 5, 5), 
        BorderFactory.createLineBorder(Color.BLUE, 2))); 
    p.add(l, BorderLayout.WEST); 
    p.add(c); 
    p.setOpaque(false); 
    return p; 
    } 

    public static void main(String... args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override public void run() { 
     createAndShowGUI(); 
     } 
    }); 
    } 

    public static void createAndShowGUI() { 
    JFrame f = new JFrame(); 
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    f.getContentPane().add(new RearrangeOrderOfPanelsTest2().makeUI()); 
    f.setSize(320, 240); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
    } 
} 

class DragMouseAdapter extends MouseAdapter { 
    private static final int xoffset = 16; 
    private static final Rectangle R1 = new Rectangle(); 
    private static final Rectangle R2 = new Rectangle(); 
    private static Rectangle prevRect; 
    private final JWindow window = new JWindow(); 
    private Component draggingComonent; 
    private int index = -1; 
    private Component gap; 
    private Point startPt; 
    private Point dragOffset; 
    private final int gestureMotionThreshold = DragSource.getDragThreshold(); 

    public DragMouseAdapter() { 
    super(); 
    window.setBackground(new Color(0, true)); 
    } 

    @Override public void mousePressed(MouseEvent e) { 
    JComponent parent = (JComponent) e.getComponent(); 
    if (parent.getComponentCount() <= 1) { 
     startPt = null; 
     return; 
    } 
    startPt = e.getPoint(); 
    } 

    private void startDragging(JComponent parent, Point pt) { 
    //get a dragging panel 
    Component c = parent.getComponentAt(pt); 
    index = parent.getComponentZOrder(c); 
    if (Objects.equals(c, parent) || index < 0) { 
     return; 
    } 
    draggingComonent = c; 
    Dimension d = draggingComonent.getSize(); 

    Point dp = draggingComonent.getLocation(); 
    dragOffset = new Point(pt.x - dp.x, pt.y - dp.y); 

    //make a dummy filler 
    gap = Box.createRigidArea(d); 
    swapComponentLocation(parent, c, gap, index); 

    //make a cursor window 
    window.add(draggingComonent); 
    window.pack(); 

    updateWindowLocation(pt, parent); 
    window.setVisible(true); 
    } 

    private void updateWindowLocation(Point pt, JComponent parent) { 
    Point p = new Point(pt.x - dragOffset.x, pt.y - dragOffset.y); 
    SwingUtilities.convertPointToScreen(p, parent); 
    window.setLocation(p); 
    } 

    private static int getTargetIndex(Rectangle r, Point pt, int i) { 
    int ht2 = (int)(.5 + r.height * .5); 
    R1.setBounds(r.x, r.y,  r.width, ht2); 
    R2.setBounds(r.x, r.y + ht2, r.width, ht2); 
    if (R1.contains(pt)) { 
     prevRect = R1; 
     return i - 1 > 0 ? i : 0; 
    } else if (R2.contains(pt)) { 
     prevRect = R2; 
     return i; 
    } 
    return -1; 
    } 
    private static void swapComponentLocation(
     Container parent, Component remove, Component add, int idx) { 
    parent.remove(remove); 
    parent.add(add, idx); 
    parent.revalidate(); 
    parent.repaint(); 
    } 

    @Override public void mouseDragged(MouseEvent e) { 
    Point pt = e.getPoint(); 
    JComponent parent = (JComponent) e.getComponent(); 

    //MotionThreshold 
    double a = Math.pow(pt.x - startPt.x, 2); 
    double b = Math.pow(pt.y - startPt.y, 2); 
    if (draggingComonent == null && 
     Math.sqrt(a + b) > gestureMotionThreshold) { 
     startDragging(parent, pt); 
     return; 
    } 
    if (!window.isVisible() || draggingComonent == null) { 
     return; 
    } 

    //update the cursor window location 
    updateWindowLocation(pt, parent); 
    if (prevRect != null && prevRect.contains(pt)) { 
     return; 
    } 

    //change the dummy filler location 
    for (int i = 0; i < parent.getComponentCount(); i++) { 
     Component c = parent.getComponent(i); 
     Rectangle r = c.getBounds(); 
     if (Objects.equals(c, gap) && r.contains(pt)) { 
     return; 
     } 
     int tgt = getTargetIndex(r, pt, i); 
     if (tgt >= 0) { 
     swapComponentLocation(parent, gap, gap, tgt); 
     return; 
     } 
    } 
    parent.remove(gap); 
    parent.revalidate(); 
    } 

    @Override public void mouseReleased(MouseEvent e) { 
    startPt = null; 
    if (!window.isVisible() || draggingComonent == null) { 
     return; 
    } 
    Point pt = e.getPoint(); 
    JComponent parent = (JComponent) e.getComponent(); 

    //close the cursor window 
    Component cmp = draggingComonent; 
    draggingComonent = null; 
    prevRect = null; 
    startPt = null; 
    dragOffset = null; 
    window.setVisible(false); 

    //swap the dragging panel and the dummy filler 
    for (int i = 0; i < parent.getComponentCount(); i++) { 
     Component c = parent.getComponent(i); 
     if (Objects.equals(c, gap)) { 
     swapComponentLocation(parent, gap, cmp, i); 
     return; 
     } 
     int tgt = getTargetIndex(c.getBounds(), pt, i); 
     if (tgt >= 0) { 
     swapComponentLocation(parent, gap, cmp, tgt); 
     return; 
     } 
    } 
    if (parent.getParent().getBounds().contains(pt)) { 
     swapComponentLocation(parent, gap, cmp, parent.getComponentCount()); 
    } else { 
     swapComponentLocation(parent, gap, cmp, index); 
    } 
    } 
} 
+0

이것은 실제로 내가 원하는 것입니다. 정렬을 지원하지 않는다고해서 나중에 직접 추가 할 수는 없습니다.그러나 문제는 코드의 어느 부분이 무엇을하는지 이해할 수 없다는 것입니다. 특정 사물이 무엇 또는 왜 사용되었는지에 대한 설명이 거의 없습니다. 당신은 정교 할 수 있습니까? –

+0

'DragMouseAdapter'를 설명하기 위해 소스 코드에 몇 가지 의견을 추가하십시오. – aterai

관련 문제