2017-03-02 25 views
0

JTableにはいくつかの行があります。私はマウス(ドラッグアンドドロップ)で行を移動するときに、マウスが移動すると(JTableの列を動かすなど)、その行をマウスやテーブルの行とともに並べ替えて並べ替えることが必要な場合があります。 このjsfiddleは私が欲しいものですが、私はJavaスイング(または下のGIF画像)でそれをしなければなりません。例はhereですが、理解できません。JTableでマウスで行を移動

enter image description here

私のTransferHandler:

public class TableRowTransferHandler extends TransferHandler { 

    private final DataFlavor localObjectFlavor = new ActivationDataFlavor(Integer.class, "application/x-java-Integer;class=java.lang.Integer", "Integer Row Index"); 
    private JTable table = null; 

    private static final Logger logger = Logger.getLogger(TableRowTransferHandler.class.getName()); 

    public TableRowTransferHandler(JTable table) { 
     this.table = table; 
    } 

    @Override 
    protected Transferable createTransferable(JComponent c) { 
     assert (c == table); 
     return new DataHandler(table.getSelectedRow(), localObjectFlavor.getMimeType()); 
    } 

    @Override 
    public boolean canImport(TransferHandler.TransferSupport info) { 
     boolean b = info.getComponent() == table && info.isDrop() && info.isDataFlavorSupported(localObjectFlavor); 
     table.setCursor(b ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop); 
     return b; 
    } 

    @Override 
    public int getSourceActions(JComponent c) { 
     return TransferHandler.COPY_OR_MOVE; 
    } 

    @Override 
    public boolean importData(TransferHandler.TransferSupport info) { 
     JTable target = (JTable) info.getComponent(); 
     JTable.DropLocation dl = (JTable.DropLocation) info.getDropLocation(); 
     int index = dl.getRow(); 
     int max = table.getModel().getRowCount(); 
     if (index < 0 || index > max) { 
      index = max; 
     } 
     target.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 
     try { 
      Integer rowFrom = (Integer) info.getTransferable().getTransferData(localObjectFlavor); 
      if (rowFrom != -1 && rowFrom != index) { 
       ((Reorderable) table.getModel()).reorder(rowFrom, index); 
       if (index > rowFrom) { 
        index--; 
       } 
       target.getSelectionModel().addSelectionInterval(index, index); 
       return true; 
      } 
     } catch (UnsupportedFlavorException | IOException e) { 
      e.printStackTrace(); 
      logger.log(Level.SEVERE, null, e); 
     } 
     return false; 
    } 

    @Override 
    protected void exportDone(JComponent c, Transferable t, int act) { 
     if ((act == TransferHandler.MOVE) || (act == TransferHandler.NONE)) { 
      table.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 
     } 
    } 
} 

私はJTableのに使う簡単な設定である:

childrenTable.setDragEnabled(true); 
    childrenTable.setDropMode(DropMode.INSERT); 
    childrenTable.setTransferHandler(new TableRowTransferHandler(childrenTable)); 
    childrenTable.setRowSelectionAllowed(true); 
    childrenTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 

瞬間にあなたが行の間、マウスで行を移動するときにのみ持っています1つの太い線(イメージの下の赤い楕円のように)。このように行を移動することが不可能な場合は、この太い線を(1つのセルだけでなく)全体の行に表示します。

enter image description here

答えて

3

基礎のためのドラッグ&ドロップでのSwingのチュートリアルからのセクションをお読みください。

import javax.swing.*; 
import javax.swing.border.*; 
import javax.swing.table.*; 
import java.awt.*; 
import java.awt.datatransfer.*; 
import java.awt.event.*; 
import java.io.IOException; 
public class DnD_Demo extends JFrame { 
    public DnD_Demo() { 
     setTitle("DnD Demo (Version 3)"); 
     JTextArea tips = new JTextArea("1. Select a row in Table A. " + 
       "Press the row again and drag. \n  " + 
       "As you drag the cursor icon over Table B, the row that is currently under the cursor highlights " + 
       "- the new data will be inserted after the selected row. \n  " + 
       "Drop the row onto Table B. Note that the row has been removed from Table A, " + 
       "and now appears in Table B. \n" + 
       "2. Select two rows from Table A and drop onto Table B. " + 
       "Now there are two new rows in Table B. "); 
     tips.setEditable(false); 
     tips.setBackground(new Color(255,255,204)); 
     tips.setBorder(new LineBorder(Color.orange,5)); 
     getContentPane().add(tips,BorderLayout.NORTH); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JPanel panel = new JPanel(new GridLayout(2,1)); 
     panel.add(createTable("Table A")); 
     panel.add(createTable("Table B")); 
     getContentPane().add(panel,BorderLayout.CENTER); 
     pack(); 
    } 
    private JPanel createTable(String tableId) { 
     DefaultTableModel model = new DefaultTableModel(); 
     model.addColumn("Column 0"); 
     model.addColumn("Column 1"); 
     model.addColumn("Column 2"); 
     model.addColumn("Column 3"); 
     model.addRow(new String[]{tableId+" 00", tableId+" 01", tableId+" 02", tableId+" 03"}); 
     model.addRow(new String[]{tableId+" 10", tableId+" 11", tableId+" 12", tableId+" 13"}); 
     model.addRow(new String[]{tableId+" 20", tableId+" 21", tableId+" 22", tableId+" 23"}); 
     model.addRow(new String[]{tableId+" 30", tableId+" 31", tableId+" 32", tableId+" 33"}); 
     JTable table = new JTable(model); 
     table.getTableHeader().setReorderingAllowed(false); 
     table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); 
     JScrollPane scrollPane = new JScrollPane(table); 
     scrollPane.setPreferredSize(new Dimension(400,100)); 
     table.setDragEnabled(true); 
     table.setTransferHandler(new TableTransferHandler()); 
     JPanel panel = new JPanel(); 
     panel.add(scrollPane); 
     panel.setBorder(BorderFactory.createTitledBorder(tableId)); 
     return panel; 
    } 
    public static void main(String[] args) { 
     new DnD_Demo().setVisible(true); 
    } 

    abstract class StringTransferHandler extends TransferHandler { 
     protected abstract String exportString(JComponent c); 
     protected abstract void importString(JComponent c, String str); 
     protected abstract void cleanup(JComponent c, boolean remove); 
     protected Transferable createTransferable(JComponent c) { 
      return new StringSelection(exportString(c)); 
     } 
     public int getSourceActions(JComponent c) { 
      return COPY_OR_MOVE; 
     } 
     public boolean importData(JComponent c, Transferable t) { 
      if (canImport(c, t.getTransferDataFlavors())) { 
       try { 
        String str = (String)t.getTransferData(DataFlavor.stringFlavor); 
        importString(c, str); 
        return true; 
       } catch (UnsupportedFlavorException ufe) { 
       } catch (IOException ioe) { 
       } 
      } 
      return false; 
     } 
     protected void exportDone(JComponent c, Transferable data, int action) { 
      cleanup(c, action == MOVE); 
     } 
     public boolean canImport(JComponent c, DataFlavor[] flavors) { 
      for (int i = 0; i < flavors.length; i++) { 
       if (DataFlavor.stringFlavor.equals(flavors[i])) { 
        return true; 
       } 
      } 
      return false; 
     } 
    } 
    class TableTransferHandler extends StringTransferHandler { 
     public JTable target; 
     public int[] rows = null; 
     public int addIndex = -1; //Location where items were added 
     public int addCount = 0; //Number of items added. 
     protected String exportString(JComponent c) { 
      JTable table = (JTable)c; 
      rows = table.getSelectedRows(); 
      int colCount = table.getColumnCount(); 
      StringBuffer buff = new StringBuffer(); 
      for (int i = 0; i < rows.length; i++) { 
       for (int j = 0; j < colCount; j++) { 
        Object val = table.getValueAt(rows[i], j); 
        buff.append(val == null ? "" : val.toString()); 
        if (j != colCount - 1) { 
         buff.append(","); 
        } 
       } 
       if (i != rows.length - 1) { 
        buff.append("\n"); 
       } 
      } 
      return buff.toString(); 
     } 
     protected void importString(JComponent c, String str) { 
      target = (JTable)c; 
      DefaultTableModel model = (DefaultTableModel)target.getModel(); 
      int index = target.getSelectedRow(); 
      //Prevent the user from dropping data back on itself. 
      //For example, if the user is moving rows #4,#5,#6 and #7 and 
      //attempts to insert the rows after row #5, this would 
      //be problematic when removing the original rows. 
      //So this is not allowed. 
      if (rows != null && index >= rows[0] - 1 && 
        index <= rows[rows.length - 1]) { 
       rows = null; 
       return; 
      } 
      int max = model.getRowCount(); 
      if (index < 0) { 
       index = max; 
      } else { 
       index++; 
       if (index > max) { 
        index = max; 
       } 
      } 
      addIndex = index; 
      String[] values = str.split("\n"); 
      addCount = values.length; 
      int colCount = target.getColumnCount(); 
      for (int i = 0; i < values.length ; i++) { 
       model.insertRow(index++, values[i].split(",")); 
      } 
      //If we are moving items around in the same table, we 
      //need to adjust the rows accordingly, since those 
      //after the insertion point have moved. 
      if (rows!= null && addCount > 0) { 
       for (int i = 0; i < rows.length; i++) { 
        if (rows[i] > addIndex) { 
         rows[i] += addCount; 
        } 
       } 
      } 
     } 
     protected void cleanup(JComponent c, boolean remove) { 
      JTable source = (JTable)c; 
      if (remove && rows != null) { 
       DefaultTableModel model = 
         (DefaultTableModel)source.getModel(); 
       for (int i = rows.length - 1; i >= 0; i--) { 
        model.removeRow(rows[i]); 
       } 
      } 
      rows = null; 
      addCount = 0; 
      addIndex = -1; 
     } 
    } 
} 
2

私はSwing tutorialJListの項目スワップにListTransferHandler.javaも参考になると思います。ここでは

は、私はJTableのをサポートするために、カスタムTransferHandlerでウェブ上のどこかにあるいくつかの古いコードです。ここ

私はJTableためListTransferHandlerの変形例である:

import java.awt.*; 
import java.awt.datatransfer.*; 
import java.awt.dnd.*; 
import java.awt.event.*; 
import java.io.IOException; 
import java.util.*; 
import java.util.List; 
import javax.activation.*; 
import javax.swing.*; 
import javax.swing.table.*; 

public final class TableRowsDnDTest { 
    private final TransferHandler handler = new TableRowTransferHandler(); 
    private final String[] columnNames = {"String", "Integer", "Boolean"}; 
    private final Object[][] data = { 
    {"AAA", 12, true}, {"aaa", 1, false}, 
    {"BBB", 13, true}, {"bbb", 2, false}, 
    {"CCC", 15, true}, {"ccc", 3, false}, 
    {"DDD", 17, true}, {"ddd", 4, false}, 
    {"EEE", 18, true}, {"eee", 5, false}, 
    {"FFF", 19, true}, {"fff", 6, false}, 
    {"GGG", 92, true}, {"ggg", 0, false} 
    }; 
    private final TableModel model = new DefaultTableModel(data, columnNames) { 
    @Override public Class<?> getColumnClass(int column) { 
     switch (column) { 
     case 0: 
     return String.class; 
     case 1: 
     return Number.class; 
     case 2: 
     return Boolean.class; 
     default: 
     return super.getColumnClass(column); 
     } 
    } 
    }; 
    private final JTable table = new JTable(model); 

    public JComponent makeUI() { 
    table.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 
    table.setTransferHandler(handler); 
    table.setDropMode(DropMode.INSERT_ROWS); 
    table.setDragEnabled(true); 
    table.setFillsViewportHeight(true); 
    //table.setAutoCreateRowSorter(true); //XXX 

    //Disable row Cut, Copy, Paste 
    ActionMap map = table.getActionMap(); 
    Action dummy = new AbstractAction() { 
     @Override public void actionPerformed(ActionEvent e) { /* Dummy action */ } 
    }; 
    map.put(TransferHandler.getCutAction().getValue(Action.NAME), dummy); 
    map.put(TransferHandler.getCopyAction().getValue(Action.NAME), dummy); 
    map.put(TransferHandler.getPasteAction().getValue(Action.NAME), dummy); 

    JPanel p = new JPanel(new BorderLayout()); 
    p.add(new JScrollPane(table)); 
    p.setBorder(BorderFactory.createTitledBorder("Drag & Drop JTable")); 
    return p; 
    } 
    public static void main(String... args) { 
    EventQueue.invokeLater(() -> { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     f.getContentPane().add(new TableRowsDnDTest().makeUI()); 
     f.setSize(320, 240); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    }); 
    } 
} 

//Demo - BasicDnD (Drag and Drop and Data Transfer) https://docs.oracle.com/javase/tutorial/uiswing/dnd/basicdemo.html 
//Demo - DropDemo (Drag and Drop and Data Transfer) https://docs.oracle.com/javase/tutorial/uiswing/dnd/dropmodedemo.html 
//@see https://docs.oracle.com/javase/tutorial/uiswing/examples/dnd/DropDemoProject/src/dnd/ListTransferHandler.java 
//@see https://github.com/aterai/java-swing-tips/blob/master/DnDReorderTable/src/java/example/TableRowsDnDTest.java 
class TableRowTransferHandler extends TransferHandler { 
    private final DataFlavor localObjectFlavor; 
    private int[] indices; 
    private int addIndex = -1; //Location where items were added 
    private int addCount; //Number of items added. 

    protected TableRowTransferHandler() { 
    super(); 
    localObjectFlavor = new ActivationDataFlavor(Object[].class, DataFlavor.javaJVMLocalObjectMimeType, "Array of items"); 
    } 
    @Override protected Transferable createTransferable(JComponent c) { 
    JTable table = (JTable) c; 
    DefaultTableModel model = (DefaultTableModel) table.getModel(); 
    List<Object> list = new ArrayList<>(); 
    indices = table.getSelectedRows(); 
    for (int i : indices) { 
     list.add(model.getDataVector().get(i)); 
    } 
    Object[] transferedObjects = list.toArray(); 
    return new DataHandler(transferedObjects, localObjectFlavor.getMimeType()); 
    } 
    @Override public boolean canImport(TransferHandler.TransferSupport info) { 
    JTable table = (JTable) info.getComponent(); 
    boolean isDropable = info.isDrop() && info.isDataFlavorSupported(localObjectFlavor); 
    table.setCursor(isDropable ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop); 
    return isDropable; 
    } 
    @Override public int getSourceActions(JComponent c) { 
    return TransferHandler.MOVE; 
    } 
    @Override public boolean importData(TransferHandler.TransferSupport info) { 
    if (!canImport(info)) { 
     return false; 
    } 
    TransferHandler.DropLocation tdl = info.getDropLocation(); 
    if (!(tdl instanceof JTable.DropLocation)) { 
     return false; 
    } 
    JTable.DropLocation dl = (JTable.DropLocation) tdl; 
    JTable target = (JTable) info.getComponent(); 
    DefaultTableModel model = (DefaultTableModel) target.getModel(); 
    int index = dl.getRow(); 
    int max = model.getRowCount(); 
    if (index < 0 || index > max) { 
     index = max; 
    } 
    addIndex = index; 
    target.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 
    try { 
     Object[] values = (Object[]) info.getTransferable().getTransferData(localObjectFlavor); 
     addCount = values.length; 
     for (int i = 0; i < values.length; i++) { 
     int idx = index++; 
     model.insertRow(idx, (Vector) values[i]); 
     target.getSelectionModel().addSelectionInterval(idx, idx); 
     } 
     return true; 
    } catch (UnsupportedFlavorException | IOException ex) { 
     ex.printStackTrace(); 
    } 
    return false; 
    } 
    @Override protected void exportDone(JComponent c, Transferable data, int action) { 
    cleanup(c, action == TransferHandler.MOVE); 
    } 

    //If the remove argument is true, the drop has been 
    //successful and it's time to remove the selected items 
    //from the list. If the remove argument is false, it 
    //was a Copy operation and the original list is left 
    //intact. 
    protected void cleanup(JComponent c, boolean remove) { 
    if (remove && indices != null) { 
     c.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 
     DefaultTableModel model = (DefaultTableModel)((JTable) c).getModel(); 
     //If we are moving items around in the same list, we 
     //need to adjust the indices accordingly, since those 
     //after the insertion point have moved. 
     if (addCount > 0) { 
     for (int i = 0; i < indices.length; i++) { 
      if (indices[i] >= addIndex) { 
      indices[i] += addCount; 
      } 
     } 
     } 
     for (int i = indices.length - 1; i >= 0; i--) { 
     model.removeRow(indices[i]); 
     } 
    } 
    indices = null; 
    addCount = 0; 
    addIndex = -1; 
    } 
} 
関連する問題