---
category: swing
folder: SliderWithArrowButtons
title: JSliderの値を増減するJButtonを作成する
tags: [JSlider, Timer, JButton]
author: aterai
pubdate: 2022-05-02T01:15:46+09:00
description: JSliderの値を減少、増加するJButtonを作成してその左右に配置します。
image: https://drive.google.com/uc?id=1xjLVPR8SE7m4MInXokfLDVPG8fBpLEDS
---
* Summary [#summary]
`JSlider`の値を減少、増加する`JButton`を作成してその左右に配置します。
#download(https://drive.google.com/uc?id=1xjLVPR8SE7m4MInXokfLDVPG8fBpLEDS)
* Source Code Examples [#sourcecode]
#code(link){{
JSlider slider = new JSlider(-900, 900, 0);
slider.setMajorTickSpacing(10);
// slider.setPaintTicks(true);
slider.setSnapToTicks(true);
slider.setPaintLabels(true);
updateSliderLabelTable(slider);
JLabel label = new JLabel("100%", SwingConstants.CENTER) {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.width = Math.max(d.width, 32);
return d;
}
};
slider.addChangeListener(e -> {
int iv = slider.getValue();
int pct;
if (iv >= 0) {
pct = 100 + iv;
slider.setMajorTickSpacing(1);
} else {
pct = 100 + iv / 10;
slider.setMajorTickSpacing(10);
}
label.setText(pct + "%");
label.repaint();
});
}}
* Description [#explanation]
* Description [#description]
- `JSlider`の値が`0`の場合は`100%`を表現し、ここが中央になるよう最小値を`-900`、最大値を`900`に設定
-- [[JSliderのノブをダブルクリックして値を初期値にリセットする>Swing/ZoomLevelsSlider]]
-- `JSlider`の値が正の場合は拡大を表現するよう、値を`100 + JSlider#getValue()`パーセントに変換して`JLabel`に表示(最大値は`1000%`になる)
-- `JSlider`の値が負の場合は縮小を表現するよう、値を`100 + JSlider#getValue() / 10`パーセントに変換して`JLabel`に表示(最小値は`10%`になる)
- `JButton`に`ActionListener`ではなく`MouseListener`を追加し、プレスされている間は`Timer`を起動して`JSlider`の値を繰り返し増減する
-- [[JButtonがマウスで押されている間、アクションを繰り返すTimerを設定する>Swing/AutoRepeatTimer]]
-- `JSlider`の値が正で拡大方向の場合はステップ幅を`+10`、負で縮小方向の場合は`-50`で値を変更
#code{{
class AutoRepeatHandler extends MouseAdapter implements ActionListener {
private final Timer autoRepeatTimer;
private final int stepSize;
private final JSlider slider;
private JButton arrowButton;
protected AutoRepeatHandler(int stepSize, JSlider slider) {
super();
this.stepSize = stepSize;
this.slider = slider;
autoRepeatTimer = new Timer(60, this);
autoRepeatTimer.setInitialDelay(300);
}
@Override public void actionPerformed(ActionEvent e) {
Object o = e.getSource();
if (o instanceof Timer) {
boolean isPressed = arrowButton != null && !arrowButton.getModel().isPressed();
if (isPressed && autoRepeatTimer.isRunning()) {
autoRepeatTimer.stop();
arrowButton = null;
}
} else if (o instanceof JButton) {
arrowButton = (JButton) o;
}
int iv = slider.getValue();
int step;
if (iv == 0) {
step = stepSize > 0 ? stepSize * 2 : stepSize * 10;
} else if (iv > 0) {
step = stepSize * 2;
} else {
step = stepSize * 10;
}
slider.setValue(iv + step);
}
@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();
}
}
}
}}
* Reference [#reference]
- [[JSliderのノブをダブルクリックして値を初期値にリセットする>Swing/ZoomLevelsSlider]]
- [[JButtonがマウスで押されている間、アクションを繰り返すTimerを設定する>Swing/AutoRepeatTimer]]
* Comment [#comment]
#comment
#comment