我想创建一个JButton或AbstractButton的子类,只要鼠标按在按钮上,它将调用指定的.actionPerformed。爪哇秋千按钮
到目前为止,我正在考虑扩展JButton,在创建时(在构造函数中)添加一个鼠标监听器,并在鼠标关闭时调用actionPerformed。到目前为止,我提出了这个问题,但如果我在正确的轨道上,并且如果这样的话,我正在怀疑如何正确实施“按下”逻辑。
package components;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
public class HoldButton extends JButton {
private class HeldDownMouseListener implements MouseListener {
private boolean mouseIsHeldDown;
private HoldButton button;
private long millis;
public HeldDownMouseListener(HoldButton button, long millis) {
this.button = button;
this.millis = millis;
}
@Override
public void mouseClicked(MouseEvent arg0) { }
@Override
public void mouseEntered(MouseEvent arg0) { }
@Override
public void mouseExited(MouseEvent arg0) { }
@Override
public void mousePressed(MouseEvent arg0) {
mouseIsHeldDown = true;
// This should be run in a sub thread?
// while (mouseIsHeldDown) {
// button.fireActionPerformed(new ActionEvent(button, ActionEvent.ACTION_PERFORMED, "heldDown"));
// try {
// Thread.sleep(millis);
// } catch (InterruptedException e) {
// e.printStackTrace();
// continue;
// }
// }
}
@Override
public void mouseReleased(MouseEvent arg0) {
mouseIsHeldDown = false;
}
}
public HoldButton() {
addHeldDownMouseListener();
}
public HoldButton(Icon icon) {
super(icon);
addHeldDownMouseListener();
}
public HoldButton(String text) {
super(text);
addHeldDownMouseListener();
}
public HoldButton(Action a) {
super(a);
addHeldDownMouseListener();
}
private void addHeldDownMouseListener() {
addMouseListener(new HeldDownMouseListener(this, 300));
}
}
非常感谢您的时间。
编辑:选择我想出了一个工作实现定时器方法:
package components;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
public class HoldButton extends JButton {
private static final long serialVersionUID = 1L;
public static final long CLICK_LAG = 300;
public static final long INITIAL_FIRE_DELAY = 500;
public static final double FIRE_DELAY_STEP_MULTIPLIER = 25;
public static final long MIN_FIRE_DELAY = 100;
private class HeldDownMouseListener implements MouseListener {
private class HeldDownCheckerTask extends TimerTask {
private HeldDownMouseListener listener;
public HeldDownCheckerTask(HeldDownMouseListener listener) {
this.listener = listener;
}
@Override
public void run() {
long delay = INITIAL_FIRE_DELAY;
while (listener.isMouseHeldDownOnButton()) {
listener.fireMouseHeldDown();
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (delay > MIN_FIRE_DELAY) {
final long decrease = Math.round(FIRE_DELAY_STEP_MULTIPLIER * Math.pow(INITIAL_FIRE_DELAY/delay, 2));
delay = Math.max(delay - decrease, MIN_FIRE_DELAY);
}
}
}
}
private boolean mouseIsHeldDown;
private boolean mouseIsOnButton;
private HoldButton button;
private Timer timer;
public HeldDownMouseListener(HoldButton button) {
this.button = button;
}
public boolean isMouseHeldDownOnButton() {
return mouseIsHeldDown && mouseIsOnButton;
}
private void cancelTimer() {
if (timer != null) {
timer.cancel();
timer = null;
}
}
private void fireMouseHeldDown() {
button.fireActionPerformed(new ActionEvent(button, ActionEvent.ACTION_PERFORMED, "heldDown"));
}
@Override
public void mouseClicked(MouseEvent arg0) {
cancelTimer();
}
@Override
public void mouseEntered(MouseEvent arg0) {
mouseIsOnButton = true;
}
@Override
public void mouseExited(MouseEvent arg0) {
mouseIsOnButton = false;
}
@Override
public void mousePressed(MouseEvent arg0) {
cancelTimer();
mouseIsHeldDown = true;
timer = new Timer();
timer.schedule(new HeldDownCheckerTask(this), CLICK_LAG);
}
@Override
public void mouseReleased(MouseEvent arg0) {
mouseIsHeldDown = false;
}
}
public HoldButton() {
addHeldDownMouseListener();
}
public HoldButton(Icon icon) {
super(icon);
addHeldDownMouseListener();
}
public HoldButton(String text) {
super(text);
addHeldDownMouseListener();
}
public HoldButton(Action a) {
super(a);
addHeldDownMouseListener();
}
private void addHeldDownMouseListener() {
addMouseListener(new HeldDownMouseListener(this));
}
}
嗯,我想你应该使用javax.swing.Timer而不是java.util.Timer。你应该把它设置为一个重复的时间(所以你不必自己调用sleep())。 javax.swing.Timer的优点是它将始终在Event Dispatch Thread内运行您的任务,这通常是对任何Swing EventListener的调用所期望的。 如果actionPerformed()访问或更改GUI组件,您当前的实现将调用actionPerformed _outside_ EDT。 – jfpoilpret 2010-04-07 07:35:05