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

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

ただいまの
回答率

90.35%

  • Java

    14371questions

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

  • Swing

    231questions

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

Java Swingでラベルの描画がおかしくなる

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 244

某野球ゲームのミニゲームである地雷原を進むゲームを作り出したところです。
今はボタンを押すと格子状のラベルが描画されるコードを書いていました。

が、ボタンを押しても何の反応もせずウインドウを最小化して戻したり、タイトルバーをつかんでドラッグで描画部分を下に隠して戻したりすると正しく表示されます。
ボーダーが表示されてないだけで実際はそこに描画されてるのかなと思い背景色も変えたりしましたが、やはり表示部分を何らかの方法で隠して再表示しないと描画されません。

ボタンを押したらすぐ表示されるようにするにはどうすればいいのでしょうか?

↓ボタンを押しただけではこの格子が出ない↓
イメージ説明

public class Mine {
    public static void main(String[] args) {
        Swing mine = new Swing("地雷ゲーム");
        Process.process = mine;  //処理クラスに渡す
        mine.setVisible(true);
        mine.setLocationRelativeTo(null); 
        mine.setResizable(false);    
    }
}
import javax.swing.*;
import java.awt.*;
import javax.swing.border.*;
import java.awt.event.*;
import java.util.*;

class Swing extends JFrame implements ActionListener{ 
    JButton[] difficultyBtns = new JButton[3];
    JPanel p1 = new JPanel();

    Swing(String title){
        setTitle(title);
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        p1 = new JPanel();
        p1.setLayout(null);
        p1.setBounds(0, 0, 800, 600);

        difficultyBtns[0] = new JButton("easy"); 
        difficultyBtns[1] = new JButton("normal"); 
        difficultyBtns[2] = new JButton("hard");

        difficultyBtns[0].setBounds(220, 10, 100, 30);
        difficultyBtns[1].setBounds(350, 10, 100, 30);
        difficultyBtns[2].setBounds(480, 10, 100, 30);

        for (int i=0; i<3; i++) {
            difficultyBtns[i].setLayout(null);
            difficultyBtns[i].setBorder(new LineBorder(Color.black, 1, false));
            difficultyBtns[i].addActionListener(this); 
            difficultyBtns[i].setFont(new Font("メイリオ", Font.PLAIN, 18));
            difficultyBtns[i].setHorizontalAlignment(JLabel.CENTER);
            difficultyBtns[i].setVerticalAlignment(JLabel.CENTER);
            p1.add(difficultyBtns[i]);
        }
        difficultyBtns[0].setActionCommand("easy");
        difficultyBtns[1].setActionCommand("normal");
        difficultyBtns[2].setActionCommand("hard");

        add(p1);
    }

    public void actionPerformed(ActionEvent e){ 
        String cmd = e.getActionCommand();
        int difficulty = 0;
        if(cmd.equals("easy")) {
            difficulty = 11;
            Process.makeBtnEasy();
        } else if (cmd.equals("normal")) {
            difficulty = 21;
            Process.makeBtnNormal();
        } else {
            difficulty = 31;
        }
        Maze.s_main(difficulty);   //穴掘り法で迷路を作るメソッド 全て拾い物
    }
}
import javax.swing.*;
import java.awt.*;
import javax.swing.border.*;
import java.awt.event.*;
import java.util.*;

public class Process {
    public static Swing process = new Swing("");

    public static void makeBtnEasy() {    //easyでの描画
        JLabel[][] labels = new JLabel[9][9];

        for(int row=0; row<labels.length; row++) {
            for(int col=0; col<labels[row].length; col++) {
                labels[row][col] = new JLabel();
                labels[row][col].setBounds(265+(col*30),100+(row*30), 30, 30);
                //labels[row][col].setLayout(null);
                //↑これが関係してるかと思いコメントアウトしたが直らなかった
                labels[row][col].setBorder(new LineBorder(Color.black, 1, false));
                process.p1.add(labels[row][col]);
            }
        }
    }

    public static void makeBtnNormal() {    //normalでの描画
        JLabel[][] labels = new JLabel[19][19];

        for(int row=0; row<labels.length; row++) {
            for(int col=0; col<labels[row].length; col++) {
                labels[row][col] = new JLabel();
                labels[row][col].setBounds(210+(col*20),100+(row*20), 20, 20);
                //labels[row][col].setLayout(null);
                labels[row][col].setBackground(Color.GREEN); //背景色設定してみたがダメだった
                labels[row][col].setOpaque(true);
                labels[row][col].setBorder(new LineBorder(Color.black, 1, false));
                process.p1.add(labels[row][col]);
            }
        }
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+2

質問にある実装方法ではボタンを押すたびにJLabelのインスタンスが追加されてしまうのでメモリが破綻します。あらかじめeasyPanelとnormalPanelを用意しておいて、それぞれに必要なJLabelを貼り付けます。これらのパネルは両方ともsetVisible(false)としておいて、ボタンが押されたときにいずれか一方をsetVisible(true)とします。

public static void main(String[] args) {
    Swing mine = new Swing("地雷ゲーム");
    mine.setVisible(true);
    mine.setLocationRelativeTo(null);
    mine.setResizable(false);
}
public class Swing extends JFrame implements ActionListener {

    JButton[] difficultyBtns = new JButton[3];
    JPanel p1 = new JPanel();
    JPanel easyPanel = new JPanel();
    JPanel normalPanel = new JPanel();

    Swing(String title) {
        setTitle(title);
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        p1 = new JPanel();
        p1.setLayout(null);
        p1.setBounds(0, 0, 800, 600);

        difficultyBtns[0] = new JButton("easy");
        difficultyBtns[1] = new JButton("normal");
        difficultyBtns[2] = new JButton("hard");

        difficultyBtns[0].setBounds(220, 10, 100, 30);
        difficultyBtns[1].setBounds(350, 10, 100, 30);
        difficultyBtns[2].setBounds(480, 10, 100, 30);

        for (int i = 0; i < 3; i++) {
            difficultyBtns[i].setLayout(null);
            difficultyBtns[i].setBorder(new LineBorder(Color.black, 1, false));
            difficultyBtns[i].addActionListener(this);
            difficultyBtns[i].setFont(new Font("メイリオ", Font.PLAIN, 18));
            difficultyBtns[i].setHorizontalAlignment(JLabel.CENTER);
            difficultyBtns[i].setVerticalAlignment(JLabel.CENTER);
            p1.add(difficultyBtns[i]);
        }
        difficultyBtns[0].setActionCommand("easy");
        difficultyBtns[1].setActionCommand("normal");
        difficultyBtns[2].setActionCommand("hard");

        easyPanel.setLayout(null);
        easyPanel.setBounds(0, 0, 600, 500);
        easyPanel.setVisible(false);
        JLabel[][] easyLabels = new JLabel[9][9];

        for(int row=0; row<easyLabels.length; row++) {
            for(int col=0; col<easyLabels[row].length; col++) {
                easyLabels[row][col] = new JLabel();
                easyLabels[row][col].setBounds(265+(col*30),100+(row*30), 30, 30);
                easyLabels[row][col].setBorder(new LineBorder(Color.black, 1, false));
                easyPanel.add(easyLabels[row][col]);
            }
        }
        p1.add(easyPanel);

        normalPanel.setLayout(null);
        normalPanel.setBounds(0, 0, 600, 500);
        normalPanel.setVisible(false);
        JLabel[][] normalLabels = new JLabel[19][19];

        for(int row=0; row<normalLabels.length; row++) {
            for(int col=0; col<normalLabels[row].length; col++) {
                normalLabels[row][col] = new JLabel();
                normalLabels[row][col].setBounds(210+(col*20),100+(row*20), 20, 20);
                normalLabels[row][col].setBackground(Color.GREEN); //背景色設定してみたがダメだった
                normalLabels[row][col].setOpaque(true);
                normalLabels[row][col].setBorder(new LineBorder(Color.black, 1, false));
                normalPanel.add(normalLabels[row][col]);
            }
        }
        p1.add(normalPanel);

        add(p1);

    }

    public void actionPerformed(ActionEvent e) {
        String cmd = e.getActionCommand();
        int difficulty = 0;
        if (cmd.equals("easy")) {
            difficulty = 11;
            normalPanel.setVisible(false);
            easyPanel.setVisible(true);
        } else if (cmd.equals("normal")) {
            difficulty = 21;
            normalPanel.setVisible(true);
            easyPanel.setVisible(false);
        } else {
            difficulty = 31;
        }
        Maze.s_main(difficulty); // 穴掘り法で迷路を作るメソッド 全て拾い物
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/10 20:01

    回答ありがとうございます!
    仰るとおりeasyとnormalのラベルがバッティングして同時に表示されるので、makeBtnEasy内でまずラベルがすでにあるか調べて、あったら全部消してから描画とするようにしようと考えていましたが、回答のやり方のほうがすごくスマートなのでありがたく使わせていただきます!

    キャンセル

checkベストアンサー

0

actionPerformedの最後でrepaint()を呼んでみてください。

某野球ゲームのミニゲームである地雷原を進むゲーム

パワポケ8ですかね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/10 18:29

    回答ありがとうございます!
    情報を更新したらすぐに描画されるものだと思っていました。検索したときに再描画と書いてあるのを除いて調べていたのが馬鹿でした。
    名前を出していいのかわからなかったですが、おっしゃるとおりパワポケ3,8の地雷ゲームです

    キャンセル

  • 2018/05/10 18:34

    私もSwingを触りはじめた時にハマった記憶があります。

    ---
    > おっしゃるとおりパワポケ3,8の地雷ゲームです
    ですよね。パワポケはそれなりにやり込んだので懐かしいです。維織さん推しです。

    キャンセル

  • 2018/05/10 18:48

    javaも学び始めたところなのにGUIに手を出してひーひーいいながら都度基礎的な質問を投稿しているので、いつも申し訳ない気持ちがありましたが、ベテランの方も最初ハマったと聞いて少し安心しました(失礼)

    パワポケは7までやってましたが独特のブラック感が好きでした、彼女がさらわれたりするし。

    キャンセル

  • 2018/05/10 18:58 編集

    > 情報を更新したらすぐに描画されるものだと思っていました。

    その感覚はswingではなく他のGUIライブラリーでは正しい場合もあります。例えばJavaFXはそれに近いです(再描画メソッドがどのクラスにもなくなってるのです)。計算機の能力が上がるにつれ、プログラミングの手法が進むにつれ色々な方法論が「よりスマート」な方向に進んでますので、swing時代には必要だった再描画がもうあまり必要とされなくなったのかも知れません。

    キャンセル

  • 2018/05/10 19:07

    >例えばJavaFXはそれに近いです
    そうなんですね!使っているノートPCが超低スペックでeclipseを入れられないのでswingでやっているのですが、もうすぐ買い換えてeclipseを入れてJavaFXの勉強もしようと思っているのでその時は苦労しなくてすみそうです。

    キャンセル

同じタグがついた質問を見る

  • Java

    14371questions

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

  • Swing

    231questions

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