编辑 - 基于接受的答案的正确代码显示在此帖的底部。
我找到了一种方法(written by Andremoniy),可以在不点击单击和双击的情况下捕获双击和三击。它非常适合我的目的。
我对其进行了修改,以便可以通过实现调整点击间隔。这也很有效。
我的修改包括将其设为abstract class
,定义实现必须定义的5个abstract
方法(单次,双次,三次和“很多”点击的方法以及点击间隔调整者)。
以下是修改后的版本(println
语句具有指导意义):
public abstract class Click123 extends JPanel
{
public abstract void singleClick();
public abstract void doubleClick();
public abstract void tripleClick();
public abstract void manyClick();
public abstract int getFreq();
public Click123()
{
addMouseListener
(
new MouseAdapter()
{
Thread cp = null;
public void mouseClicked(MouseEvent e)
{
if (cp != null && cp.isAlive())
cp.interrupt();
if (e.getClickCount() == 1)
{
cp = new Thread(new ClickProcessor(new Callable<Void>() {
@Override public Void call() throws Exception {
singleClick();
return null;
}
}));
cp.start();
}
else if (e.getClickCount() == 2)
{
cp = new Thread(new ClickProcessor(new Callable<Void>() {
@Override public Void call() throws Exception {
doubleClick();
return null;
}
}));
cp.start();
}
else if (e.getClickCount() == 3)
{
cp = new Thread(new ClickProcessor(new Callable<Void>()
{
@Override public Void call() throws Exception {
tripleClick();
return null;
}
})
);
cp.start();
}
else manyClick();
} // mouseClicked
} // new MouseAdapter
); // add mouseListener
} // Click123
class ClickProcessor implements Runnable
{
Callable<Void> eventProcessor;
ClickProcessor(Callable<Void> eventProcessor)
{
this.eventProcessor = eventProcessor;
}
@Override public void run()
{
try
{
Thread.sleep(getFreq());
eventProcessor.call();
} catch (InterruptedException e) { System.out.println(e);}
catch (Exception e) { System.out.println(e);}
} // run
} // class ClickProcessor
} // class Click123
以下是实施计划:
public class NewMain1 {
static int INITIAL_CLICK_FREQUENCY = ((Integer)Toolkit.getDefaultToolkit()
.getDesktopProperty("awt.multiClickInterval"));
public static int CLICK_FREQUENCY;
static JSpinner spinner = new JSpinner();
static final JLabel ch = new JLabel("Click here to test");
public static void main(String[] args) {
CLICK_FREQUENCY = INITIAL_CLICK_FREQUENCY;
spinner = new JSpinner();
spinner.setModel(new SpinnerNumberModel(CLICK_FREQUENCY, 200, 900, 50));
spinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
CLICK_FREQUENCY = (int) spinner.getValue();
}
});
Click123 frame = new Click123(){
public void singleClick(){
JOptionPane.showMessageDialog(null,"Single click at " + CLICK_FREQUENCY);
}
public void doubleClick(){
JOptionPane.showMessageDialog(null,"Double click at " + CLICK_FREQUENCY);
}
public void tripleClick(){
JOptionPane.showMessageDialog(null,"Triple click at " + CLICK_FREQUENCY);
}
public void manyClick(){
JOptionPane.showMessageDialog(null,"Many clicks at " + CLICK_FREQUENCY);
}
public int getFreq(){
return CLICK_FREQUENCY;
}
};
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.setSize(500, 300);
ch.setBorder(new EtchedBorder());
frame.add(ch);
frame.add(spinner);
frame.setVisible(true);
} // main
}
最初写的是Click123 extends JFrame
。我修改了它(通过将顶行更改为extends JTextField
)以使用类型为JTextField
的网格。然后我添加了一个按钮来动态更改点击间隔。所以现在我有三个相同的(除了扩展类型)巨大的代码。
我的问题是:如何修改Click123
,以便在不做任何更改的情况下,可以使用任何组件识别单击,双击和三击?
编辑 - 必要更改摘要(对于我自己的应用,abstract
方法需要传递MouseEvent
才能确定哪个组件触发了点击次数):
班级定义:
public abstract class Click123<T extends Component>
{
public abstract void singleClick(MouseEvent e); // same for 3 others
...
public Click123(T target)
{
target.addMouseListener
(
new MouseAdapter() ...
} ...
}
final
已添加为修饰符,以便传递MouseEvent
:
public void mouseClicked(final MouseEvent e)
通过MouseEvent
:
singleClick(e); // same for doubleClick and tripleClick and manyClick
接收MouseEvent
以确定哪个组件触发了点击次数:
public void doubleClick(MouseEvent e)
实现:
frame = new JPanel();
new Click123(frame) {
答案 0 :(得分:3)
泛型不是必需的。您只需要将MouseListener
添加到Component
。
public abstract class Click123 // doesn't extend anything
{
public Click123(Component comp)
{
comp.addMouseListener(new MouseAdapter() {
// ...
}));
}
}
现在您可以传递JFrame
或任何您需要的Component
:
Click123 handler = new Click123(myJFrame){
public void singleClick(){
JOptionPane.showMessageDialog(null,"Single click at " + CLICK_FREQUENCY);
}
// Other implementing methods here
}
答案 1 :(得分:1)
泛型是解决方案的一部分。只需执行以下操作:
Click123<T extends Component>
public Click123(T targetedComponent) {
targetedComponent.addMouseListener
而非addMouseListener
JFrame
或JPanel
或其他内容,然后将其作为构造函数参数传递给new Click123
。然后使用您使用JFrame
。Click123
醇>
答案 2 :(得分:0)
根据要求,我发布了有效的代码。原始帖子中的编辑太分散而无用。原始代码修改标有//////////.
package clickForm;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.concurrent.Callable;
public abstract class Click123<T extends Component> ////////////////
{
public abstract void singleClick(MouseEvent e); ////////////////
public abstract void doubleClick(MouseEvent e); ////////////////
public abstract void tripleClick(MouseEvent e); ////////////////
public abstract void manyClick(MouseEvent e); ////////////////
public abstract int getFreq();
public Click123(T target) ////////////////
{
target.addMouseListener ////////////////
(
new MouseAdapter() ////////////////
{
Thread cp = null;
public void mouseClicked(final MouseEvent e)
{
if (cp != null && cp.isAlive())
cp.interrupt();
if (e.getClickCount() == 1)
{
cp = new Thread(new ClickProcessor(new Callable<Void>() {
@Override public Void call() throws Exception {
singleClick(e); //////////////////////////////////////////
return null;
}
}));
cp.start();
}
else if (e.getClickCount() == 2)
{
cp = new Thread(new ClickProcessor(new Callable<Void>() {
@Override public Void call() throws Exception {
doubleClick(e); //////////////////////////////////////////
return null;
}
}));
cp.start();
}
else if (e.getClickCount() == 3)
{
cp = new Thread(new ClickProcessor(new Callable<Void>()
{
@Override public Void call() throws Exception {
tripleClick(e); //////////////////////////////////////////
return null;
}
})
);
cp.start();
}
else manyClick(e); //////////////////////////////////////////
} // mouseClicked
} // new MouseAdapter
); // add mouseListener
} // Click123
class ClickProcessor implements Runnable
{
Callable<Void> eventProcessor;
ClickProcessor(Callable<Void> eventProcessor)
{
this.eventProcessor = eventProcessor;
}
@Override public void run()
{
try
{
Thread.sleep(getFreq());
eventProcessor.call();
} catch (InterruptedException e) { System.out.println(e);}
catch (Exception e) { System.out.println(e);}
} // run
} // class ClickProcessor
} // class Click123
实现:
package clickForm;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Main {
static int CLICK_FREQUENCY = (int) Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
static JSpinner spinner = new JSpinner();
static final JLabel ch = new JLabel("Click here to test");
static JFrame frame = new JFrame();
public static void main(String[] args) {
spinner = new JSpinner();
spinner.setModel(new SpinnerNumberModel(CLICK_FREQUENCY, 200, 900, 50));
spinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
CLICK_FREQUENCY = (int) spinner.getValue();
}
});
new Click123(ch){ /////////////////////////////////////////////
@Override
public void singleClick(MouseEvent e) { //////////////////////////////
JOptionPane.showMessageDialog(null,"Single at " + CLICK_FREQUENCY);
}
@Override
public void doubleClick(MouseEvent e) { //////////////////////////////
JOptionPane.showMessageDialog(null,"Double at " + CLICK_FREQUENCY);
}
@Override
public void tripleClick(MouseEvent e) { //////////////////////////////
JOptionPane.showMessageDialog(null,"Triple at " + CLICK_FREQUENCY);
}
@Override
public void manyClick(MouseEvent e) { //////////////////////////////
JOptionPane.showMessageDialog(null,"Many at " + CLICK_FREQUENCY);
}
@Override
public int getFreq() {
return CLICK_FREQUENCY;
}
};
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.setSize(500, 300);
ch.setBorder(new EtchedBorder());
frame.add(ch);
frame.add(spinner);
frame.setVisible(true);
} // main
}