---
category: swing
folder: AutoRepeatTimer
title: JButtonがマウスで押されている間、アクションを繰り返すTimerを設定する
tags: [JButton, ActionListener, MouseListener, Timer]
author: aterai
pubdate: 2015-06-08T00:00:32+09:00
description: JButtonがマウスで押されている間は指定したアクションを繰り返し実行するTimerを設定します。
image: https://lh3.googleusercontent.com/-zp2-TOEE4JE/VXRXk25rFUI/AAAAAAAAN6I/_Kn4GsC9a1g/s800/AutoRepeatTimer.png
---
* 概要 [#summary]
`JButton`がマウスで押されている間は指定したアクションを繰り返し実行する`Timer`を設定します。

#download(https://lh3.googleusercontent.com/-zp2-TOEE4JE/VXRXk25rFUI/AAAAAAAAN6I/_Kn4GsC9a1g/s800/AutoRepeatTimer.png)

* サンプルコード [#sourcecode]
#code(link){{
class AutoRepeatHandler extends MouseAdapter implements ActionListener {
  private final Timer autoRepeatTimer;
  private final BigInteger extent;
  private final JTextComponent view;
  private JButton arrowButton;

  protected AutoRepeatHandler(int extent, JTextComponent view) {
    super();
    this.extent = BigInteger.valueOf(extent);
    this.view = view;
    autoRepeatTimer = new Timer(60, this);
    autoRepeatTimer.setInitialDelay(300);
  }

  @Override public void actionPerformed(ActionEvent e) {
    Object o = e.getSource();
    if (o instanceof Timer) {
      boolean released= arrowButton != null && !arrowButton.getModel().isPressed();
      if (released && autoRepeatTimer.isRunning()) {
        autoRepeatTimer.stop();
        // arrowButton = null;
      }
    } else if (o instanceof JButton) {
      arrowButton = (JButton) o;
    }
    BigInteger i = new BigInteger(view.getText());
    view.setText(i.add(extent).toString());
  }

  @Override public void mousePressed(MouseEvent e) {
    if (SwingUtilities.isLeftMouseButton(e) && e.getComponent().isEnabled()) {
      autoRepeatTimer.start();
    }
  }

  @Override public void mouseReleased(MouseEvent e) {
    autoRepeatTimer.stop();
    arrowButton = null;
  }

  @Override public void mouseExited(MouseEvent e) {
    if (autoRepeatTimer.isRunning()) {
      autoRepeatTimer.stop();
    }
  }
}
}}

* 解説 [#explanation]
上記のサンプルでは、`JButton`をクリックすると編集不可の`JTextField`に表示される数値を増減する`ActionListener`と、`JButton`が押されている間はこのアクションを自動的にリピートする`Timer`を起動するための`MouseListener`のふたつのリスナーを設定しています。

- `JSpinner`で使用されている`javax.swing.plaf.basic.BasicSpinnerUI`内の`ArrowButtonHandler`と、このサンプルで使用している`Timer`のリピート間隔(`60ms`)や初回起動までの時間(`300ms`)は同じ値を使用している

* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/plaf/basic/BasicSpinnerUI.html BasicSpinnerUI (Java Platform SE 8)]
- [[JSliderの値を増減するJButtonを作成する>Swing/SliderWithArrowButtons]]
- [[JTabbedPaneのタブスクロールボタンで連続スクロールを実行する>Swing/ScrollTabsActionRepeater]]
- [https://github.com/openjdk/jdk/blob/master/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java at master · openjdk/jdk]

* コメント [#comment]
#comment
#comment