2015-03-04 53 views
5

JButtons'u bir Nesneye Sürükle ve Bırak işleminin nasıl yapılacağını örnekler için internette araştırdım, ancak çalışamadım.JButton'dan JComponent'e sürükleyin ve Java'dan JComponent'e bırakın

Programım ne yapar, bir düğmeyi tıkladığımda, nesne bir alanı güncelleştirdi (selectedobject.setField() ile). Bunu tıklayarak değil, JButton'u sürükleyerek yapabilmek istiyorum.

Bunu nasıl yapabilirim? bunu buldum ve benim kodunda koymak için çalıştı:

btn.setTransferHandler(new ImageHandler()); 
btn.addMouseListener(new MouseAdapter() { 
public void mousePressed(MouseEvent e) { 
     JComponent c = (JComponent)e.getSource(); 
     TransferHandler handler = c.getTransferHandler(); 
     handler.exportAsDrag(c, e, TransferHandler.COPY); 
      }   
}); 

ben here gelen ImageHandler dersi aldım.

+0

sizi ne "yeni bir değer alır" demek? Düğmenin "değerini" başka bir şeye sürüklemek ister misiniz? – MadProgrammer

+0

Düğme seçilen nesneye bir animasyon ekler. Sürükle ve bırak ile aynı animasyonu rastgele bir nesneye ekleyebilmek istiyorum. – user3450862

cevap

9

Drag'n'drop eğlenceli bir çıtır çıtır, çıtır havuçlar ... bir "çekirdek" API ve daha yeni "aktarma" API'sı olduğu gerçeğinden değil,

kafasını karıştırmak gerçekten çok kolay değil

Aşağıdaki örnek, "aktarma" API'sini kullanır ve String değerini bir düğmeden JLabel'a aktarır.

Drag Numbers

import java.awt.Color; 
import java.awt.Component; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.GridLayout; 
import java.awt.datatransfer.DataFlavor; 
import java.awt.datatransfer.StringSelection; 
import java.awt.datatransfer.Transferable; 
import java.awt.dnd.DnDConstants; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.TransferHandler; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.border.CompoundBorder; 
import javax.swing.border.EmptyBorder; 
import javax.swing.border.LineBorder; 

public class Test { 

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

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

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

    public class TestPane extends JPanel { 

     public TestPane() { 
      setLayout(new GridLayout(1, 2)); 
      add(createLeftPanel()); 
      add(createRightPanel()); 

     } 

     protected JPanel createLeftPanel() { 
      JPanel panel = new JPanel(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridwidth = GridBagConstraints.REMAINDER; 
      gbc.fill = GridBagConstraints.HORIZONTAL; 
      gbc.weightx = 1; 
      for (int index = 0; index < 10; index++) { 
       JButton btn = new JButton(Integer.toString(index + 1)); 
       panel.add(btn, gbc); 
       btn.setTransferHandler(new ValueExportTransferHandler(Integer.toString(index + 1))); 

       btn.addMouseMotionListener(new MouseAdapter() { 
        @Override 
        public void mouseDragged(MouseEvent e) { 
         JButton button = (JButton) e.getSource(); 
         TransferHandler handle = button.getTransferHandler(); 
         handle.exportAsDrag(button, e, TransferHandler.COPY); 
        } 
       }); 
      } 
      return panel; 
     } 

     protected JPanel createRightPanel() { 
      JPanel panel = new JPanel(new GridBagLayout()); 
      JLabel label = new JLabel("Drop in"); 
      label.setBorder(new CompoundBorder(new LineBorder(Color.DARK_GRAY), new EmptyBorder(20, 20, 20, 20))); 
      label.setTransferHandler(new ValueImportTransferHandler()); 
      panel.add(label); 
      return panel; 
     } 

    } 

    public static class ValueExportTransferHandler extends TransferHandler { 

     public static final DataFlavor SUPPORTED_DATE_FLAVOR = DataFlavor.stringFlavor; 
     private String value; 

     public ValueExportTransferHandler(String value) { 
      this.value = value; 
     } 

     public String getValue() { 
      return value; 
     } 

     @Override 
     public int getSourceActions(JComponent c) { 
      return DnDConstants.ACTION_COPY_OR_MOVE; 
     } 

     @Override 
     protected Transferable createTransferable(JComponent c) { 
      Transferable t = new StringSelection(getValue()); 
      return t; 
     } 

     @Override 
     protected void exportDone(JComponent source, Transferable data, int action) { 
      super.exportDone(source, data, action); 
      // Decide what to do after the drop has been accepted 
     } 

    } 

    public static class ValueImportTransferHandler extends TransferHandler { 

     public static final DataFlavor SUPPORTED_DATE_FLAVOR = DataFlavor.stringFlavor; 

     public ValueImportTransferHandler() { 
     } 

     @Override 
     public boolean canImport(TransferHandler.TransferSupport support) { 
      return support.isDataFlavorSupported(SUPPORTED_DATE_FLAVOR); 
     } 

     @Override 
     public boolean importData(TransferHandler.TransferSupport support) { 
      boolean accept = false; 
      if (canImport(support)) { 
       try { 
        Transferable t = support.getTransferable(); 
        Object value = t.getTransferData(SUPPORTED_DATE_FLAVOR); 
        if (value instanceof String) { 
         Component component = support.getComponent(); 
         if (component instanceof JLabel) { 
          ((JLabel) component).setText(value.toString()); 
          accept = true; 
         } 
        } 
       } catch (Exception exp) { 
        exp.printStackTrace(); 
       } 
      } 
      return accept; 
     } 
    } 
} 

ben "drop" sürümü, bir "sürükle" için izin TransferHandler s ayırmak ve benim çıkış yolu gittin. Bunu yapmak için "sahip" değilsiniz ve her iki işlemi gerçekleştirmek için tek bir TransferHandler "kullanabilir", bu size kalmış.

Farklı değerleri kabul ve accordingingly SUPPORTED_DATE_FLAVOR değiştirme ValueExportTransferHandler değiştirmek zorunda kalacak, ancak bu da başka bir örnek olarak Drag and Drop custom object from JList into JLabel bir göz olabilir

temelleri vardır ...

+0

Orada bir şeyler var. Yani, "exportAsDrag" her bir sürükleme olayı için * çağrılmamalıdır *, değil mi? Pratikte çalışsa bile. EDIT: Sadece koştum. Çalışır ve mouseDragged yöntemi, bir sebepten dolayı, yalnızca bir kez * yürütüldüğünde, hepsi iyi görünüyor. –

+0

@DreamspacePresident Neden olmasın? 'exportAsDrag' 'mouseDragged' üzerinde çağrıldı, eğer değilse, o zaman ne zaman çağrılmalıdır? ps- Ben düşünüyorum düşünüyorum 'mouseMoved';) – MadProgrammer

+0

exportAsDrag docs Çünkü "Swing sürükle desteğinin başlatılmasını neden olur." ve "Bu çağrının iadesinde aktarım tamamlanmayacaktır (yani çağrı, düşüşü beklemeyi engellemez)." Bana göre, bu şeyin D & D başına * bir kez * çağrılacağını açıkça ima eder. Ama diğer yorumumu düzenlediğime bakın, hepsi iyi görünüyor. –