0

ゲーム用のボードを作成しようとしています。最初にフレームを作成してから、//ユーザーが行と列を数字として入力し、開始ボタンを押すと、//フレーム上のすべての内容を削除し、パネルを追加する必要がありますいたるところにボタンがあるグリッド レイアウト

コードは次のとおりです(問題は、フレームがクリアされて何も表示されないことです)

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class Frame extends JFrame implements ActionListener{
    private static final long serialVersionUID = 1L;


    JButton newButton;
    JButton Start;
    JTextArea row;
    JTextArea col;
    JLabel background;
    JLabel rows;
    JLabel columns;
    JLabel Error;
    JPanel myPanel;
    JCheckBox box;


    public Frame()
    {
                //adding frame


                setTitle("DVONN Game");
            setSize(1000, 700);
            setVisible(true);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setLayout(null);
        //making start button
        Start = new JButton(new ImageIcon("Start"));
        Start.setBounds(500, 30, 300, 300);
        Start.setOpaque(true);
        Start.addActionListener(this);

            //make background
        background = new JLabel();
        background.setBounds(0, -300, 2000, 1500);
        background.setIcon(Color.BLUE));

        rows = new JLabel("Enter the rows");
        columns = new JLabel("Enter the columns");
        rows.setForeground(Color.WHITE);
        columns.setForeground(Color.WHITE);
        rows.setBounds(10,10,100,30);
        columns.setBounds(10,45,105,30);

        row = new JTextArea();
        col = new JTextArea();
        row.setBounds(120,10,100,30);
        col.setBounds(120,45,100,30);

        Error = new JLabel("Enter numbers plz!");
                Error.setBounds(10, 100, 400, 30);
        Error.setForeground(Color.RED);
        Error.setVisible(true);

        box = new JCheckBox("Enable Random Filling");
        box.setBounds(10, 200, 150, 20);
        box.setVisible(true);

        myPanel = new JPanel();
        myPanel.setBounds(30, 30, 700, 500);
        myPanel.setVisible(true);

        newButton = new JButton();
        newButton.setOpaque(true);

        getContentPane().add(box);
        getContentPane().add(rows);
        getContentPane().add(columns);
        getContentPane().add(row);
        getContentPane().add(col);
        getContentPane().add(Start);
        getContentPane().add(background);

        this.validate();
        this.repaint();

    }


    public static void main(String[]args)
    {
        new Frame();
    }

      //adding actions for start button


      public void actionPerformed(ActionEvent e) {

        boolean flag = true;
        String r1 = row.getText();
        String c1 = col.getText();
        int x = 0,y = 0;

        try{
            x = Integer.parseInt(r1);
            y = Integer.parseInt(c1);
        } catch(NumberFormatException l) {
            flag = false;
        }

        int size = x * y;

        if (flag == true) {
            this.getContentPane().removeAll();
            this.validate();
            this.repaint();

            myPanel.setLayout(new GridLayout(x, y));

            while(size != 0)
            {
                myPanel.add(newButton);
                size --;
            }

            this.getContentPane().add(myPanel);

        } else {

            this.getContentPane().add(Error);
        }
    }
}
4

4 に答える 4

2

このコードにはいくつかの問題があります

  1. そんなに多くのコードを投稿する必要は本当にありますか? 1 つのボタンを押すだけのシンプルな UI と、表示される別のコンポーネントがあれば、SSCCEには十分です。
  2. nullレイアウトの使用。LayoutManagers の使い方を学んでください
  3. 各 Swing コンポーネントは、階層に一度だけ含めることができます。したがって、同じコンポーネントを何度も追加するため、このループは役に立ちません (負のサイズが無限ループになることは言うまでもありません)。

    while(size != 0){
      myPanel.add(newButton);
      size --;
    }
    
  4. sizeが実際にかどうかを確認するためにデバッグを試みましたか>0ParseExceptionsを黙って無視するので、コンテンツ ペインを消去して何も追加しないsizeofになる可能性があります。0
  5. 次に、goldilocks が提案するように実行validateし、コンポーネントを追加した後に呼び出します。Container#addメソッド の javadoc を参照してください

    このメソッドは、レイアウト関連の情報を変更するため、コンポーネント階層を無効にします。コンテナーが既に表示されている場合は、追加されたコンポーネントを表示するために、その後階層を検証する必要があります。

于 2012-05-17T15:35:58.843 に答える
1

古い要素が削除された後ではなく、新しい要素が追加されたvalidate()にandを呼び出します。repaint()

setVisible()個々のコンポーネントを呼び出す必要はなくpack()、Frame 自体で呼び出す必要はありません。また、コンストラクターでvalidate()andを使用しないでください。repaint()つまり、それらを次のものに置き換えます。

pack();
setVisible(true);

または、コンストラクターが呼び出された後にオブジェクトでそれを行うことができます。

于 2012-05-17T11:38:24.450 に答える
0

交換してみる

   public static void main(String[]args)
{
    new Frame();
}

   public static void main(String[]args)
{
    new Frame().setVisible(true);
}
于 2012-05-17T11:39:29.583 に答える
0

コンストラクターでの呼び出しを削除し、this.setVisibleこれをメイン メソッドにします。

public static void main(String[] args) {  
    final Frame fr = new Frame();

    java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
             fr.setVisible(true);
         }
    });
}

これにより、フレーム要素が表示される前に配置されます。

于 2012-05-17T11:45:26.743 に答える