2009-03-12 15 views
5

キーボードボタンが押されたとき(つまりCTRLボタン)に行が選択されているときに、JTableのコントロールを操作して別の機能を提供する簡単な方法はありますか?私は、行のCTRL +クリック(マウスクリック)が選択された行の選択を解除し、行を選択しないという表を作成するよう求められました。ユーザーが選択されていない行をCTRL +クリックすると、何も起こりません。JTableのCtrl +クリックの動作を変更する

私はテーブルを作成し、CTRL + A(select all)のような機能を無効にできました.MouseEventが生成されたときにコントロールボタンが押されたかどうかを確認できましたが、 CTRL +クリックの調整方法を理解しているようです。ここではいくつかのコードです:私はテーブルから選択したすべての行を取得し、その後、新たにクリックされた行はselectedRowsにあったかどうかを確認するつもりだったと周りにプレーしたのmousePressedメソッドで

package nicky; 

import javax.swing.*; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.event.*; 

public class TableTester extends JPanel { 
    public TableTester() { 
     super(new GridLayout(1,0)); 

     final String[] columnNames = {"First Name", 
             "Last Name", 
             "Sport", 
             "# of Years", 
             "Vegetarian"}; 

     final Object[][] data = { 
      {"Tom", "Roberts","Athletic", new Integer(5), new Boolean(false)}, 
      {"Sarah", "Watt", "Football", new Integer(3), new Boolean(true)}, 
      {"Laura", "Brown", "Swimming", new Integer(2), new Boolean(false)}, 
      {"Simon", "Smith", "Tennis", new Integer(20), new Boolean(true)}, 
      {"Paul", "Jones", "Rugby", new Integer(10), new Boolean(false)} 
     }; 

     JTable table = new JTable(data, columnNames); 
     table.setPreferredScrollableViewportSize(new Dimension(500, 100)); 

     table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 

     table.addMouseListener(new MouseListener(){ 
      public void mouseEntered(MouseEvent me){} 
      public void mouseExited(MouseEvent me){} 
      public void mouseReleased(MouseEvent me){} 
      public void mouseClicked(MouseEvent me){} 
      public void mousePressed(MouseEvent me){ 
       if (me.isControlDown()){ 
        System.out.println("This is working "); 
       } 
      } 
     }); 

     InputMap inputMap = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 
     KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK); 
     inputMap.put(keyStroke, "none"); 

     JScrollPane scrollPane = new JScrollPane(table); 
     add(scrollPane); 
    } 

    private static void createAndShowGUI() { 
     JFrame.setDefaultLookAndFeelDecorated(true); 
     JFrame frame = new JFrame("TableTester"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     TableTester newContentPane = new TableTester(); 
     newContentPane.setOpaque(true); 
     frame.setContentPane(newContentPane); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 

...しかし、どの行がMouseEventに関連付けられているかを確認する方法があるかどうかはわかりません。

任意のアイデア/提案をいただければ幸いです

(また、私はこのような予想される動作があまりにも多くの周りに再生するべきではありません知っているが、それは会社でレガシーシステムを複製することです)!

答えて

8

OK、2番目のテイク(私は最初のものをいくつかの他の用途に興味があるように残しましたが、誰が知っていますか?教育目的のためにそこにいると言う:-))。

私はJTableのソースコードを見て、マウスイベントがルックアンドフィールで処理されることを発見しました。どのようにコントロールキーを処理するかを知っているので、必要な処理を行うためにchangeSelectionメソッドを安全にオーバーライドできます。
要件が少し変わっています(Shift +クリックは使用できますか?)が、コンテキストはわかりません。

class SpecialTable extends JTable 
{ 
    SpecialTable(Object[][] data, String[] columnNames) 
    { 
     super(data, columnNames); 
// That's already the default   
//  setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 
    } 

    /** 
    * Called by javax.swing.plaf.basic.BasicTableUI.Handler.adjustSelection(MouseEvent) 
    * like: table.changeSelection(pressedRow, pressedCol, e.isControlDown(), e.isShiftDown()); 
    */ 
    @Override 
    public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) 
    { 
     if (toggle && !isRowSelected(rowIndex)) 
      return; // Don't do the selection 
     super.changeSelection(rowIndex, columnIndex, toggle, extend); 
    } 
} 

非常に簡単で正確に必要なもの!

このような簡単なテストケースを提供してくれてありがとうございました。自分で書かなければならなかったかもしれません... :-D興味深い、学習課題でした。

+0

Woohoo!出来た!ありがとう:) はい、私は要件が狂っていると思う...そしてこれはそれの半分でもありません! – Nicks

1

私はそれが最善の方法だと確信していないですが、私は

class SpecialTable extends JTable 
{ 
    boolean bIsControlDown; 
    int clickedRow; 

    SpecialTable(Object[][] data, String[] columnNames) 
    { 
     super(data, columnNames); 
//  setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 
     getSelectionModel().addListSelectionListener(this); 
     addMouseListener(new MouseInputAdapter() 
     { 
      public void mousePressed(MouseEvent me) 
      { 
       bIsControlDown = me.isControlDown(); 
       clickedRow = rowAtPoint(me.getPoint()); 
      } 
     }); 
    } 

    public void valueChanged(ListSelectionEvent evt) 
    { 
     super.valueChanged(evt); 
     if (bIsControlDown) 
     { 
      if (!evt.getValueIsAdjusting()) 
      { 
//    System.out.println(evt); 
//    System.out.println("=> " + clickedRow); 
       getSelectionModel().removeSelectionInterval(clickedRow, clickedRow); 
      } 
     } 
    } 
} 

だけであなたのコードでtableを定義する行置換...、次の成功を持っていた:

JTable table = new SpecialTable(data, columnNames); 
    table.setPreferredScrollableViewportSize(new Dimension(500, 100)); 

あなたを選択されていない行をControlキーを押しながらクリックすると、簡単に選択されてから選択解除されます。

+0

ありがとうございます。残念ながらそれは私の問題のために働くつもりです。行が選択されると直ちにメッセージが消えますので、選択/非選択のクイック・セレクト・アクションはそのメッセージを送信します。 – Nicks

+0

私はそれを恐れた。代わりに、super.valueChanged()への呼び出しを避け、複数の間隔の選択を自分で完全に処理します(Javaのコードをコピーして自分のやり方で変更することもできます)。 – PhiLho

+0

真実 - ありがとう、私はそれを行くつもりだと思う。 – Nicks

関連する問題