2012-07-12 59 views
6

我使用的TransferHandler從一個JPanel數據傳遞給一個JTextArea爲一個JLabel(在左側面板中單擊某個創建JLabel以拖動)拖動一個JLabel用的TransferHandler(拖放)

的數據的傳輸工作正常,但我也想「展示」JLabel,因爲它被拖動鼠標指針。

如果您註釋掉

dropLabel.setTransferHandler(new TransferHandler("text")); 

dropLabel.getTransferHandler().exportAsDrag(dropLabel, e, 
      TransferHandler.COPY); 

,你會看到我是多麼希望它看起來。 (但當然這些數據不會被傳輸)。

我怎樣才能讓轉移到工作和JLabel遵循鼠標光標?

下面是代碼:

import java.awt.*; 
import java.awt.datatransfer.Transferable; 
import java.awt.event.*; 

import javax.swing.*; 
import javax.swing.border.Border; 

public class DragTest extends JFrame implements MouseMotionListener, 
     MouseListener { 

    private JPanel leftPanel = new JPanel(null); 
    private JPanel rightPanel = new JPanel(null); 
    private JLabel dragLabel = new JLabel("drop"); 
    private final JWindow window = new JWindow(); 
    JLabel dropLabel; 

    public DragTest() { 
     this.setLayout(new GridLayout(1, 2)); 

     leftPanel.setBorder(BorderFactory.createLineBorder(Color.black)); 
     rightPanel.setBorder(BorderFactory.createLineBorder(Color.black)); 
     this.add(leftPanel); 
     this.add(rightPanel); 
     leftPanel.addMouseListener(this); 
     leftPanel.addMouseMotionListener(this); 

     JTextArea area = new JTextArea(); 

     rightPanel.setLayout(new GridLayout(1, 1)); 
     rightPanel.add(area); 

     dragLabel.setFont(new Font("Serif", Font.BOLD, 48)); 
    } 

    @Override 
    public void mousePressed(MouseEvent e) { 

     dropLabel = new JLabel("drop"); 

     Dimension labelSize = dropLabel.getPreferredSize(); 
     dropLabel.setSize(labelSize); 
     int x = e.getX() - labelSize.width/2; 
     int y = e.getY() - labelSize.height/2; 
     dropLabel.setLocation(x, y); 
     leftPanel.add(dropLabel); 

     dropLabel.setTransferHandler(new TransferHandler("text")); 

     dropLabel.getTransferHandler().exportAsDrag(dropLabel, e, 
       TransferHandler.COPY); 

     repaint(); 

    } 

    @Override 
    public void mouseDragged(MouseEvent me) { 
     dragLabel = new JLabel("drop"); 
     dragLabel.setFont(new Font("Serif", Font.BOLD, 48)); 
     int x = me.getPoint().x; 
     int y = me.getPoint().y; 
     window.add(dragLabel); 
     window.pack(); 
     Point pt = new Point(x, y); 
     Component c = (Component) me.getSource(); 
     SwingUtilities.convertPointToScreen(pt, c); 
     window.setLocation(pt); 
     window.setVisible(true); 
     repaint(); 
    } 

    @Override 
    public void mouseMoved(MouseEvent e) { 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 

    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 

//  leftPanel.remove(dropLabel); 

     window.remove(dragLabel); 
     window.setVisible(false); 

     repaint(); 
    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 

    } 

    @Override 
    public void mouseExited(MouseEvent e) { 

    } 

    public static void main(String[] args) { 

     DragTest frame = new DragTest(); 
     frame.setVisible(true); 
     frame.setSize(600, 400); 
     frame.setResizable(false); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 
} 

回答

9

又如:

enter image description here

編輯:修正閃爍光標

import java.awt.*; 
import java.awt.datatransfer.*; 
import java.awt.dnd.*; 
import java.awt.event.*; 
import java.io.*; 
import java.util.*; 
import javax.activation.*; 
import javax.swing.*; 
import javax.swing.text.*; 

public class DragTest3 { 
    public JComponent makeUI() { 
    DragPanel p1 = new DragPanel(); 
    p1.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 
    p1.add(new JLabel(UIManager.getIcon("OptionPane.warningIcon"))); 
    p1.add(new JLabel(UIManager.getIcon("OptionPane.errorIcon"))); 
    p1.add(new JLabel("Label1")); 
    p1.add(new JLabel("Label2")); 
    MouseListener handler = new Handler(); 
    p1.addMouseListener(handler); 
    LabelTransferHandler th = new LabelTransferHandler(); 
    p1.setTransferHandler(th); 
    JPanel p = new JPanel(new GridLayout(1,2)); 
    p.add(p1); 

    DragPanel p2 = new DragPanel(); 
    p2.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 
    p2.addMouseListener(handler); 
    p2.setTransferHandler(th); 
    p.add(p2); 

    JPanel panel = new JPanel(new GridLayout(2,1)); 
    panel.add(p); 
    panel.add(new JScrollPane(new JTextArea())); 
    return panel; 
    } 
    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 DragTest3().makeUI()); 
    f.setSize(320, 240); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
    } 
} 
class DragPanel extends JPanel { 
    public DragPanel() { 
    super(); 
    } 
    public JLabel draggingLabel; 
} 
class Handler extends MouseAdapter { 
    @Override public void mousePressed(MouseEvent e) { 
    DragPanel p = (DragPanel)e.getSource(); 
    Component c = SwingUtilities.getDeepestComponentAt(p, e.getX(), e.getY()); 
    if(c!=null && c instanceof JLabel) { 
     p.draggingLabel = (JLabel)c; 
     p.getTransferHandler().exportAsDrag(p, e, TransferHandler.MOVE); 
    } 
    } 
} 
class LabelTransferHandler extends TransferHandler { 
    private final DataFlavor localObjectFlavor; 
    private final JLabel label = new JLabel() { 
    @Override public boolean contains(int x, int y) { 
     return false; 
    } 
    }; 
    private final JWindow window = new JWindow(); 
    public LabelTransferHandler() { 
    System.out.println("LabelTransferHandler"); 
    localObjectFlavor = new ActivationDataFlavor(
     DragPanel.class, DataFlavor.javaJVMLocalObjectMimeType, "JLabel"); 
    window.add(label); 
    window.setAlwaysOnTop(true); 
    window.setBackground(new Color(0,true)); 
    DragSource.getDefaultDragSource().addDragSourceMotionListener(
    new DragSourceMotionListener() { 
     @Override public void dragMouseMoved(DragSourceDragEvent dsde) { 
     Point pt = dsde.getLocation(); 
     pt.translate(5, 5); // offset 
     window.setLocation(pt); 
     } 
    }); 
    } 
    @Override protected Transferable createTransferable(JComponent c) { 
    System.out.println("createTransferable"); 
    DragPanel p = (DragPanel)c; 
    JLabel l = p.draggingLabel; 
    String text = l.getText(); 
    //TEST 
    //if(text==null) { 
    // text = l.getIcon().toString(); 
    //} 
    //return new StringSelection(text+"\n"); 
    final DataHandler dh = new DataHandler(c, localObjectFlavor.getMimeType()); 
    if(text==null) return dh; 
    final StringSelection ss = new StringSelection(text+"\n"); 
    return new Transferable() { 
     @Override public DataFlavor[] getTransferDataFlavors() { 
     ArrayList<DataFlavor> list = new ArrayList<>(); 
     for(DataFlavor f:ss.getTransferDataFlavors()) { 
      list.add(f); 
     } 
     for(DataFlavor f:dh.getTransferDataFlavors()) { 
      list.add(f); 
     } 
     return list.toArray(dh.getTransferDataFlavors()); 
     } 
     public boolean isDataFlavorSupported(DataFlavor flavor) { 
     for (DataFlavor f: getTransferDataFlavors()) { 
      if (flavor.equals(f)) { 
      return true; 
      } 
     } 
     return false; 
     } 
     public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 
     if(flavor.equals(localObjectFlavor)) { 
      return dh.getTransferData(flavor); 
     } else { 
      return ss.getTransferData(flavor); 
     } 
     } 
    }; 
    } 
    @Override public boolean canImport(TransferSupport support) { 
    if(!support.isDrop()) { 
     return false; 
    } 
    return true; 
    } 
    @Override public int getSourceActions(JComponent c) { 
    System.out.println("getSourceActions"); 
    DragPanel p = (DragPanel)c; 
    label.setIcon(p.draggingLabel.getIcon()); 
    label.setText(p.draggingLabel.getText()); 
    window.pack(); 
    Point pt = p.draggingLabel.getLocation(); 
    SwingUtilities.convertPointToScreen(pt, p); 
    window.setLocation(pt); 
    window.setVisible(true); 
    return MOVE; 
    } 
    @Override public boolean importData(TransferSupport support) { 
    System.out.println("importData"); 
    if(!canImport(support)) return false; 
    DragPanel target = (DragPanel)support.getComponent(); 
    try { 
     DragPanel src = (DragPanel)support.getTransferable().getTransferData(localObjectFlavor); 
     JLabel l = new JLabel(); 
     l.setIcon(src.draggingLabel.getIcon()); 
     l.setText(src.draggingLabel.getText()); 
     target.add(l); 
     target.revalidate(); 
     return true; 
    } catch(UnsupportedFlavorException ufe) { 
     ufe.printStackTrace(); 
    } catch(java.io.IOException ioe) { 
     ioe.printStackTrace(); 
    } 
    return false; 
    } 
    @Override protected void exportDone(JComponent c, Transferable data, int action) { 
    System.out.println("exportDone"); 
    DragPanel src = (DragPanel)c; 
    if(action == TransferHandler.MOVE) { 
     src.remove(src.draggingLabel); 
     src.revalidate(); 
     src.repaint(); 
    } 
    src.draggingLabel = null; 
    window.setVisible(false); 
    } 
} 
+0

這是作弊;) – MadProgrammer 2012-07-13 07:50:41

+0

@MadProgrammer我也這麼認爲:) – aterai 2012-07-30 05:38:29

+0

啊是的,但它是一個很好的作弊;) – MadProgrammer 2012-07-30 05:43:24

3

更新:不幸的是,您使用的是TransferHandler

我最後一次使用TransferHandler API(回到6.10/6.12)時,代碼中存在一個忽略傳輸圖像的錯誤。它實際上將其設置爲null。這可能在後來的更新中得到修復,但我最近沒有檢查過。

經過大量挖掘,我發現TransferHandler的默認實現忽略了「getVisualRepresentation(Transferable t)」方法。不是。

我做了一些挖掘,並且該類使用一堆「私有」內部類來處理DnD進程的工作,使得它幾乎不可能在不必重寫整個事物的情況下簡單地更改實現。

基本上,DragSource允許你傳遞一個它可以使用的圖像(至於這是否成立是另一個問題),但它隱藏在一個私有的DragHandler類中。感謝Sun.

+0

,並看看一個試圖重寫傳輸處理程序,但有這麼多包的私有代碼,只是不是一個簡單的任務,試圖 – MadProgrammer 2012-07-13 00:17:55

+0

我嘗試了「手冊」的DnD過程和「的startDrag」法不使用我在Windows 7下提供的拖動圖像(我認爲Mac可以做到這一點)...你可能想看看http://rabbit-hole.blogspot.com.au/2006/05/my-drag-image-是更好的yours.html更多的信息 – MadProgrammer 2012-07-13 00:23:17

-2

我用這個碼並作了一些修改。根據TOS,我將其重新發布到SO。

import java.awt.Color; 
import java.awt.Point; 
import java.awt.datatransfer.DataFlavor; 
import java.awt.datatransfer.StringSelection; 
import java.awt.datatransfer.Transferable; 
import java.awt.datatransfer.UnsupportedFlavorException; 
import java.awt.dnd.DragSource; 
import java.awt.dnd.DragSourceDragEvent; 
import java.awt.dnd.DragSourceMotionListener; 
import java.io.IOException; 
import java.util.ArrayList; 
import javax.activation.ActivationDataFlavor; 
import javax.activation.DataHandler; 
import javax.swing.*; 


@SuppressWarnings("serial") 
public class LabelTransferHandler extends TransferHandler { 

    private final DataFlavor localObjectFlavor; 
    private final DeviceAssignments root; 

    private final JLabel label = new JLabel() { 
     @Override public boolean contains(int x, int y) { 
      return false; 
     } 
    }; 

    private final JWindow window = new JWindow(); 

    public LabelTransferHandler(DeviceAssignments root) { 
     this.root = root; 
     localObjectFlavor = new ActivationDataFlavor(
      LabelDragScrollPane.class, DataFlavor.javaJVMLocalObjectMimeType, "JLabel"); 
     window.add(label); 
     window.setAlwaysOnTop(true); 
     window.setBackground(new Color(0,true)); 
     DragSource.getDefaultDragSource().addDragSourceMotionListener(
      new DragSourceMotionListener() { 
       @Override public void dragMouseMoved(DragSourceDragEvent dsde) { 
        Point pt = dsde.getLocation(); 
        pt.translate(5, 5); // offset 
        window.setLocation(pt); 
       } 
      } 
     ); 
    } 

    @Override protected Transferable createTransferable(JComponent c) { 
     LabelDragScrollPane p = (LabelDragScrollPane)c; 
     MacLabel l = p.draggingLabel; 
     String text = l.getMac(); 
     final DataHandler dh = new DataHandler(c, localObjectFlavor.getMimeType()); 
     if(text==null) return dh; 
     final StringSelection ss = new StringSelection(text+"\n"); 
     return new Transferable() { 
      @Override public DataFlavor[] getTransferDataFlavors() { 
      ArrayList<DataFlavor> list = new ArrayList<DataFlavor>(); 
      for(DataFlavor f:ss.getTransferDataFlavors()) { 
       list.add(f); 
      } 
      for(DataFlavor f:dh.getTransferDataFlavors()) { 
       list.add(f); 
      } 
      return list.toArray(dh.getTransferDataFlavors()); 
      } 
      public boolean isDataFlavorSupported(DataFlavor flavor) { 
       for (DataFlavor f: getTransferDataFlavors()) { 
        if (flavor.equals(f)) { 
         return true; 
        } 
       } 
       return false; 
      } 
      public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 
       if(flavor.equals(localObjectFlavor)) { 
        return dh.getTransferData(flavor); 
       } else { 
        return ss.getTransferData(flavor); 
       } 
      } 
     }; 
    } 

    @Override public boolean canImport(TransferSupport support) { 
     if(!support.isDrop()) { 
      return false; 
     } 
     return true; 
    } 

    @Override public int getSourceActions(JComponent c) { 
     LabelDragScrollPane p = (LabelDragScrollPane)c; 
     label.setBorder(p.draggingLabel.getBorder()); 
     label.setText(p.draggingLabel.getMac()); 
     label.setPreferredSize(p.draggingLabel.getPreferredSize()); 

     window.pack(); 
     Point pt = p.draggingLabel.getLocation(); 
     SwingUtilities.convertPointToScreen(pt, p); 
     window.setLocation(pt); 
     window.setVisible(true); 
     return MOVE; 
    } 

    @Override public boolean importData(TransferSupport support) { 
     if(!canImport(support)) return false; 
     JButton target = (JButton)support.getComponent(); 
     try { 
      LabelDragScrollPane src = (LabelDragScrollPane)support.getTransferable().getTransferData(localObjectFlavor); 
      target.setText(src.draggingLabel.getMac()); 
      return true; 
     } catch(UnsupportedFlavorException ufe) { 
      ufe.printStackTrace(); 
     } catch(java.io.IOException ioe) { 
      ioe.printStackTrace(); 
     } 
     return false; 
    } 
    @Override protected void exportDone(JComponent c, Transferable data, int action) { 
     LabelDragScrollPane src = (LabelDragScrollPane)c; 
     if(action == TransferHandler.MOVE) { 
      root.updateNodeIdPanel(); 
     } 
     src.draggingLabel = null; 
     window.setVisible(false); 
    } 
} 
+0

這似乎不是問題的新答案,可能會被刪除。如果您重複使用代碼並關注CC許可,那麼您需要向原作者詢問有關其他許可的信息,或者在您使用它的地方發佈出處_,而不是在這裏。 – 2014-09-17 00:00:42

+0

做你想做的。我遵循網站的使用條款。我的良知很乾淨。 – 2014-09-17 14:45:13