JToggleButtonに回転アニメーション付き展開・折り畳みIconを設定する
Total: 19, Today: 19, Yesterday: 0
Posted by aterai at
Last-modified:
Summary
JToggleButtonに選択するとアニメーション効果付きで時計回りに90度回転、選択解除で-90度回転して元の0度に戻る展開・折り畳みIconを設定します。
Screenshot

Advertisement
Source Code Examples
class AnimatableIcon implements Icon {
private final Icon icon;
private final Timer timer = new Timer(15, null);
private double currentAngle;
private double targetAngle;
private Component parent;
protected AnimatableIcon(Icon icon, Component parent) {
this.icon = icon;
this.parent = parent;
double step = .5;
this.timer.addActionListener(e -> {
double diff = targetAngle - currentAngle;
if (Math.abs(diff) < step) {
currentAngle = targetAngle;
timer.stop();
} else {
currentAngle += diff * step;
}
Optional.ofNullable(this.parent).ifPresent(Component::repaint);
});
}
public void animateTo(double angle) {
this.targetAngle = angle;
if (!timer.isRunning()) {
timer.start();
}
}
@Override public void paintIcon(Component c, Graphics g, int x, int y) {
if (this.parent == null) {
this.parent = c;
}
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int cx = x + icon.getIconWidth() / 2;
int cy = y + icon.getIconHeight() / 2;
g2.rotate(Math.toRadians(currentAngle), cx, cy);
icon.paintIcon(c, g2, x, y);
g2.dispose();
}
@Override public int getIconWidth() {
return icon.getIconWidth();
}
@Override public int getIconHeight() {
return icon.getIconHeight();
}
}
View in GitHub: Java, KotlinDescription
- 折り畳み状態の右矢印アイコンは
Menu.arrowIconを使用 - アコーディオンパネルはJPanelをアコーディオン風に展開のタイトル部分を
JLabelからBoxLayoutを設定したJButtonに変更して使用JButtonの子要素として左端にタイトル文字列表示用のJLabel、右端に展開・折り畳みIconを設定したJToggleButtonを配置
JButton、またはその子要素のJToggleButtonがクリックされたらアコーディオンパネルの展開・折り畳みと合わせて展開・折り畳みIconの回転角度を設定してアニメーションを開始- 回転アニメーション用の
Timerは各Icon毎に作成して使用
- 回転アニメーション用の
private void rotate(AnimatableIcon animeIcon) {
if (toggleButton.isSelected()) {
animeIcon.animateTo(90d);
panel.setVisible(true);
} else {
animeIcon.animateTo(0d);
panel.setVisible(false);
}
revalidate();
EventQueue.invokeLater(() -> panel.scrollRectToVisible(panel.getBounds()));
}