質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.40%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

解決済

1回答

367閲覧

java swing スライダーの値に合わせて、画像とgifが縦横比を保ったままリサイズするようにしたい

ikigamikita

総合スコア20

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

1グッド

0クリップ

投稿2024/05/21 05:53

編集2024/05/21 06:28

実現したいこと

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}
TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

以前の質問の回答を組み込みました。

java

1package music2; 2 3import javax.sound.sampled.*; 4import javax.swing.*; 5import javax.swing.event.ChangeEvent; 6import javax.swing.event.ChangeListener; 7import java.awt.*; 8import java.net.URL; 9import java.util.Objects; 10 11 12public class TestPanel extends JPanel implements ChangeListener, LineListener { 13 public static void main(String[] args) { 14 JFrame frame = new JFrame("アプリ"); 15 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 16 frame.setResizable(false); 17 frame.add(new TestPanel()); 18 frame.pack(); 19 frame.setLocationRelativeTo(null); 20 frame.setVisible(true); 21 } 22 23 private final JSlider slider; 24 private final JLabel label; 25 private final JToggleButton toggleButton; 26 private Clip clip; 27 private FloatControl gainControl; 28 29 TestPanel() { 30 setPreferredSize(new Dimension(800, 800)); 31 setBackground(Color.WHITE); 32 setLayout(null); 33 34 label = new JLabel("test"); 35 label.setBounds(300, 10, 100, 100); 36 add(label); 37 38 JLabel label2 = new JLabel("テスト"); 39 label2.setBounds(300, 500, 100, 100); 40 add(label2); 41 42 toggleButton = new PurupuruButton(); 43 toggleButton.setBounds(325, 195, 150, 150); 44 try { 45 URL url = getClass().getResource("tama.png"); 46 toggleButton.setIcon(new ImageIcon(Objects.requireNonNull(url))); 47 } catch (Exception e) { 48 System.err.println("画像ファイルが見つかりません: tama.png"); 49 } 50 try { 51 URL url = getClass().getResource("purupuru.gif"); 52 toggleButton.setSelectedIcon(new ImageIcon(Objects.requireNonNull(url))); 53 } catch (Exception e) { 54 System.err.println("画像ファイルが見つかりません: purupuru.gif"); 55 } 56 // sliderもChangeListenerなのでこっちは匿名クラスで 57 toggleButton.addChangeListener(new ChangeListener() { 58 @Override public void stateChanged(ChangeEvent e) { 59 if (toggleButton.isSelected()) clip.loop(1); 60 else clip.stop(); 61 } 62 }); 63// ラムダの場合(↑と同じ意味) 64// toggleButton.addChangeListener(e -> { 65// if (toggleButton.isSelected()) clip.loop(1); 66// else clip.stop(); 67// }); 68 add(toggleButton); 69 70 slider = new JSlider(50, 150, 100); 71 slider.setBounds(300, 600, 200, 50); 72 slider.addChangeListener(this); 73 add(slider); 74 75 try { 76 URL url = getClass().getResource("ogawa.wav"); 77 AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(Objects.requireNonNull(url)); 78 79 clip = AudioSystem.getClip(); 80 clip.open(audioInputStream); 81 clip.addLineListener(this); 82 83 gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); 84 } catch (Exception e) { 85 System.err.println("音声ファイルが見つかりません: gawa.wav"); 86 } 87 } 88 89 @Override public void stateChanged(ChangeEvent e) { 90 label.setText("値:" + slider.getValue()); 91 float value = (float) slider.getValue() / 100f; 92 gainControl.setValue(20f * (float) Math.log10(value)); 93 94 // 倍率(value)を乗じて拡縮(アス比固定) 95 int width = (int) (toggleButton.getIcon().getIconWidth() * value); 96 int height = (int) (toggleButton.getIcon().getIconHeight() * value); 97 int x = (getWidth() - width) / 2; // 左右中央 98 int y = (getHeight() - height) / 2 - 130; // 上下中央チョイ上(130はテキトウ 99 toggleButton.setBounds(x, y, width, height); 100 } 101 102 @Override public void update(LineEvent event) { 103 if (event.getType() == LineEvent.Type.STOP) { 104 toggleButton.setSelected(false); 105 } 106 } 107 108 // 画像を自身のサイズに合わせるトグルボタン(IconはImageIconだという前提) 109 private static class PurupuruButton extends JToggleButton { 110 public PurupuruButton() { 111 setContentAreaFilled(false); 112 setBorderPainted(false); 113 setFocusPainted(false); 114 } 115 116 @Override protected void paintComponent(Graphics g) { 117 super.paintComponent(g); 118 119 // ImageIconを取得(IconはImageIconだという前提) 120 ImageIcon icon = (ImageIcon) (isSelected() ? getSelectedIcon() : getIcon()); 121 122 // ImageIconを自分のサイズに合わせて描画 123 g.drawImage(icon.getImage(), 0, 0, getWidth(), getHeight(), null); 124 } 125 } 126}

アプリ動画

投稿2024/05/21 14:36

編集2024/05/24 15:24
TN8001

総合スコア9640

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikigamikita

2024/05/22 01:22

ありがとうございます!
ikigamikita

2024/05/24 13:28

ご対応頂き感謝致します!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.40%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問