[英]Generic class to detect triple click without firing double- or single-click
[英]Java : detect triple-click without firing double-click
我有一個JTable,我想在雙擊單元格時調用一個函數,並在單擊三次單元格時調用另一個函數。
當單擊三次單元格時,我不想調用雙擊功能。
我現在擁有的是(mgrdAlarm是JTable):
mgrdAlarm.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
System.out.println("getClickCount() = " + e.getClickCount());
if (e.getClickCount()==2)
{
doubleClick();
System.out.println("Completed : doubleClick()");
}
if (e.getClickCount()==3)
{
tripleClick();
System.out.println("Completed : tripleClick()");
}
}
});
雙擊控制台時顯示:
getClickCount() = 1
getClickCount() = 2
Completed : doubleClick()
三擊時,控制台顯示:
getClickCount() = 1
getClickCount() = 2
Completed : doubleClick()
getClickCount() = 3
Completed : tripleClick()
三擊時,我希望控制台顯示:
getClickCount() = 1
getClickCount() = 2
getClickCount() = 3
Completed : tripleClick()
因此,當單擊三次單元格時,我不想調用函數doubleClick(),但我想在雙擊單元格時調用函數doubleClick()。
[編輯]
正如所有回復都表明解決方案似乎是延遲雙擊操作並等待一段時間進行三次點擊。
但正如這里所討論的那樣,可能會導致不同類型的問題:用戶可能將其雙擊時間設置得相當長,這可能與我的三次點擊超時重疊。
如果我的雙擊操作在我的三擊操作之前執行,那不是真正的災難,但它確實會產生一些額外的開銷,特別是一些我希望阻止的額外數據流量。
到目前為止唯一的解決辦法可能會導致其他問題,這可能實際上比原來的問題更糟糕,我現在就把它留下來。
public class TestMouseListener implements MouseListener {
private boolean leftClick;
private int clickCount;
private boolean doubleClick;
private boolean tripleClick;
public void mouseClicked(MouseEvent evt) {
if (evt.getButton()==MouseEvent.BUTTON1){
leftClick = true; clickCount = 0;
if(evt.getClickCount() == 2) doubleClick=true;
if(evt.getClickCount() == 3){
doubleClick = false;
tripleClick = true;
}
Integer timerinterval = (Integer)Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
Timer timer = new Timer(timerinterval, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if(doubleClick){
System.out.println("double click.");
clickCount++;
if(clickCount == 2){
doubleClick(); //your doubleClick method
clickCount=0;
doubleClick = false;
leftClick = false;
}
}else if (tripleClick) {
System.out.println("Triple Click.");
clickCount++;
if(clickCount == 3) {
tripleClick(); //your tripleClick method
clickCount=0;
tripleClick = false;
leftClick = false;
}
} else if(leftClick) {
System.out.println("single click.");
leftClick = false;
}
}
});
timer.setRepeats(false);
timer.start();
if(evt.getID()==MouseEvent.MOUSE_RELEASED) timer.stop();
}
}
public static void main(String[] argv) throws Exception {
JTextField component = new JTextField();
component.addMouseListener(new TestMouseListener());
JFrame f = new JFrame();
f.add(component);
f.setSize(300, 300);
f.setVisible(true);
component.addMouseListener(new TestMouseListener());
}
}
之前的答案是正確的:你必須考慮時間和延遲,將其識別為雙擊,直到經過一定的時間。 挑戰在於,正如您所注意到的,用戶可能具有非常長或非常短的雙擊閾值。 所以你需要知道用戶的設置是什么。 這個其他Stack Overflow線程( 區分單擊和Java中的雙擊 )提到了awt.multiClickInterval
桌面屬性。 嘗試使用它作為您的閾值。
你可以做類似的事情,不同的延遲時間:
public class ClickForm extends JFrame {
final static long CLICK_FREQUENTY = 300;
static class ClickProcessor implements Runnable {
Callable<Void> eventProcessor;
ClickProcessor(Callable<Void> eventProcessor) {
this.eventProcessor = eventProcessor;
}
@Override
public void run() {
try {
Thread.sleep(CLICK_FREQUENTY);
eventProcessor.call();
} catch (InterruptedException e) {
// do nothing
} catch (Exception e) {
// do logging
}
}
}
public static void main(String[] args) {
ClickForm f = new ClickForm();
f.setSize(400, 300);
f.addMouseListener(new MouseAdapter() {
Thread cp = null;
public void mouseClicked(MouseEvent e) {
System.out.println("getClickCount() = " + e.getClickCount() + ", e: " + e.toString());
if (cp != null && cp.isAlive()) cp.interrupt();
if (e.getClickCount() == 2) {
cp = new Thread(new ClickProcessor(new Callable<Void>() {
@Override
public Void call() throws Exception {
System.out.println("Double click processed");
return null;
}
}));
cp.start();
}
if (e.getClickCount() == 3) {
cp = new Thread(new ClickProcessor(new Callable<Void>() {
@Override
public Void call() throws Exception {
System.out.println("Triple click processed");
return null;
}
}));
cp.start();
}
}
});
f.setVisible(true);
}
}
有一個教程這個位置
編輯:它會單獨觸發單擊事件,因此您可以獲得:單擊然后雙擊然后三擊。 所以你仍然需要做一些計時技巧。
代碼是:
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class Main {
public static void main(String[] argv) throws Exception {
JTextField component = new JTextField();
component.addMouseListener(new MyMouseListener());
JFrame f = new JFrame();
f.add(component);
f.setSize(300, 300);
f.setVisible(true);
component.addMouseListener(new MyMouseListener());
}
}
class MyMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent evt) {
if (evt.getClickCount() == 3) {
System.out.println("triple-click");
} else if (evt.getClickCount() == 2) {
System.out.println("double-click");
}
}
}
您需要延遲執行double click
以檢查它是否為tripple click
。
暗示。
如果getClickCount()==2
然后把它等待...比如200ms
?
這與檢測雙擊而不觸發單擊完全相同。 你必須延遲發射一個事件,直到你確定沒有下一個點擊。
以下是我為實現這一目標所做的工作,這對我來說確實很好。 檢測點擊類型需要延遲。 你可以選擇它。 如果在400ms內發生三次點擊,則會出現以下延遲。 您可以將其減小到可以連續單擊的程度。 如果你只是擔心延遲,那么這是一個非常微不足道的延遲,這對於實現這一點必不可少。
這里flag
和t1
是全局變量。
public void mouseClicked(MouseEvent e)
{
int count=e.getClickCount();
if(count==3)
{
flag=true;
System.out.println("Triple click");
}
else if(count==2)
{
try
{
t1=new Timer(1,new ActionListener(){
public void actionPerformed(ActionEvent ae)
{
if(!flag)
System.out.println("Double click");
flag=false;
t1.stop();
}
});
t1.setInitialDelay(400);
t1.start();
}catch(Exception ex){}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.