web-dev-qa-db-ja.com

JPanelを使用してJFrameのサイズを自動的に変更Java

マインスイーパゲームに変更を加えています。これらの1つは難しさです。私はこれとその動作をなんとか実行できましたが、ゲームボード(独自のJpanel内)が(難易度に応じて)大きくなったり小さくなったりすると、JFrameのサイズを自動的に変更できなくなります。私は使っている:

setPreferredSize(new Dimension(WIDTH, HEIGHT));

ウィンドウの初期サイズを設定しますが、これにより、JMenuBarからWord'File 'のみを表示する場合のように、ウィンドウが非常に小さくなります。手動でサイズを変更する必要があります。

ActionListenerイベントでsetSize()やframe.pack()などを試しましたが、サイズを変更できないようです。

使用するコード/メソッドに関するヒント。

編集:投稿されたコード

package mines;

import Java.awt.BorderLayout;
import Java.awt.Dimension;
import Java.awt.event.ActionEvent;
import Java.awt.event.ActionListener;

import javax.swing.*;

public class SetupFrame extends JFrame {

    private final int WIDTH = 600;
    private final int HEIGHT = 500;
    public JFrame frame;
    public JMenuBar menubar;
    public JMenu file;
    public JMenu levels;
    public JMenu help;
    public JMenuItem login;
    public JMenuItem save;
    public JMenuItem resume;
    public JMenuItem exit;
    public JMenuItem easy;
    public JMenuItem medium;
    public JMenuItem hard;
    private JLabel statusbar;
    public JPanel main;
    public JPanel buttonPanel;
    public JPanel saved;
    public JPanel game;
    public Board mineGame;
    public JButton ngButton;
    public JButton undoButton;
    public JButton redoButton;
    public JTabbedPane tp;
    public String[] levelPicker;
    public JComboBox levelSelect;
    public JFileChooser chooser;
    public String filename;

    public int difficulty;

    public SetupFrame(){

      frame = new JFrame();

      String filename = JOptionPane.showInputDialog(frame, "Enter Your Name.");

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


      setLocationRelativeTo(null);
      setTitle("Minesweeper");

      //menubar, menus, menu items
      menubar = new JMenuBar();
      setJMenuBar(menubar);

      file = new JMenu("File");
      help = new JMenu("Help");

      menubar.add(file);
      menubar.add(help);

      login = new JMenuItem("Login..");
      save = new JMenuItem("Save..");
      resume = new JMenuItem("Resume..");
      exit = new JMenuItem("Exit");

      file.add(login);
      file.add(save);
      file.add(resume);
      file.addSeparator();
      file.add(exit);

      statusbar = new JLabel("");



      chooser = new JFileChooser(); // new File Chooser for saved tab
      undoButton = new JButton(" Undo "); //undo Button for game panel 
      ngButton = new JButton(" New Game ");//new game Button for game panel
      redoButton = new JButton(" Redo");//redo Button for game panel

      main = new JPanel(new BorderLayout()); //new panel for main game
      //main.add(mineGame, BorderLayout.CENTER); //add instance mineGame to main panel

      game = new JPanel(new BorderLayout());// new panel for game tab
      main.add(game, BorderLayout.CENTER); //add the mineGames panel to game panel
      game.add(statusbar, BorderLayout.SOUTH); //add statusbar to bottom of game panel
            //game.add(button, BorderLayout.NORTH); // add buttons (eventually be redo, undo, new game)

      saved = new JPanel(); // create new panel for the saved tab
      saved.add(chooser);//add the File Chooser to the saved tab

      String[] levelPicker = {"Easy", "Medium", "Hard"};
      levelSelect = new JComboBox(levelPicker);
      levelSelect.setSelectedIndex(0);
            //levelSelect.addActionListener(this);

       buttonPanel = new JPanel();
       buttonPanel.add(undoButton);
       buttonPanel.add(ngButton);
       buttonPanel.add(redoButton);
       buttonPanel.add(levelSelect);
       main.add(buttonPanel, BorderLayout.NORTH);

       //create & add the tabs
       tp = new JTabbedPane();
       tp.addTab ("Game", main);
       tp.addTab ("Saved", saved);
       tp.addTab ("Statistics", null);
       add(tp);

       setPreferredSize(new Dimension(WIDTH, HEIGHT));
       setResizable(true);
       setVisible(true);
       frame.pack();


        class listener implements ActionListener{
            public void actionPerformed (ActionEvent e)
            {   
                if(e.getSource() == ngButton){
                    //JOptionPane.showInputDialog(frame, "Do You want To Save");
                    newMineGame();
                }
                JComboBox cb = (JComboBox)e.getSource();
                String picker = (String)cb.getSelectedItem();
                if (picker == "Easy"){
                    difficulty = 0;
                    newMineGame();
                }
                if (picker == "Medium"){
                    difficulty = 1;
                    newMineGame();
                    frame.pack();
                }
                if (picker == "Hard"){
                    difficulty = 2;
                    newMineGame();
                    frame.pack();
                }
            }


            private void newMineGame() {
                game.removeAll();
                mineGame = new Board(statusbar, difficulty);
                game.add(mineGame, BorderLayout.CENTER);
                game.add(statusbar, BorderLayout.SOUTH);
                repaint();
            }

        }

        ngButton.addActionListener(new listener());
        undoButton.addActionListener(new listener());
        redoButton.addActionListener(new listener());
        levelSelect.addActionListener(new listener());


    }

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

    }
5
Ange King

これらの1つは難しさです。私はこれとその動作をなんとか実行できましたが、ゲームボード(独自のJpanel内)が(難易度に応じて)大きくなったり小さくなったりすると、JFrameのサイズを自動的に変更できなくなります。

そして

actionListenerイベントでsetSize()やframe.pack()などを試しましたが、サイズを変更できないようです。

  • JFrame.pack()

    1. 地雷を表すすべてのJComponentsJToggleButtonを使用する最良の方法があります)は、適切にPreferredSizeを親(JPanel)に返します。

    2. gridLayoutによって配置された親(JPanel)(非常に単純)

    3. JFrame.pack()を行う方法、時期、場所は2つあります。

      • CardLayoutを使用します。Cardを切り替えた後の次のコード行はJFrame.pack()です。

      • 古いJPanelを(JFrameから)削除して新しいものに置き換えたら、JFrame.(re)validate()JFrame.repaint()、およびJFrame.pack()を呼び出す必要があります最後のコード行として

  • 別の問題があるかもしれません。重要なのは、JFrame.setResizable(false);の設定がある場合のコードの順序です。


編集後

  • 使用 Cardlayout

  • コード行がありません(JFrameを拡張しないでください。このオブジェクトを_Local variable_として作成してください)JFrame.(re)validate()JFrame.repaint()、およびJFrame.pack()private void newMineGame() {の最後のコード行として


しかし、私はあなたが何を意味するのか理解していません: "コード行がありません(JFrameを拡張しないでください。このオブジェクトをローカル変数として作成してください);

コードは

_import javax.swing.*;

public class SetupFrame {

    private JFrame frame;
    private JMenuBar menubar = new JMenuBar();
    private Board mineGame;

    public SetupFrame() {
        //there add required JComponents

        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setTitle("Minesweeper");
        frame.setJMenuBar(menubar);
        frame.add(mineGame);
        //frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));
        //frame.setResizable(true);//not neccessary
        frame.pack();
        frame.setVisible(true);
    }

    private void newMineGame() {
        //remove old Board
        //add a new Board
        frame.validate();
        frame.repaint();
        frame.pack();
    }

    private static void main(String[] args) {
        Java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new SetupFrame();
            }
        });
    }
}
_
7
mKorbel

ここにあなたの間違いがあります:

frame.pack();

frameが実際にSetupFrameから拡張されているのに、なぜJFrameが必要なのですか?この行をpack()だけ変更すると、機能します。

@mKorbelは、pack()の動作に関する完全で非常に役立つ説明をすでに投稿しています(ありがとうございます)。

更新

また、listenerクラスでは、JButtonが押されたときに次の例外が発生します。

Java.lang.ClassCastException: javax.swing.JButton cannot be cast to javax.swing.JComboBox

これを回避するには、この小さな変更を加える必要があります。

class listener implements ActionListener{

    public void actionPerformed (ActionEvent e) {
        if(e.getSource() == ngButton){
            //JOptionPane.showInputDialog(frame, "Do You want To Save");
            newMineGame();
        } else if(e.getSource() instanceof JComboBox){ // add this else-if block
            JComboBox cb = (JComboBox)e.getSource();
            String picker = (String)cb.getSelectedItem();
            if (picker.equals("Easy")){ // <-- picker == "Easy" is not the proper way to compare string, use equals() method instead
                difficulty = 0;
                newMineGame();
            }
            if (picker.equals("Medium")){
                difficulty = 1;
                newMineGame();
                //frame.pack();  <--- again, just use pack();
                pack();
            }
            if (picker.equals("Hard")){
                difficulty = 2;
                newMineGame();
                //frame.pack();  <--- again, just use pack();
                pack();
            }
        }
    }

またはさらに良いことに、 ItemListener を実装して、代わりにJComboBoxを使用してActionListener選択の変更をリッスンします

7
dic19