前提
学校で「じゃんけんゲーム」を作成しているのですが、相手が出した手の画像が表示されないです。
実現したいこと
- 画像が表示されるようにする
該当のソースコード
Main.java
package RockPaperScissors; public class Main { public static void main(String[] args) { MainWindow window = new MainWindow(); window.show(); } }
Mainwindow.java
package RockPaperScissors; import javax.swing.*; import java.awt.event.*; import java.awt.*; import java.awt.Graphics.*; import RockPaperScissors.Hands; public class MainWindow { private final JFrame frame; private final JLabel messageLabel1; private final JLabel messageLabel2; private JLabel HandsImage; private final JButton rockButton; private final JButton scissorsButton; private final JButton paperButton; private final JButton retryButton; private Status gameStatus; private Hands opponentHand; static private int winning = 0; static private JPanel canvas; public MainWindow() { this.frame = new JFrame("じゃんけん対決"); this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.frame.setBounds(200, 200, 600, 400); var pane = this.frame.getContentPane(); canvas = new JPanel(); canvas.setLayout(null); this.messageLabel1 = new JLabel("じゃんけん..."); this.messageLabel1.setBounds(20, 20, 400, 40); canvas.add(this.messageLabel1); this.messageLabel2 = new JLabel("連勝回数:" + winning); this.messageLabel2.setBounds(500, 20, 400, 40); canvas.add(this.messageLabel2); this.rockButton = new JButton(Hands.Rock.getDisplay()); this.rockButton.setBounds(100,300, 100, 40); this.rockButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { selectHand(Hands.Rock); HandsImage = new JLabel(new ImageIcon("rock.png")); //HandsImage = new JLabel(opponentHand.getImage()); } }); this.HandsImage = new JLabel(new ImageIcon("paper.png")); this.HandsImage.setPreferredSize(new Dimension(300,300)); this.HandsImage.setHorizontalAlignment(JLabel.LEFT); this.HandsImage.setBounds(300, 300, 300, 300); canvas.add(HandsImage); canvas.add(rockButton); this.scissorsButton = new JButton(Hands.Scissors.getDisplay()); this.scissorsButton.setBounds(250, 300, 100, 40); this.scissorsButton.addActionListener((e) -> this.selectHand(Hands.Scissors)); canvas.add(this.scissorsButton); this.paperButton = new JButton(Hands.Paper.getDisplay()); this.paperButton.setBounds(400, 300, 100, 40); this.paperButton.addActionListener((e) -> this.selectHand(Hands.Paper)); canvas.add(this.paperButton); this.retryButton = new JButton("リトライ"); this.retryButton.setBounds(450, 200, 100, 40); this.retryButton.addActionListener((e) -> this.init()); canvas.add(this.retryButton); pane.add(canvas); } public void paint(Graphics g) { g.setColor(Color.black); } public void show() { this.init(); this.frame.setVisible(true); } public void init() { this.messageLabel1.setText("じゃんけん..."); this.opponentHand = Hands.getRandomHand(); this.HandsImage = new JLabel(new ImageIcon("paper.png")); this.HandsImage.setPreferredSize(new Dimension(300,300)); this.HandsImage.setHorizontalAlignment(JLabel.LEFT); canvas.add(HandsImage); canvas.add(rockButton); this.gameStatus = Status.Wait; } public void selectHand(Hands selected) { if(this.gameStatus != Status.Wait) { return; } switch((selected.getNumber() - opponentHand.getNumber() + 3) % 3) { case 0: this.init(); this.messageLabel1.setText("あいこで..."); break; case 1: this.messageLabel1.setText(String.format("相手が出したのは「%s」なのであなたの負けです。", this.opponentHand.getDisplay())); this.winning = 0; this.messageLabel2.setText(String.format("連勝回数:" + winning, this.opponentHand.getDisplay())); this.gameStatus = Status.Done; break; case 2: this.messageLabel1.setText(String.format("相手が出したのは「%s」なのであなたの勝ちです。", this.opponentHand.getDisplay())); ++ this.winning; this.messageLabel2.setText(String.format("連勝回数:" + winning, this.opponentHand.getDisplay())); this.gameStatus = Status.Done; break; } } }
Hands.java
package RockPaperScissors; import java.util.*; import java.awt.image.*; import java.io.*; import javax.imageio.*; import javax.swing.ImageIcon; public enum Hands { Rock("グー", 0, "rock.png"), Scissors("チョキ", 1,"scissors.png"), Paper("パー", 2, "paper.png"); private final String display; private final int number; private final ImageIcon image; Hands(String display, int number, String filename) { this.display = display; this.number = number; this.image = new ImageIcon(filename); } public static Hands getRandomHand() { Random rand = new Random(); return Hands.values()[rand.nextInt(3)]; } public String getDisplay() { return this.display; } public int getNumber() { return this.number; } public ImageIcon getImage() { return this.image; } }
試したこと
this.HandsImage = new JLabel(new ImageIcon("paper.png")); this.HandsImage.setPreferredSize(new Dimension(300,300)); this.HandsImage.setHorizontalAlignment(JLabel.LEFT); this.HandsImage.setBounds(300, 300, 300, 300);
の部分を様々な場所に移動させましたが、どれも失敗でした。
javadoc は関係ありませんのでタグから外したほうが良いです。
>~の部分を様々な場所に移動させましたが
プログラムがどう動いているかは考えずにテキトウに移動させていたのでしょうか。
コメントありがとうございます。
試した場所としては上記の場所の他に、MainWindow.java内のpublic void actionPerformed(ActionEvent e)、canvas.setLayout(null);の下で試しました。
https://github.com/frohoff/jdk8u-dev-jdk/blob/master/src/share/classes/javax/swing/ImageIcon.java をみると、new ImageIcon("paper.png")としても、そのファイルが見つからなければ例外などスローせずスルーしている。paper.pngを見つけられていないのでは?
フルバスで指定すればいいのかも。new ImageIcon("c:/hoge/hage/paper.png")
質問は編集できますので
学校でということで恐らく Swing の前にコンソールプログラムをやっていると思いますが、 Swing はコンソールのように"表示"と言えば即表示するわけではありません。
JFrame→JPanel→JLabel といった各コンポーネントのツリー構造を正しく作って、後は Swing に表示をお願いすると Swing 側で適切なタイミングで表示する…という間接的な処理となります。
移動させてみたという HandsImage の生成処理は、処理フローのどこかで canvas に add されていれば表示対象とされ add されなければ対象とされないというだけのことで、処理のタイミングを変更しようというのであれば適切なタイミングがどこなのかを理解して変更するべきでしょう。
また、 shiketa さんのご指摘の通り、 そもそも画像ファイルが取得出来ているのかは確認する必要があると思います。
各ファイルがどこにあるのか、『取得出来る所に置いているはず』であれば、フォルダ構造も提示して頂けるとこちらも確認出来ます。