Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

resize JFrame automatically with JPanel Java

I am implementing changes to a minesweeper game. One of these things is the difficulty. I have managed to do this and its working, but as the game board (in its own Jpanel) gets bigger & smaller (depending on the difficulty), I cannot get the JFrame to resize automatically. I am using:

setPreferredSize(new Dimension(WIDTH, HEIGHT));

to set the initial size of the window, but this makes it REALLY tiny, as in only showing the word 'File' from the JMenuBar. I have to resize it manually.

I tried setSize() and things like frame.pack() on the ActionListener event, but I cannot seem to get it to resize.

Any tips on what code/methods to use.

edit: code posted

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();

    }
like image 255
Ange King Avatar asked Oct 04 '13 11:10

Ange King


People also ask

How do you resize a frame in Java?

You can change the size of the JFrame by simply placing the cursor in the corners and dragging it. Or if you press the resize option next to close(X) in the upper right corner, it will be enlarged to full-screen size. This happens because the resize is set to “true” by default.

How do I make JScrollPane resizable?

By default a JFrame uses a BorderLayout (so there is no need to reset it). All you need to do is add the JScrollPane to the CENTER of the BorderLayout and it will resize automatically. And the basic code would be: JTextArea textArea = new JTextArea(...); JScrollPane scrollPane = new JScrollPane(); frame.

How do I resize a JFrame in eclipse?

in this example, the four buttons will resize with the window. JFrame frame = new JFrame(); Container cp = frame. getContentPane(); cp. setLayout(new GridLayout(2, 2)); cp.


2 Answers

One of these things is the difficulty. I have managed to do this and its working, but as the game board (in its own Jpanel) gets bigger & smaller (depending on the difficulty), I cannot get the JFrame to resize automatically.

and

tried setSize() and things like frame.pack() on the ActionListener event, but I cannot seem to get it to resize.

  • JFrame.pack() works in case

    1. that all JComponents representing mines (there is best of ways to use JToggleButton) returns properly PreferredSize back to its parent (JPanel)

    2. parent (JPanel) laid by GridLayout (very simple)

    3. and there are two ways how, when, where to JFrame.pack()

      • use CardLayout, the next code line after swithching Card is JFrame.pack()

      • remove old JPanel (from JFrame) and replace with new, then you need to call JFrame.(re)validate(), JFrame.repaint() and JFrame.pack() as last code lines

  • maybe there is another issue, important is code ordering in the case that is there settings for JFrame.setResizable(false);


after your edit

  • use Cardlayout

  • there you miss code lines (don't to extends JFrame, create this Object as Local variable) JFrame.(re)validate(), JFrame.repaint() and JFrame.pack() as last code lines in private void newMineGame() {


but I dont understand what you mean by: "there you miss code lines (don't to extends JFrame, create this Object as Local variable) ;

code could be

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();
            }
        });
    }
}
like image 64
mKorbel Avatar answered Sep 18 '22 05:09

mKorbel


Here is your mistake:

frame.pack();

Why do you need frame if your SetupFrame actually extends from JFrame? Change this line by just pack() and it will work.

@mKorbel already posted a complete and very useful explanation about pack() behavior (thank you).

Update

Also in your listener class you'll get this exception when a JButton is pressed:

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

You need make this little change to avoid this:

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();
            }
        }
    }

Or even better, implement an ItemListener to listen JComboBox selection changes instead using an ActionListener

like image 25
dic19 Avatar answered Sep 19 '22 05:09

dic19