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

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

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

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

Q&A

解決済

2回答

1171閲覧

Java・JLabelの3つの画像変更方法を思いつきましたが全部エラー。。。原因と改善をお願いします。

abe_sinzo

総合スコア12

Java

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

0グッド

0クリップ

投稿2022/04/24 08:19

JLabelで1つディスプレイを用意し、その下に3つのJButtonを用意します。
3つのJButtonにはそれぞれ画像が張り付けてあり、各ボタンを押すと、そのボタンの画像がディスプレイに表示されるというプログラムです。

actionPerformed(ActionEvent e)に画像変更の方法を3つ思い付き、if文で分けて実行してみましたが、どれもうまくいきませんでした。

その3つの案は
1, 新しくJLabelを作り、ディスプレイ用に代入して入れ替える
2, ディスプレイは最初にaddしているので、remove(0)で削除してから新しいLabelをaddする
3, JlabelのsetIconで画像を指定して変更する

それぞれの実行結果は
1, 何も変わらない
2, 画面がバグる(フリーズしてしまう)
イメージ説明
3, 大量のエラー(エラーをみても理由がわかりませんでした)
イメージ説明

この3つの方法がうまくいかない理由と改善案をご教授していただきたいです。よろしくお願いします。

Java

1import java.awt.*; 2import javax.swing.*; 3class ImageDisplayEvt extends JFrame implements ActionListener{ 4 JLabel lb1; 5 JButton bt1,bt2,bt3; 6 ImageIcon img1,img3_base,img4_base; 7 8 public ImageDisplayEvt(String title) { 9 setTitle(title); 10 setLocation(100,100); 11 setSize(640,600); 12 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 13 setLayout(new FlowLayout(FlowLayout.LEFT,20,20)); 14 15 //1枚目(Label) 16 img1=new ImageIcon("img/sakura1.jpg"); 17 int width=img1.getIconWidth(); 18 int height=img1.getIconHeight(); 19 JLabel lb1=new JLabel(new ImageIcon("img/sakura1.jpg")); 20 add(lb1); 21 22 //2枚目(Button1) 23 Image img2=img1.getImage().getScaledInstance((int) (width/(height/100.0)), 24 100, Image.SCALE_SMOOTH); 25 bt1=new JButton(new ImageIcon(img2)); 26 bt1.setPreferredSize(new Dimension((int) (width/(height/100.0)),100)); 27 add(bt1); 28 bt1.addActionListener(this); 29 30 //3枚目(Button2) 31 img3_base=new ImageIcon("img/sakura2.jpg"); 32 Image img3=img3_base.getImage().getScaledInstance( 33 (int) ((img3_base.getIconWidth())/(( img3_base.getIconHeight()/100))), 34 100, Image.SCALE_SMOOTH); 35 bt2=new JButton(new ImageIcon(img3)); 36 bt2.setPreferredSize(new Dimension( 37 (int) ((img3_base.getIconWidth())/(( img3_base.getIconHeight()/100))) 38 ,100)); 39 add(bt2); 40 bt2.addActionListener(this); 41 42 //4枚目(Button3) 43 img4_base=new ImageIcon("img/sakura3.png"); 44 Image img4=img4_base.getImage().getScaledInstance( 45 (int) ((img4_base.getIconWidth()/(img4_base.getIconHeight()/100.0))), 46 100, Image.SCALE_SMOOTH); 47 bt3=new JButton(new ImageIcon(img4)); 48 bt3.setPreferredSize(new Dimension( 49 (int) ((img4_base.getIconWidth()/(img4_base.getIconHeight()/100.0))), 50 100)); 51 add(bt3); 52 bt3.addActionListener(this); 53 54 } 55 56 public static void main(String[] args) { 57 (new ImageDisplayEvt("ImageDisplayEvent")).setVisible(true); 58 } 59 60 public void actionPerformed(ActionEvent e) { 61 if(e.getSource().equals(bt1)) { 62 System.out.println("bt1 was pushed!"); 63 64 JLabel lb2=new JLabel(img3_base); 65 this.lb1=lb2;//エラーはないが画像が変わらない 66 } 67 if(e.getSource().equals(bt2)) { 68 System.out.println("bt2 was pushed!"); 69 70 JLabel lb2=new JLabel(img3_base); 71 remove(0);add(lb2,0);//画面が止まる 72 } 73 if(e.getSource().equals(bt3)) { 74 System.out.println("bt3 was pushed!"); 75 76 this.lb1.setIcon(img4_base);//大量のエラー 77 } 78 } 79} 80

(追記)
それぞれの画像のサイズがバラバラですので、getIconWidth()とgetIconHeight()を用いて、高さが100になるように縮小しています。

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

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

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

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

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

guest

回答2

0

コンストラクタ内で完結するようにすれば、フィールドが無く(or 減ら)せて、代入忘れによるバグが減らせると思います。

java

1import java.awt.BorderLayout; 2import java.awt.Image; 3 4import javax.swing.*; 5 6class ImageDisplayEvt extends JFrame { 7 public static void main(String[] args) { 8 SwingUtilities.invokeLater(() -> new ImageDisplayEvt().setVisible(true)); 9 } 10 11 private static final String[] filenames = { "img/sakura1.png", "img/sakura2.png", "img/sakura3.png" }; 12 13 public ImageDisplayEvt() { 14 setTitle("ImageDisplayEvent"); 15 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 16 17 JLabel display = new JLabel(); 18 add(display, BorderLayout.CENTER); 19 20 JPanel selectPanel = new SelectPanel(filenames, display); 21 add(selectPanel, BorderLayout.SOUTH); 22 23 pack(); 24 setLocationRelativeTo(null); 25 } 26 27 private static class SelectPanel extends JPanel { 28 SelectPanel(String[] filenames, JLabel display) { 29 super(); 30 31 JButton firstButton = null; 32 for(String filename : filenames) { 33 JButton button = createButton(filename, display); 34 if(firstButton == null) firstButton = button; 35 add(button); 36 } 37 firstButton.doClick(); 38 } 39 40 private static JButton createButton(String filename, JLabel display) { 41 ImageIcon imageIcon = new ImageIcon(filename); 42 JButton button = new JButton(createResizeIcon(imageIcon, 100)); 43 button.addActionListener(v -> display.setIcon(imageIcon)); 44 return button; 45 } 46 47 private static ImageIcon createResizeIcon(ImageIcon src, int height) { 48 return new ImageIcon(src.getImage().getScaledInstance( 49 src.getIconWidth() * height / src.getIconHeight(), 50 height, 51 Image.SCALE_SMOOTH)); 52 } 53 } 54}

投稿2022/04/25 19:36

jimbe

総合スコア12648

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

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

0

ベストアンサー

3つの方法がうまくいかない理由と改善案

・ 案1(左側のボタン)
論外です。残念ながら、this.lb1 の値を上書きしただけでは、画面上は何も変化しません。

・ 案2(中央のボタン)
フリーズする理由は、JFrame から直接 remove(0) しているためです。

通常の Container から部品を抜く際は直接 remove(0) すれば良いのですが、JFrame から部品を抜くときだけは、getContentPane().remove(0) とすることになっています。なお、コンポーネント階層の構造を変えた後は、validate() する必要もあります。

Java

1 JLabel lb2 = new JLabel(img3_base); 2 getContentPane().remove(0); 3 add(lb2, 0); 4 validate(); 5 this.lb1 = lb2; // <- 忘れずに

・ 案3(右のボタン)
this.lb1 の初期値が null であるため、NullPointerException が発生しているだけです。コンストラクタの中で、

Java

1 JLabel lb1 = new JLabel(new ImageIcon("img/sakura1.jpg")); 2 add(lb1); 3 this.lb1 = lb1; // <- これが足りない

とでもしておけば良いでしょう。

投稿2022/04/24 10:42

編集2022/04/24 10:53
momodx

総合スコア185

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

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

abe_sinzo

2022/04/24 12:09

lb1の初期値がNullであることに気づけました。大変分かりやすいご説明ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問