実現したいこと
java swingでアプリを作っているのですが、slider.getValue()というスライダーの値に応じて画像とgifの大きさが画像の比率を保ったまま変化するようにしたいです。
(slider.getValue()の値が大きくなれば画像とgifの大きさも比率を保ったまま大きくなるし、slider.getValue()の値が小さくなれば画像とgifの大きさも比率を保ったままそれに応じて小さくなるという具合です)
元々は、circlePanel.setDiameter(slider.getValue());という部分で、スライダーの値に合わせてパネルの大きさも変動していたのですが、中身を画像やgifに変えたため効かなくなりました。
よろしくお願いします。
該当のソースコード
java
1package music2; 2 3import java.awt.Color; 4import java.awt.event.ActionEvent; 5import java.awt.event.ActionListener; 6import java.awt.event.MouseAdapter; 7import java.awt.event.MouseEvent; 8import java.io.IOException; 9import java.net.URL; 10 11import javax.sound.sampled.AudioInputStream; 12import javax.sound.sampled.AudioSystem; 13import javax.sound.sampled.Clip; 14import javax.sound.sampled.FloatControl; 15import javax.sound.sampled.LineEvent; 16import javax.sound.sampled.LineListener; 17import javax.sound.sampled.LineUnavailableException; 18import javax.sound.sampled.UnsupportedAudioFileException; 19import javax.swing.Icon; 20import javax.swing.ImageIcon; 21import javax.swing.JFrame; 22import javax.swing.JLabel; 23import javax.swing.JPanel; 24import javax.swing.JSlider; 25import javax.swing.Timer; 26import javax.swing.event.ChangeEvent; 27import javax.swing.event.ChangeListener; 28 29public class TestFrame extends JFrame implements ChangeListener, LineListener { 30 public static void main(String[] args) { 31 new TestFrame().setVisible(true); 32 } 33 34 private JSlider slider; 35 private JLabel label; 36 private CirclePanel circlePanel; 37 private Clip clip; 38 private FloatControl gainControl; 39 40 TestFrame() { 41 super("アプリ"); 42 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 43 setSize(800, 800); 44 45 circlePanel = new CirclePanel(); 46 setContentPane(circlePanel); 47 48 label = new JLabel("test"); 49 label.setBounds(300, 10, 100, 100); 50 add(label); 51 52 JLabel label2 = new JLabel("テスト"); 53 label2.setBounds(300, 500, 100, 100); 54 add(label2); 55 56 slider = new JSlider(50, 150, 100); 57 slider.addChangeListener(this); 58 JPanel p = new JPanel(); 59 p.add(slider); 60 p.setBounds(300, 600, 200, 50); 61 add(p); 62 63 try { 64 loadAudioFile("ogawa.wav"); 65 } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) { 66 e.printStackTrace(); 67 } 68 } 69 70 private void loadAudioFile(String filePath) throws UnsupportedAudioFileException, IOException, LineUnavailableException { 71 URL url = getClass().getResource(filePath); 72 if (url != null) { 73 AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url); 74 clip = AudioSystem.getClip(); 75 clip.open(audioInputStream); 76 gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); 77 clip.addLineListener(this); 78 System.err.println("音声ファイルが見つかった: " + filePath); 79 } else { 80 System.err.println("音声ファイルが見つかりません: " + filePath); 81 } 82 } 83 84 public void stateChanged(ChangeEvent e) { 85 label.setText("値:" + slider.getValue()); 86 circlePanel.setDiameter(slider.getValue()); 87 float value = (float) slider.getValue() / 100f; // 0.5 ~ 1.5の範囲に正規化 88 gainControl.setValue(20f * (float) Math.log10(value)); // 音量の調整 89 } 90 91 @Override 92 public void update(LineEvent event) { 93 LineEvent.Type type = event.getType(); 94 if (type == LineEvent.Type.STOP) { 95 circlePanel.setStart(false); 96 } 97 } 98 99 private class CirclePanel extends JPanel { 100 private final int X = 350, Y = 250; 101 private int diameterOfCircle = 100; 102 private boolean start = false; 103 private Timer shakeTimer; 104 private int shakeOffset = 0; 105 private ImageIcon gifIcon, tamaIcon; 106 private JLabel imageLabel; 107 108 private class EllipseClickListener extends MouseAdapter { 109 @Override 110 public void mouseClicked(MouseEvent e) { 111 if (imageLabel.getBounds().contains(e.getPoint())) { 112 System.out.println(e.getPoint() + "=図形内"); 113 if (!start) { 114 start = true; 115 clip.start(); 116 startShaking(); 117 showGifAnimation(); 118 System.out.println(start); 119 } else { 120 start = false; 121 clip.stop(); 122 stopShaking(); 123 hideGifAnimation(); 124 System.out.println(start); 125 } 126 } else { 127 System.out.println(e.getPoint() + "=図形外"); 128 } 129 } 130 } 131 132 CirclePanel() { 133 super(null); 134 setBackground(Color.WHITE); 135 addMouseListener(new EllipseClickListener()); 136 initShakeTimer(); 137 138 // Load images 139 try { 140 URL tamaURL = getClass().getResource("tama.png"); 141 if (tamaURL != null) { 142 tamaIcon = new ImageIcon(tamaURL); 143 } else { 144 System.err.println("画像ファイルが見つかりません: tama.png"); 145 } 146 147 URL gifURL = getClass().getResource("purupuru.gif"); 148 if (gifURL != null) { 149 gifIcon = new ImageIcon(gifURL); 150 } else { 151 System.err.println("GIFファイルが見つかりません: purupuru.gif"); 152 } 153 154 imageLabel = new JLabel(tamaIcon); 155 add(imageLabel); 156 setImageLabelBounds(tamaIcon); // imageLabelの追加後に呼び出す 157 } catch (Exception e) { 158 e.printStackTrace(); 159 } 160 } 161 162 void setDiameter(int diameter) { 163 this.diameterOfCircle = diameter; 164 if (imageLabel != null) { 165 setImageLabelBounds(imageLabel.getIcon()); 166 } 167 repaint(); 168 } 169 void setStart(boolean start) { 170 this.start = start; 171 } 172 173 private void initShakeTimer() { 174 shakeTimer = new Timer(50, new ActionListener() { 175 @Override 176 public void actionPerformed(ActionEvent e) { 177 shakeOffset = (shakeOffset == 0) ? 5 : 0; 178 imageLabel.setLocation(X - imageLabel.getWidth() / 2 + shakeOffset, Y - imageLabel.getHeight() / 2); 179 } 180 }); 181 } 182 183 private void startShaking() { 184 shakeTimer.start(); 185 } 186 187 private void stopShaking() { 188 shakeTimer.stop(); 189 shakeOffset = 0; 190 imageLabel.setLocation(X - imageLabel.getWidth() / 2, Y - imageLabel.getHeight() / 2); 191 } 192 193 private void showGifAnimation() { 194 if (gifIcon != null && imageLabel != null) { 195 imageLabel.setIcon(gifIcon); 196 setImageLabelBounds(gifIcon); // ImageIcon は Icon のサブクラスなので渡せる 197 } 198 } 199 private void hideGifAnimation() { 200 if (tamaIcon != null && imageLabel != null) { 201 imageLabel.setIcon(tamaIcon); 202 setImageLabelBounds(tamaIcon); // ImageIcon は Icon のサブクラスなので渡せる 203 } 204 } 205 206 private void setImageLabelBounds(Icon icon) { 207 if (imageLabel != null && icon != null) { 208 int width = icon.getIconWidth(); 209 int height = icon.getIconHeight(); 210 imageLabel.setBounds(X - width / 2, Y - height / 2, width, height); 211 } 212 } 213 } 214}
試したこと
文字制限で書ききれませんが、下記のようにsetImageLabelBounds(Icon icon)を触って何とかしようと試みましたが、そうすると初期状態で画像が表示されなくなったり、画像やgifの一部しか表示されなくなったりしたため断念しました。
java
1private void setImageLabelBounds(Icon icon) { 2 if (imageLabel != null && icon != null) { 3 ImageIcon imageIcon = (ImageIcon) icon; 4 int originalWidth = imageIcon.getIconWidth(); 5 int originalHeight = imageIcon.getIconHeight(); 6 7 // スライダーの値に基づいて画像の幅を変更 8 int newWidth = (int) (diameterOfCircle * ((double) originalWidth / originalHeight)); 9 10 // 新しい幅が画面外に出ないように調整 11 if (newWidth > getWidth()) { 12 newWidth = getWidth(); 13 } 14 15 // 高さを新しい幅に基づいて変更してアスペクト比を保つ 16 int newHeight = (int) (newWidth * ((double) originalHeight / originalWidth)); 17 18 // 新しい幅と高さで imageLabel の位置を設定 19 int x = X - newWidth / 2; 20 int y = Y - newHeight / 2; 21 imageLabel.setBounds(x, y, newWidth, newHeight); 22 } 23}
![guest](/img/icon/icnUserSample.jpg)
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/05/22 01:22
2024/05/24 13:28