我想創建一個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