🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Java

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

Swing

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

Q&A

解決済

1回答

5108閲覧

Java Swing 画像変更が上手く行えない

ponzu7080

総合スコア7

Java

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

Swing

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

0グッド

0クリップ

投稿2019/11/09 08:40

前提・実現したいこと

Java Swingを用いて一定回数(設定値のカウント)を超えたときに画像が変更されるようにしたい。

Java SwingでButtonクラス、Mainクラスの2種類を用いて、ボタンコマンド(今回は愛でる)を10回押すと画像が変更されるようにしたいのですが、全然画像が変わらなく全くどうすればいいのかわからないです。独学なため何が足りないとかあれば教えてほしいです。

発生している問題・エラーメッセージ

画像が切り替わらない。

エラーメッセージ ```エラーは発生しない。 ### 該当のソースコード Mainクラスは以下 import java.awt.BorderLayout; import java.awt.Container; import java.awt.image.BufferedImage; import java.awt.event.*; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; public class Main{ public static void main(String[]args){ Button a=new Button(); JFrame frame=new JFrame("イカちゃん"); frame.setSize(700,460);//一つ目が横 二つ目が縦の画面サイズ 単位はピクセル frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// xボタンを押したときの動作。今回は閉じる。 Container contentPane=frame.getContentPane();//合紙のようなもので、白い部分を表示させている。 JLabel label=new JLabel("イカちゃんを愛でよう!あ、拡大はしないで欲しいでゲソ");//文字列 label.setHorizontalAlignment(JLabel.CENTER);//文字列を中央に表示 JButton button=new JButton("愛でる");//ボタン ImageIcon icon=new ImageIcon("C:/イカ愛で/img1.png");//\の所は/でも動く JLabel picture=new JLabel(icon);//画像 contentPane.add(picture,BorderLayout.CENTER);//画像の貼り付け contentPane.add(label,BorderLayout.NORTH);//文字列の貼り付け contentPane.add(button,BorderLayout.SOUTH);//ボタンの貼り付け frame.setVisible(true);//ウィンドウを可視化。 } } Buttonクラスは以下の通り import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JFrame; import java.awt.Container; import java.awt.BorderLayout; import java.awt.event.*; public class Button extends JFrame implements ActionListener{ private int jbuttoncount=10; int count=0; public int getJbuttoncount(){return this.jbuttoncount;} public void setjbuttoncount(int jbuttoncount){this.jbuttoncount=jbuttoncount;} JLabel label; Button(){ this.count++; ImageIcon icon=new ImageIcon("C:/イカ愛で/img1.png"); JLabel label=new JLabel(icon); } public void actionPerformed(ActionEvent e){ if(this.jbuttoncount<this.count){ ImageIcon icon=new ImageIcon("C:/イカ愛で/img4.png"); JLabel label=new JLabel(icon); Container contentPane=new Container(); contentPane.add(label,BorderLayout.CENTER);//画像の貼り付け } } } ```ここに言語名を入力 Java

試したこと

if構文やオブジェクト指向などを用いてMainクラスと分け、画像が変わるようにした。

補足情報(FW/ツールのバージョンなど)

jdk-12.0.1

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

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

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

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

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

jimbe

2019/11/09 16:23

コードは, ファイル毎に, ```の行で挟む形にして頂けると, 専用の枠にインデント付きで表示されます.
guest

回答1

0

ベストアンサー

ActionListener を実装している Button のインスタンス a が, JButton のインスタンス button に登録されていないようです.

他にも...
Button クラスは JFrame としては機能させていませんので extends JFrame は無駄です.
Button クラスのコンストラクタでのみ count を加算していては何時までたっても 10 にはなりません.
同じくコンストラクタで, img1.png のラベルを生成しても使われておりません.
actionPerformed 内で, Container contentPane=new Container(); としても, JFrame の contentPane とは無関係ですので, 何の操作をしても意味はありません.

java

1import java.awt.BorderLayout; 2import java.awt.event.ActionEvent; 3import java.awt.event.ActionListener; 4 5import javax.swing.Icon; 6import javax.swing.ImageIcon; 7import javax.swing.JButton; 8import javax.swing.JFrame; 9import javax.swing.JLabel; 10 11public class LoveSquid extends JFrame { 12 public static void main(String[] args) { 13 new LoveSquid().setVisible(true); 14 } 15 LoveSquid() { 16 super("イカちゃん"); 17 setSize(700,460); 18 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 20 JLabel label = new JLabel("イカちゃんを愛でよう!あ、拡大はしないで欲しいでゲソ"); 21 label.setHorizontalAlignment(JLabel.CENTER); 22 add(label,BorderLayout.NORTH); 23 24 ImageIcon icon1 = new ImageIcon("C:/イカ愛で/img1.png"); 25 JLabel picture = new JLabel(icon1); 26 add(picture,BorderLayout.CENTER); 27 28 JButton button = new JButton("愛でる"); 29 ImageIcon icon4 = new ImageIcon("C:/イカ愛で/img4.png"); 30 button.addActionListener(new LoveActionListener(picture, 10, icon4)); 31 add(button,BorderLayout.SOUTH); 32 } 33 static class LoveActionListener implements ActionListener { 34 private JLabel label; 35 private int countMax; 36 private Icon icon; 37 private int count = 0; 38 LoveActionListener(JLabel label, int countMax, Icon icon) { 39 this.label = label; 40 this.countMax = countMax; 41 this.icon = icon; 42 } 43 public void actionPerformed(ActionEvent e) { 44 if(++count >= countMax) { 45 label.setIcon(icon); 46 } 47 } 48 } 49}

投稿2019/11/09 16:27

編集2019/11/09 17:20
jimbe

総合スコア13202

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

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

ponzu7080

2019/11/10 13:30

回答ありがとうございます。続けて質問で申し訳ないのですが、Mainクラスの修正は大丈夫なのでしょうか?また後に追加するコマンドを増やしていきたいので、Mainクラスと分けたのですが分ける必要は特になかったのでしょうか? 以下ソースコードについて。 15行目のnew LoveSquid().setVisibleの役割は理解できるのですが、newの部分が全くわからないです。 LoveSquidのsuperでアクセスしているのが、なんでそうなるんだ?となってしまいました... よければご享受お願いします。
jimbe

2019/11/10 15:33

> Mainクラスの修正は大丈夫なのでしょうか? 「Mainクラスの修正」とはどういうことを指していらっしゃるのかが分かりません. Main クラスでなく LoveSquid クラスとしましたのは, 名称はなるべくそのモノを示すものにしたほうが良いと思うためです. > 後に追加するコマンドを増やしていきたい 「愛でる」ボタンの機能は LoveActionListener が行っていますが, どの処理をどこで行うかは, 機能を増やすに従って変更していくことになります. 最初から「何があっても, 何でも出来るように」しようとしても無理ですので, テキトウな所で切り上げて, 後のことは後に考えることにすると良いかと思います. その過程で, オブジェクトとしてどう切り分けると分かり易いか等を考えていきます. > new LoveSquid().setVisibleの役割は理解できるのですが、newの部分が全くわからないです。 これは, LoveSquid のインスタンスを生成する部分と, そのインスタンスの setVisible を呼ぶ部分を(手をぬいて)まとめているだけです. LoveSquid a = new LoveSquid(); a.setVisible(true); と書いても良いのですが, a を別に使うことはありませんので, 「生成して表示するだけ」を表現する意味もあります. > LoveSquidのsuperでアクセスしている super("イカちゃん"); でしょうか? LovSquid は JFrame ですので, super で JFrame のコンストラクタを呼んでいます.
ponzu7080

2019/11/11 08:05

自分は上記の通り2つクラスを作成し、MainクラスとButtonクラスに分けたのですが、jimbeさんはクラスを纏めてやっていらっしゃったので、分ける必要はなかったのかな?ということです。解りづらくてすいません。 後に追加するコマンドについての解答ありがとうこざいます。例えば、ボタンを押したときにハートのアニメーションが発生するようにしたい場合なども、それに合わせてコードも変わっていくということなんですね。 質問回答ありがとうございます。new のところ完全に理解できました。 super("イカちゃん");の所で大丈夫です。superでアクセスし、タイトルを呼び出しているということで大丈夫でしょうか? 重ね重ね質問失礼いたします。
jimbe

2019/11/11 08:47

> 分ける必要はなかったのかな?ということです 私のコードも LoveSquid と LoveActionListener の2つのクラスですし, LoveActionListener は static ですので LoveSquid とは独立しています. LoveSquid の中に LoveActionListener を入れましたのは, 2つ合わせてもファイルとして分ける程のコード量では無いことと, LoveActionListener は (今の所)"愛でる" ボタンの処理のみを担当しており, クラスとして独立しているとは言え LoveSquid からのみ使用するからです. ハートが出るボタンを追加すると, 恐らく HeartActionListener を作ることになるのではないかと思います. もし HeartActionListener と LoveActionListener で共通の処理や変数があれば, それを別クラスとして抜き出して両リスナから使ったり, または両リスナの親クラスを作ってそこに入れたりとなります. static "では無い" 内部クラスであれば, 外側のクラスのメソッド/変数を使えますので, それを使うことも出来ますが, そうすると少々分かり難くなりますので程々に…ですね. > superでアクセスし、タイトルを呼び出している タイトルを設定している, です.
ponzu7080

2019/11/12 04:21

何度も親切丁寧に解答をくださりありがとうございます。 分ける必要なかったのか、の解答理解できました。てっきり一つのクラス内に纏めて書いてあるから、クラスを分けていないと考えていましたが、staticですから分けてありますしね。 HeartActionListenerを作るとなると当然ですけど、やはり色々また変わってくるんですね。 superの役割でタイトル設定できるというのは初めて知りました、オーバーライドでしょうか。
jimbe

2019/11/12 05:34

> superの役割でタイトル設定できるというのは初めて知りました、オーバーライドでしょうか オーバーライドではありません. 単に親クラスの(String 引数一つの)コンストラクタを呼んでいるだけです. 子クラスのコンストラクタは, (親クラスに「パラメータ無しのコンストラクタ」が無い限り)親クラスのコンストラクタを呼ばなければなりません. JFrame には「パラメータ無しのコンストラクタ」がありますので呼ぶ必要無いことになり, またタイトルを設定するなら setTitle が使用できるのですが, JFrame のコンストラクタには(ご存じの通り)タイトル文字列を引数とするものがありますので, 「子コンストラクタから親コンストラクタを呼び出す」形式をあえて使用してタイトルを設定することにしました. この辺りは好みと言いますか, かなり個人的なコーディングスタイルのお話になるかと思います.
ponzu7080

2019/11/13 13:09

お返事遅くなりすみません。なるほど、理解できました。子コンストラクタから親コンストラクタを呼び出すことが可能なのは知っていましたが、そんな応用がきくんですね。。。今回はsetを使わずにタイトルを設定なさるというのを知れてよかったです。また何度も答えていただき本当に、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問