버튼에서 마우스를 누르고있는 동안 지정된 .actionPerformed를 호출하는 JButton 또는 AbstractButton의 하위 클래스를 생성하려고합니다.자바 스윙 보류 버튼
지금까지 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));
}
}
그럼 java.util.Timer 대신 javax.swing.Timer를 사용해야한다고 생각합니다. 그리고 당신은 반복적 인 시간으로 설정해야합니다 (그래서 당신은 자기 자신을 sleep()이라고 부를 필요가 없습니다). javax.swing.Timer의 장점은 일반적으로 Event Dispatch Thread 내에서 작업을 실행한다는 것입니다. 이는 일반적으로 모든 Swing EventListener에 대한 호출에 필요합니다. actionPerformed()가 GUI 구성 요소를 액세스하거나 변경하면 현재 구현에서 actionPerformed _ outside_EDT를 호출합니다. – jfpoilpret