Java swingで理想通りのアニメーションが実装できない

java

1package music2;2 3import java.awt.Color;4import java.awt.Graphics;5import java.awt.Graphics2D;6import java.awt.event.ActionEvent;7import java.awt.event.ActionListener;8import java.awt.event.MouseAdapter;9import java.awt.event.MouseEvent;10import java.awt.geom.Ellipse2D;11import java.io.IOException;12import java.net.URL;13 14import javax.sound.sampled.AudioInputStream;15import javax.sound.sampled.AudioSystem;16import javax.sound.sampled.Clip;17import javax.sound.sampled.FloatControl;18import javax.sound.sampled.LineEvent;19import javax.sound.sampled.LineListener;20import javax.sound.sampled.LineUnavailableException;21import javax.sound.sampled.UnsupportedAudioFileException;22import javax.swing.JFrame;23import javax.swing.JLabel;24import javax.swing.JPanel;25import javax.swing.JSlider;26import javax.swing.Timer;27import javax.swing.event.ChangeEvent;28import javax.swing.event.ChangeListener;29 30public class TestFrame extends JFrame implements ChangeListener, LineListener {31 public static void main(String[] args) {32 new TestFrame().setVisible(true);33 }34 35 private JSlider slider;36 private JLabel label;37 private CirclePanel circlePanel;38 private Clip clip;39 private FloatControl gainControl;40 41 TestFrame() {42 super("アプリ");43 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);44 setSize(800, 800);45 46 circlePanel = new CirclePanel();47 setContentPane(circlePanel);48 49 label = new JLabel("test");50 label.setBounds(300, 10, 100, 100);51 add(label);52 53 JLabel label2 = new JLabel("テスト");54 label2.setBounds(300, 500, 100, 100);55 add(label2);56 57 slider = new JSlider(50, 150, 100);58 slider.addChangeListener(this);59 JPanel p = new JPanel();60 p.add(slider);61 p.setBounds(300, 300, 200, 50);62 add(p);63 64 try {65 loadAudioFile("ogawa.wav");66 } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {67 e.printStackTrace();68 }69 }70 71 private void loadAudioFile(String filePath) throws UnsupportedAudioFileException, IOException, LineUnavailableException {72 URL url = getClass().getResource(filePath);73 if (url != null) {74 AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);75 clip = AudioSystem.getClip();76 clip.open(audioInputStream);77 gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);78 clip.addLineListener(this);79 System.err.println("音声ファイルが見つかった: " + filePath);80 } else {81 System.err.println("音声ファイルが見つかりません: " + filePath);82 }83 }84 85 public void stateChanged(ChangeEvent e) {86 label.setText("値:" + slider.getValue());87 circlePanel.setDiameter(slider.getValue());88 float value = (float) slider.getValue() / 100f; // 0.5 ~ 1.5の範囲に正規化89 gainControl.setValue(20f * (float) Math.log10(value)); // 音量の調整90 }91 92 @Override93 public void update(LineEvent event) {94 LineEvent.Type type = event.getType();95 if (type == LineEvent.Type.STOP) {96 circlePanel.setStart(false);97 }98 }99 100 private class CirclePanel extends JPanel {101 private final int X = 350, Y = 250;102 private int diameterOfCircle = 100;103 private Ellipse2D ellipse;104 private boolean start = false;105 private Color ellipseColor = Color.GRAY; // 円の色を保持する変数106 private Timer shakeTimer;107 private int shakeOffset = 0;108 109 private class EllipseClickListener extends MouseAdapter {110 @Override111 public void mouseClicked(MouseEvent e) {112 if (ellipse.contains(e.getPoint())) {113 System.out.println(e.getPoint() + "=図形内");114 if (!start) {115 start = true;116 clip.start();117 setEllipseColor(Color.CYAN); // 円の色を水色に変更118 startShaking();119 System.out.println(start);120 } else {121 start = false;122 clip.stop();123 setEllipseColor(Color.LIGHT_GRAY);124 stopShaking();125 System.out.println(start);126 }127 } else {128 System.out.println(e.getPoint() + "=図形外");129 }130 }131 }132 133 void setEllipseColor(Color color) {134 this.ellipseColor = color;135 repaint();136 }137 138 CirclePanel() {139 super(null);140 setBackground(Color.WHITE);141 addMouseListener(new EllipseClickListener());142 initShakeTimer();143 setEllipseColor(Color.LIGHT_GRAY);144 }145 146 void setDiameter(int diameter) {147 this.diameterOfCircle = diameter;148 repaint();149 }150 151 void setStart(boolean start) {152 this.start = start;153 }154 155 private void initShakeTimer() {156 shakeTimer = new Timer(50, new ActionListener() {157 @Override158 public void actionPerformed(ActionEvent e) {159 shakeOffset = (shakeOffset == 0) ? 5 : 0;160 repaint();161 }162 });163 }164 165 private void startShaking() {166 shakeTimer.start();167 }168 169 private void stopShaking() {170 shakeTimer.stop();171 shakeOffset = 0;172 repaint();173 }174 175 @Override176 protected void paintComponent(Graphics g) {177 super.paintComponent(g);178 Graphics2D g2 = (Graphics2D) g;179 g2.setColor(ellipseColor); // 円の色を設定180 ellipse = new Ellipse2D.Double(X - diameterOfCircle / 2 + shakeOffset, Y - diameterOfCircle / 2, diameterOfCircle, diameterOfCircle);181 g2.fill(ellipse);182 183 // ぼうっと光った楕円形の水玉模様を描画184 int spotWidth = diameterOfCircle / 3; // 横幅は外側の円の1/3185 int spotHeight = spotWidth / 2; // 縦幅は横幅の半分186 int spotX = X - diameterOfCircle / 4 + shakeOffset; // 円の中心から1/4の距離に配置187 int spotY = Y - diameterOfCircle / 4;188 Ellipse2D spot = new Ellipse2D.Double(spotX, spotY, spotWidth, spotHeight);189 190 // 水玉模様にぼけ効果を追加191 g2.setColor(new Color(255, 255, 255, 128)); // 半透明の白色192 g2.fill(spot);193 g2.setColor(new Color(255, 255, 255, 255)); // 完全な白色194 g2.fillOval(spotX + spotWidth / 4, spotY, spotWidth / 2, spotHeight);195 }196 }197}

コメントを投稿

0 コメント