2015-03-04 37 views
5

Szukałem w Internecie przykładów, jak przeciągać i upuszczać JButtons do obiektu, ale nie mogłem go uruchomić.Przeciągnij i upuść z JButton do JComponent w Javie

To, co robi mój program, polega na tym, że po kliknięciu przycisku obiekt zaktualizował pole (za pomocą selectedobject.setField()). Chcę to zrobić nie klikając, ale przeciągając przycisk J.

Jak mogę to zrobić? znalazłem to, a ja starałem się umieścić w kodzie:

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); 
      }   
}); 

wziąłem klasę ImageHandler z here.

+0

Co prawda znaczy "dostaje nową wartość"? Czy chcesz przeciągnąć "wartość" przycisku na coś innego? – MadProgrammer

+0

Przycisk dodaje animację do wybranego obiektu. Chcę móc dodać tę samą animację do losowego obiektu poprzez przeciąganie i upuszczanie. – user3450862

Odpowiedz

9

Drag'n'drop to zabawna torba z chrupiącą, munchy marchewką ... nie pomogła temu fakt, że istnieje "core" API i nowszy "transfer" API, więc bardzo łatwo jest się pomylić

Poniższy przykład wykorzystuje interfejs API "transfer" i zasadniczo przekazuje wartość String z przycisku na JLabel.

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; 
     } 
    } 
} 

Poszedłem z moją drogę do oddzielenia TransferHandler s pozwalające na "drag" i "upuścić" wersję. Nie "musisz" tego robić i "możesz" użyć pojedynczego TransferHandler do wykonania obu operacji, to zależy od Ciebie.

Będziesz musiał zmodyfikować ValueExportTransferHandler przyjmować różne wartości i modyfikować SUPPORTED_DATE_FLAVOR accordingingly, ale te są podstawy

Można też rzucić okiem na Drag and Drop custom object from JList into JLabel Jako inny przykład ...

+0

Coś tam jest nie tak. Mam na myśli, że "exportAsDrag" nie powinien być wywoływany * dla każdego pojedynczego zdarzenia przeciągania *, prawda? Nawet jeśli może działać w praktyce. EDIT: Po prostu go uruchomiłem. Działa, a metoda mouseDragged jest z jakiegoś powodu wykonywana tylko raz *, więc wszystko wydaje się dobrze. –

+0

@DreamspacePresident Dlaczego nie? Wywołanie 'exportAsDrag' zostało wywołane w' mouseDragged', jeśli nie, to kiedy powinno być wywołane? ps- Myślę, że myślisz o 'mouseMoved';) – MadProgrammer

+0

Ponieważ dokumenty exportAsDrag mówią" Powoduje zainicjowanie obsługi przeciągania Swing. " oraz "Przeniesienie nie musi być zakończone po powrocie tego połączenia (tzn. połączenie nie blokuje czekania na zrzut)." co, dla mnie, wyraźnie oznacza, że ​​to coś ma się nazywać * raz * na D & D. Ale zobacz moją edycję mojego drugiego komentarza, wszystko wydaje się dobrze. –