2016-06-28 15 views
3

問題無効にドラッグ選択

私は、私のJTableの中で非選択セルをクリックしてドラッグしたいと思います。 e。テーブルはドラッグモードにする必要があります。問題は、JTableに、選択されていないセルをクリックしてドラッグすると、実際にドラッグモードではなく選択モードにあるというメカニズムがあることです。選択モードはクリックでのみ可能でなければならず、ドラッグ+ドラッグではなくShift +クリックで拡張可能でなければなりません。

私が見つけたことは、BasicTableUIにありましたが、残念ながら関連性のあるものはすべてプライベートです。

質問

どのようにドラッグを経由して選択を防ぐことができますし、非選択セルをクリックして、それをドラッグすると、ドラッグモードに瞬時になりますか?

私は検索しましたが、私が見つけた解決策はどれも満足できませんでした。または、古いJavaバージョン用です。非選択セルをクリックし、マウスをドラッグし

  • コード

    はここに再現するためのいくつかのコードです。細胞が選択されます。

  • 選択したセルをクリックしてドラッグします。テーブルはドラッグモードです。

コード:

import java.awt.BorderLayout; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseMotionAdapter; 

import javax.swing.DropMode; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 

public class Main { 
    public static void main(String args[]) { 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    Object rowData[][] = { 
     { "a", "a", "a" }, 
     { "a", "a", "a" }, 
     { "a", "a", "a" }, 
     { "a", "a", "a" }, 
     { "a", "a", "a" }, 
     }; 

    Object columnNames[] = { "Column 1", "Column 2", "Column 3" }; 
    final JTable table = new JTable(rowData, columnNames); 

    table.setDragEnabled(true); 
    table.setDropMode(DropMode.INSERT_ROWS); 

    table.addMouseMotionListener(new MouseMotionAdapter() { 

     @Override 
     public void mouseDragged(MouseEvent e) { 

     boolean selectionIsAdjusting = table.getSelectionModel().getValueIsAdjusting(); 

     if(selectionIsAdjusting) { 
      System.out.println("selecting"); 
     } else { 
      System.out.println("dragging"); 
     } 

     } 
    }); 

    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 
    table.setColumnSelectionAllowed(true); 
    table.setRowSelectionAllowed(true); 

    JScrollPane scrollPane = new JScrollPane(table); 
    frame.add(scrollPane, BorderLayout.CENTER); 
    frame.setSize(300, 150); 
    frame.setVisible(true); 

    } 
} 

スクリーンショット:

enter image description here

は助けをありがとうございました!

+0

'あなたは空のセルをクリックして、それをドラッグすると、'あなたは空の意味するか、何のコンテンツセルが(例えば区別しません空の文字列など)、または任意のセルをドラッグするだけですか?投稿されたコードには「空の」セルが含まれていません。 – copeg

+0

ああ、そうです、私はそれを修正しました。それは選択されていない細胞です。私は選択されていないセルをクリックしてドラッグします。 – Roland

+0

質問の2番目の文も更新した方が便利です。 – VGR

答えて

1

あなたは直接MouseMotionListener#mouseDragged(...)TransferHandler#exportAsDrag(...)メソッドを呼び出すことができるかもしれない:?

import java.awt.*; 
import java.awt.event.*; 
import java.util.Optional; 
import javax.swing.*; 
import javax.swing.table.*; 

public class Main2 { 
    public JComponent makeUI() { 
    Object columnNames[] = {"Column 1", "Column 2", "Column 3"}; 
    Object data[][] = { 
     { "a", "a", "a" }, 
     { "a", "a", "a" }, 
     { "a", "a", "a" }, 
     { "a", "a", "a" }, 
     { "a", "a", "a" }, 
    }; 
    JTable table = new JTable(new DefaultTableModel(data, columnNames)); 
    table.setDragEnabled(true); 
    table.setDropMode(DropMode.INSERT_ROWS); 
    table.addMouseMotionListener(new MouseAdapter() { 
     @Override public void mouseDragged(MouseEvent e) { 
     JComponent c = (JComponent) e.getComponent(); 
     Optional.ofNullable(c.getTransferHandler()) 
       .ifPresent(th -> th.exportAsDrag(c, e, TransferHandler.COPY)); 
     } 
    }); 
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 
    table.setColumnSelectionAllowed(true); 
    table.setRowSelectionAllowed(true); 

    JPanel p = new JPanel(new BorderLayout()); 
    p.add(new JScrollPane(table)); 
    p.add(new JTextField(), BorderLayout.SOUTH); 
    return p; 
    } 
    public static void main(String... args) { 
    EventQueue.invokeLater(() -> { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     f.getContentPane().add(new Main2().makeUI()); 
     f.setSize(320, 240); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    }); 
    } 
} 
-1

選択モードではありません

をドラッグ経由してあなたには、いくつかの追加のロジックとのJTableのprocessMouseEventメソッドをオーバーライドすることで動作を変更することができるかもしれ、唯一のクリックを介して可能であるべきで、シフト+クリックを経由して拡張する必要があります。ボタンダウンイベントが発生し、シフトがダウンしていない場合、親メソッドを呼び出す前に、JTableの選択を現在のクリックされた行に変更します。

JTable table = new JTable(rowData, columnNames){ 
    @Override 
     public void processMouseEvent(MouseEvent e){ 
      Component c = (Component)e.getSource(); 
      if (e.getModifiersEx() == MouseEvent.BUTTON1_DOWN_MASK && (e.getModifiers() & MouseEvent.SHIFT_DOWN_MASK) == 0){ 
       int row = rowAtPoint(e.getPoint()); 
       int col = columnAtPoint(e.getPoint()); 
       if (!isCellSelected(row, col)){ 
        clearSelection(); 
        changeSelection(row, col, false, false); 
       } 

      } 
      MouseEvent e1 = new MouseEvent(c, e.getID(), e.getWhen(), 
        e.getModifiers() | InputEvent.CTRL_MASK, 
        e.getX(), e.getY(), 
        e.getClickCount(), 
        e.isPopupTrigger() , 
        e.getButton()); 

      super.processMouseEvent(e1); 
     } 
}; 
+0

ありがとうございますが、それはすべての場合に機能しません。あなたがeであれば動作しません。 g。シングルセル選択モードで使用できます。このサンプルをシングルセル選択モードで更新しました。私はprocessMouseEventのオーバーライドを持つソリューションを見てきました。私はまだそれが満足のいくものを発見していない。 – Roland

+0

@Roland、選択モードベースで実装するよりも簡単な答えはないかもしれません...コントロールはドラッグを開始すると言われています - シフトは優先順位が必要です。したがって、必要に応じて選択範囲を変更してから、コントロールマスクを使用してMouseEventを渡します(編集 - 注:すべての選択モードでこれをテストしていません)。 – copeg

+0

お世話になりました。しかし、今では単一の細胞の選択はなくなりました。セルをクリックすると、フォーカス境界線しか得られません。私はあなたのソリューションで周りをおもしろくします。しかし、私が言ったように、私は以前にその解決策を見てきました。私が気に入らないのは、暗黙のうちに一部のリスナーを呼び出す選択の変更です。私は副作用のない正しい方法を探しています。 – Roland

関連する問題