2013-06-28 73 views
0

我已经创建了一个框架,然后嵌入其中。我在一个面板中放置了一个图像,现在我需要将该图像拖到另一个面板。我怎么能这样做。请逐步解释为初学者。如何将图像从一个面板拖动到另一个面板

+3

* “请解释一步一步” *请参阅这些任务的教程。 SO是一个问答网站。 –

+1

同时请避免在**(** I **)的时候写** **。 – Maroun

+0

请参阅此链接。 [是否有可能具有“可动” /“拖动”像Jbutton将,在一个JFrame JTextField的组件?] [1] [1]:http://stackoverflow.com/questions/5052141/is-它可能有可移动的可拖动组件像按钮jtextfiel 希望这对你有帮助。 –

回答

7

连结例如使用纯java,DragGestureListenerDropTargetAdapterTransferHandler为DnD的支持在一个面板上的图像的另一:任何形状被点击并拖动

之前:

enter image description here

绿色形状被选中并拖动到上面的空面板上后:

enter image description here

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.Point; 
import java.awt.datatransfer.DataFlavor; 
import java.awt.datatransfer.Transferable; 
import java.awt.datatransfer.UnsupportedFlavorException; 
import java.awt.dnd.DnDConstants; 
import java.awt.dnd.DragGestureEvent; 
import java.awt.dnd.DragGestureListener; 
import java.awt.dnd.DragSource; 
import java.awt.dnd.DropTarget; 
import java.awt.dnd.DropTargetAdapter; 
import java.awt.dnd.DropTargetDropEvent; 
import java.io.IOException; 
import java.net.URL; 
import javax.swing.Icon; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.TransferHandler; 
import javax.swing.TransferHandler.TransferSupport; 
import javax.swing.border.TitledBorder; 

public class Test { 

    public static void main(String[] args) { 
     createAndShowJFrame(); 
    } 

    public static void createAndShowJFrame() { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 

       JFrame frame = createJFrame(); 
       frame.setVisible(true); 

      } 
     }); 
    } 

    private static JFrame createJFrame() { 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     frame.setTitle("Test"); 

     JPanel panel = createEmptyJPanel(); 
     new MyDropTargetListener(panel);//this must be done or we wont be able to drop any image onto the empty panel 

     frame.add(panel, BorderLayout.CENTER); 

     try { 
      frame.add(createJLabelPanel(), BorderLayout.SOUTH); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 

     frame.pack(); 

     return frame; 
    } 

    private static JPanel createEmptyJPanel() { 
     final JPanel p = new JPanel() { 
      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(300, 300); 
      } 
     }; 
     p.setBorder(new TitledBorder("Drag Image onto this panel")); 

     TransferHandler dnd = new TransferHandler() { 
      @Override 
      public boolean canImport(TransferSupport support) { 
       if (!support.isDrop()) { 
        return false; 
       } 
       //only Strings 
       if (!support.isDataFlavorSupported(DataFlavor.imageFlavor)) { 
        return false; 
       } 
       return true; 
      } 

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

       Transferable tansferable = support.getTransferable(); 
       Icon ico; 
       try { 
        ico = (Icon) tansferable.getTransferData(DataFlavor.imageFlavor); 
       } catch (Exception e) { 
        e.printStackTrace(); 
        return false; 
       } 
       p.add(new JLabel(ico)); 
       return true; 
      } 
     }; 

     p.setTransferHandler(dnd); 

     return p; 
    } 

    private static JPanel createJLabelPanel() throws Exception { 
     JPanel panel = new JPanel(); 
     panel.setBorder(new TitledBorder("Drag Image from here to Panel above")); 

     JLabel label1 = new JLabel(new ImageIcon(new URL("http://i.stack.imgur.com/gJmeJ.png"))); 
     JLabel label2 = new JLabel(new ImageIcon(new URL("http://i.stack.imgur.com/8BGfi.png"))); 
     JLabel label3 = new JLabel(new ImageIcon(new URL("http://i.stack.imgur.com/1lgtq.png"))); 

     MyDragGestureListener dlistener = new MyDragGestureListener(); 
     DragSource ds1 = new DragSource(); 
     ds1.createDefaultDragGestureRecognizer(label1, DnDConstants.ACTION_COPY, dlistener); 

     DragSource ds2 = new DragSource(); 
     ds2.createDefaultDragGestureRecognizer(label2, DnDConstants.ACTION_COPY, dlistener); 

     DragSource ds3 = new DragSource(); 
     ds3.createDefaultDragGestureRecognizer(label3, DnDConstants.ACTION_COPY, dlistener); 

     panel.add(label1); 
     panel.add(label2); 
     panel.add(label3); 
     return panel; 
    } 
} 

class MyDropTargetListener extends DropTargetAdapter { 

    private DropTarget dropTarget; 
    private JPanel p; 

    public MyDropTargetListener(JPanel panel) { 
     p = panel; 
     dropTarget = new DropTarget(panel, DnDConstants.ACTION_COPY, this, true, null); 

    } 

    @Override 
    public void drop(DropTargetDropEvent event) { 
     try { 
      DropTarget test = (DropTarget) event.getSource(); 
      Component ca = (Component) test.getComponent(); 
      Point dropPoint = ca.getMousePosition(); 
      Transferable tr = event.getTransferable(); 

      if (event.isDataFlavorSupported(DataFlavor.imageFlavor)) { 
       Icon ico = (Icon) tr.getTransferData(DataFlavor.imageFlavor); 

       if (ico != null) { 

        p.add(new JLabel(ico)); 
        p.revalidate(); 
        p.repaint(); 
        event.dropComplete(true); 
       } 
      } else { 
       event.rejectDrop(); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
      event.rejectDrop(); 
     } 
    } 
} 

class MyDragGestureListener implements DragGestureListener { 

    @Override 
    public void dragGestureRecognized(DragGestureEvent event) { 
     JLabel label = (JLabel) event.getComponent(); 
     final Icon ico = label.getIcon(); 


     Transferable transferable = new Transferable() { 
      @Override 
      public DataFlavor[] getTransferDataFlavors() { 
       return new DataFlavor[]{DataFlavor.imageFlavor}; 
      } 

      @Override 
      public boolean isDataFlavorSupported(DataFlavor flavor) { 
       if (!isDataFlavorSupported(flavor)) { 
        return false; 
       } 
       return true; 
      } 

      @Override 
      public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 
       return ico; 
      } 
     }; 
     event.startDrag(null, transferable); 
    } 
} 
+0

另请参阅[this](http://stackoverflow.com/questions/14273923/how-can-i-set- the-priority-mouse-listener/14276466#14276466)回答了对Swing组件的支持的拖放问题。(接近我的答案的结尾是屏幕截图的代码) –

+1

+1和[this](http://stackoverflow.com/questions/16478413/move-component-after-drag-and-drop);) – MadProgrammer

+1

仍然是一个 - ) – kleopatra

1
  1. 可能有许多方法来实现你想要的。您可以使用玻璃窗格或JXLayer,或者您可以停止将两个面板视为单独的元素,更像是将它们视为进入大型虚拟空间的窗口。
  2. 本示例基本上将父组件视为两个图像窗格为窗口的“虚拟空间”。
  3. 它们都共享相同的图像和图像位置的细节。他们,个人,将图像位置(在虚拟坐标中)转换为局部坐标,并绘制出图像上的图像...
  4. 鼠标控制由父级控制。这大大简化了过程,因为它可以同时通知面板同时

而且代码...

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.GridLayout; 
import java.awt.Image; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.border.EmptyBorder; 
import javax.swing.border.LineBorder; 

public class CrossImage { 

    public static void main(String[] args) { 
     new CrossImage(); 
    } 

    public CrossImage() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private BufferedImage img; 
     private ImagePane left; 
     private ImagePane right; 
     private Point imagePoint; 

     public TestPane() { 
      setBorder(new EmptyBorder(10, 10, 10, 10)); 
      setLayout(new GridLayout(0, 2, 10, 10)); 
      left = new ImagePane(); 
      right = new ImagePane(); 
      imagePoint = new Point(10, 10); 
      left.setImageLocation(imagePoint); 
      right.setImageLocation(imagePoint); 
      try { 
       img = ImageIO.read(new File("Background.jpg")); 
       left.setImage(img); 
       right.setImage(img); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
      add(left); 
      add(right); 

      MouseAdapter mouseHandler = new MouseAdapter() { 
       private Point delta; 

       @Override 
       public void mousePressed(MouseEvent e) { 
        Point origin = e.getPoint(); 
        Rectangle bounds = new Rectangle(imagePoint, new Dimension(img.getWidth(), img.getHeight())); 
        if (bounds.contains(origin)) { 
         delta = new Point(origin.x - imagePoint.x, origin.y - imagePoint.y); 
        } 
       } 

       @Override 
       public void mouseDragged(MouseEvent e) { 
        if (delta != null) { 
         imagePoint = e.getPoint(); 
         imagePoint.translate(-delta.x, -delta.y); 
         left.setImageLocation(imagePoint); 
         right.setImageLocation(imagePoint); 
        } 
       } 

       @Override 
       public void mouseReleased(MouseEvent e) { 
        delta = null; 
       } 
      }; 

      addMouseListener(mouseHandler); 
      addMouseMotionListener(mouseHandler); 
     } 
    } 

    public class ImagePane extends JPanel { 

     private Image image; 
     private Point imageLocation; 

     public ImagePane() { 
      setBorder(new LineBorder(Color.DARK_GRAY)); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(this), image.getHeight(this)); 
     } 

     public void setImage(Image image) { 
      this.image = image; 
      repaint(); 
     } 

     public void setImageLocation(Point imageLocation) { 
      this.imageLocation = imageLocation; 
      repaint(); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (image != null && imageLocation != null) { 
       Point p = SwingUtilities.convertPoint(getParent(), imageLocation, this); 
       g.drawImage(image, p.x, p.y, this); 
      } 
     } 
    } 
} 
+0

星期五,评论日:-) setImageLocation中的坐标应该在ImagePanel的坐标中:它不知道哪个客户端设置了它,假设它是父类是一个通配符猜测。反过来,谁设置的位置,确实知道它起源的地方,并可以安全地将它们转换为目标坐标 – kleopatra

相关问题