2012-06-19 68 views
2

我正嘗試使用默認組件對可編輯的JTable執行撤消(和重做)功能。 JTable有一個額外的類來指定其名稱爲SpecifiedJTable的屬性。JTable將不會偵聽Doubleclicks

爲此,我想抓住單元格被雙擊的時刻(即選擇/標記要編輯單元的時刻),以便將單元格中的信息及其座標推送到堆棧上。

這應該通過MouseListener ...至少這是我的想法。 我試圖

class JTableSpecified extends JTable { 
    private static final long serialVersionUID = 1L; 
    private int c; // the currently selected column 
    private int r; // the currently selected row 

    public JTableSpecified(String[][] obj, String[] columnNames) { 
     super(obj, columnNames); // constructs the real table 
     // makes that you can only select one row at a time 
     this.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); 
     // makes that columns are not squeezed 
     this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
     // forbids to rearrange the columns 
     getTableHeader().setReorderingAllowed(false); 
     // adds action listener 
     this.getModel().addTableModelListener(new TableModelListener() { 
      public void tableChanged(TableModelEvent e) { 
       r = getSelectedRow(); 
       c = getSelectedColumn(); 
       // get the String at row r and column c 
       String s = (String) getValueAt(r, c); 
       if (jobDisplayed) jobSwitch(c, s); 
       else resSwitch(c, s); 
      } 
     });  
     this.addMouseListener(new MouseAdapter() { 
      public void mouseClicked(MouseEvent e) { 
       if (e.getClickCount() == 2) { 
        System.out.println("test"); 
       } 
      } 
     }); 
    } 
} 

這(在我的SpecifiedJTable類的構造函數站立),但不知何故clickCounter doesn't想達到什麼that's高於1

我很高興任何答案,幫幫我。謝謝。

+0

一般來說,這應該有效。我在自己的代碼中使用類似的東西。可能有一些其他鼠標監聽器在您的表上註冊,這會消耗一些鼠標事件並阻止它們傳播到您的監聽器。 – Enwired

+2

你能更正代碼嗎?作爲它不是它不會編譯。首先請通過更多相關代碼[SSCCE](http://sscce.org/) – Boro

+0

,感謝您的回答。擴展的代碼現在在問題中。 @ user1442870你可以想象這是哪一個,甚至更重要:你有什麼想法來「停止」消耗鼠標事件的其他聽衆?至少tablemodelListener不是問題。我試圖停用它,並且mouseListener畢竟沒有反應。 – user1466944

回答

-1

代碼中的錯誤是,只要第一次點擊發生,就會調用mouseClicked方法。當發生雙擊時,再次調用mouseClicked方法。您可以爲存儲時間的較早的單擊事件(使用e.getWhen()方法)放置一個靜態變量(或一個類變量)。 檢查時差,如果它足夠小,請執行您的操作(我建議調用doubleClick方法)。

您可能不得不在您的類JTableSpecified中實現鼠標偵聽器,因爲靜態變量可能不會放在您現有的代碼中。

+0

嗯,我想這不是一個真正的解決方案,我的問題:/因爲當你實現這個,你可以點擊到兩個不同的單元格,它也被解僱,因爲計數器是2.也許我可以把這個監聽器放到每個單元格......有沒有辦法做到這一點?或者如果沒有鼠標偵聽器來檢測選擇的時刻,可能還有更好的方法。 – user1466944

+0

是的,你可以通過getPosition方法檢查mouseEvent的位置。我沒有這個要求,因爲如果時差低至500毫秒,不可能在500毫秒內點擊,移動和再次點擊。但是如果你想要你可以做2個變量並檢查兩個條件。畢竟,雙擊被定義爲兩次快速連續的點擊而不用移動鼠標。 – vedant1811

2

您遇到的問題與使用mouseClicked()相關,而不是使用mousePressed()。在這種情況下,增加點擊計數器似乎非常困難,但仍然有可能。它花了我大量的點擊和鼠標移動來增加點擊計數器超過1.你可以自己嘗試一下,在你的代碼中。要讓計數器超過1,您需要快速按下&釋放鼠標,同時將鼠標從一個細胞移動到另一個細胞(或者我只是在單元格之間快速點擊?),您需要對鼠標發瘋。

正如你在這個完整的工作示例中看到的那樣,使用mousePressed()方法可以很好地檢測到你的代碼,兩個鼠標按下。

public class JTableSpecified extends JTable { 
    private static final long serialVersionUID = 1L; 

    public JTableSpecified(String[][] obj, String[] columnNames) { 
     super(obj, columnNames); // constructs the real table 
     // makes that you can only select one row at a time 
     this.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); 
     // makes that columns are not squeezed 
     this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
     // forbids to rearrange the columns 
     getTableHeader().setReorderingAllowed(false); 
     // adds action listener 
     this.getModel().addTableModelListener(new TableModelListener() { 
      @Override 
      public void tableChanged(TableModelEvent e) { 
      } 
     });   
     this.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mousePressed(MouseEvent e) { 
       if (e.getClickCount() == 2) { 
        System.out.println("test"); 
       } 
       System.out.println("e.getClickCount() = " + e.getClickCount()); 
      } 
     }); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       JPanel panel = new JPanel(); 
       panel.add(new JTableSpecified(new String[][]{{"oi", "oi2"}, {"oi3", "oi4"}}, new String[]{"Col1", "Col2"})); 
       JFrame f = new JFrame(); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       f.setContentPane(panel); 
       f.pack(); 
       f.setVisible(true); 
      } 
     }); 
    } 
} 

結論:也許你實際上要使用的mousePressed()方法?

+0

是啊,非常感謝Boro。 =)它真的與mousePressed()一起工作。非常有趣的是,這是我一直在尋找的這種「簡單」解決方案。經過多次測試,它似乎爲我的應用程序提供了完美的結果,沒有任何不需要的事件。非常感謝你。 – user1466944

1

BasicTableUI通過雙擊單元格中的編輯模式來響應雙擊。它做了許多複雜的事情,其中​​包括創建JTextField(或其他組件)以允許編輯數據,然後阻止鼠標點擊事件進一步傳播。

如果您的表格或表格單元格不可編輯,您可以通過點擊數2,3,4,...輕鬆捕獲鼠標事件。但由於您希望表格可以編輯,因此您需要一個不同的表格做法。

一個想法是覆蓋JTable。 editCellAt()

一個更好的想法是忘掉與JTable混淆,而是在表模型本身上監聽數據更改。

1

這個答案擴展了Boro的答案。
要捕捉每個使用戶編輯表格的情況,我還需要爲F2添加KeyListener(與雙擊單元格具有相同的效果),並通過按任意鍵禁用自動單元格編輯。
我只是把它添加到構造右後方的MouseListener(見上文)

//通過敲擊鍵盤
this.putClientProperty禁止編輯( 「JTable.autoStartsEdit」,Boolean.FALSE);

//的KeyListener到上按F2(鍵碼113)
this.addKeyListener(新KeyAdapter(){

公共無效在keyPressed(KeyEvent的發送){

反應if(e.getKeyCode()== 113)System.out.println(「test」);
}
});

+0

+1是的,我喜歡它。我總是喜歡當人們用'F2'編輯'標準'鍵時進行編輯。 – Boro