0

I want to modify the size of the JPanel while the program is running, for example with a menu item. How can I reach it? Or how should I modify my program to get acces to the live JPanel in the content pane?

Edit: If I make a contentpane for a gamefield that's 400x400 in the start as default. But what if I want to ad an option in the menu to change the size to 500x500, but without losing all of the content already in progress by the player.

JFrame class:

package me.test;

import javax.swing.JFrame;


public class Main extends JFrame {
    private static final long serialVersionUID = 1L;

public static void main(String[] args) {
    // TODO Auto-generated method stub
    new Main();
}

public Main() {

    setContentPane(new MyJPanel());

    pack();
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLocation(100,50);
    setResizable(false);
    setVisible(true);


    }

}

My modified JPanel:

package me.test;

import java.awt.Dimension;

import javax.swing.JPanel;

public class MyJPanel extends JPanel {

    public MyJPanel() {
        setPreferredSize(new Dimension(400,400));
    }
}
  • Changing the preferred size of the panel will not help you as long as it is used as the content pane. – Marco13 Feb 04 '14 at 15:11
  • 1
    *"I want to modify the size of the JPanel while the program is running"* Drag the `JFrame` bigger. Why do you need to do it programmatically? – Andrew Thompson Feb 04 '14 at 15:25

2 Answers2

2

Have a look over this code for some ideas. It can change sizes according to actions placed either in a toolbar in the component itself, or menu items of the frame.

Important points of the code are:

  • Set a preferred size on the component in question.
  • Get a reference to the top level container.
  • Finally pack() the top level container.

enter image description here

import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class GameSize {

    // the GUI as seen by the user (without frame)
    private JPanel gui = new JPanel(new GridBagLayout());
    Action small = new AbstractAction("Small") {

        @Override
        public void actionPerformed(ActionEvent e) {
            setSize(400, 100);
        }
    };
    Action large = new AbstractAction("Large") {

        @Override
        public void actionPerformed(ActionEvent e) {
            setSize(600, 200);
        }
    };

    private final void setSize(int w, int h) {
        gui.setPreferredSize(new Dimension(w, h));
        Container c = gui.getTopLevelAncestor();
        if (c instanceof JFrame) {
            JFrame f = (JFrame) c;
            f.pack();
        }
    }

    GameSize() {
        JToolBar tb = new JToolBar("Size");
        for (Action action : getActions()) {
            tb.add(action);
        }
        gui.add(tb);

        gui.setPreferredSize(new Dimension(200, 100));
        gui.setBackground(Color.RED);
    }

    /*
     * @return the Actions
     */
    public Action[] getActions() {
        Action[] actions = {small, large};

        return actions;
    }

    /**
     * @return the gui
     */
    public JPanel getGui() {
        return gui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                GameSize gs = new GameSize();

                JFrame f = new JFrame("Demo");
                f.add(gs.getGui());
                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See http://stackoverflow.com/a/7143398/418556 for demo.
                f.setLocationByPlatform(true);

                JMenuBar menuBar = new JMenuBar();
                f.setJMenuBar(menuBar);
                JMenu size = new JMenu("Size");
                menuBar.add(size);
                for (Action action : gs.getActions()) {
                    size.add(action);
                }

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • This caused me to search Meta-Stackoverflow for exactly this question: http://meta.stackexchange.com/q/88627/ : Complete refactoring or minimal changes? However, worth an upvote, imho – Marco13 Feb 04 '14 at 16:19
  • @Marco13 Wow. You are really missing the mark on this one. 1) That Q&A is about a 3rd party editing the *question.* So far, only the OP has edited the question. 2) It is about editing the *code* in the question, and judging by the [revisions](http://stackoverflow.com/posts/21555968/revisions) the code in the question has not altered one iota. -- What you have done by trying to stick closely to the code in the question is simply to perpetuate bad practices. Would you like me to count and detail them? – Andrew Thompson Feb 04 '14 at 16:31
  • 1
    Thank you! Think this will help, will have a look! – Barnabas Lesti Feb 04 '14 at 16:45
  • @Andrew Thompson: I did not find any recommendatations about how far to refactor the code during the *answer*. That is, whether each question should be answered with something that can equally be found in any tutorial (potentially hiding the relevant info), or with a "spot-on" answer that points out exactly what was asked for (regardless of the surrounding code, but of course, with the option to give hints for further improvements beyond just answering the question - in this example, the EDT-link and the link to 'How to use Actions'). But I'm still learning and I'll consider all these options – Marco13 Feb 04 '14 at 17:06
  • @Marco13 On 'how far to refactor code' I take my lead from this discussion of the [XY problem](http://meta.stackexchange.com/q/66377/155831), admittedly it only applies peripherally to the kinds of tips I added in the code. They are simply 'best practices' as opposed to 'the entire approach is wrong'. But I think the answers all seem to agree that adding information the OP did not explicitly ask for, is OK. IN fact, I have seen people criticized (and have myself also been criticized) for doing things like copying code that ended up back in an answer, but did not start the GUI on the EDT. – Andrew Thompson Feb 04 '14 at 17:12
  • @Marco13 Oh, and my use of actions was mainly inspired from the fact that they are sooo nice for adding actions to both a menu item and toolbar. ;) But the inclusion of both a menu and toolbar was really to demonstrate a point - that controls in the panel itself, or a menu, could equally easily change the size of the frame. – Andrew Thompson Feb 04 '14 at 17:16
  • You know that I'm not questioning your code (If I had 1 dollar for every `SwingUtilities.invokeLater` that I added in the answer to a forum question ... ;-)). Of course, hints for improvements should always be welcome (and I'm always puzzled when askers are not appreciating them). But in this case, it the asker just made his first steps in Swing, and will not understand the code without consulting the respective tutorial sites anyhow. It's a tightrope walk between "perpetuating bad practices" and "drowning someone in information". And I (as a stackoverflow-newbie) appreciate your feedback :-) – Marco13 Feb 04 '14 at 17:28
  • @Marco13 *"You know that I'm not questioning your code.."* Why not? *Anyone's* code and approach is open for discussion. It's all good. :) – Andrew Thompson Feb 04 '14 at 17:43
0

Playing around....

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

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;


public class PanelResize extends JFrame 
{
    private static final long serialVersionUID = 1L;

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

    private JPanel panel;

    public PanelResize() {

        panel = new MyJPanel();
        getContentPane().add(panel);

        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("Resize");
        JMenuItem menuItem = new JMenuItem("Resize");
        menuItem.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                panel.setPreferredSize(new Dimension(500,500));
                pack();
            }
        });
        menu.add(menuItem);
        menuBar.add(menu);
        this.setJMenuBar(menuBar);

        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocation(100,50);
        setResizable(false);
        setVisible(true);
    }

}


 class MyJPanel extends JPanel {

    public MyJPanel() {
        setPreferredSize(new Dimension(400,400));
    }
}
Marco13
  • 53,703
  • 9
  • 80
  • 159
  • *"Playing around...."* It's all fun and games until someone loses an eye. Oops, someone lost an eye! Setting a preferred size and calling `pack()` on the top level container should be more than enough. – Andrew Thompson Feb 04 '14 at 15:27
  • Well, the question was rather unclear, and the other answers (some already deleted) showed this as well. I did a guess concerning the intention, but admittedly, he'd probably be better off with a link to some tutorial.... – Marco13 Feb 04 '14 at 15:30
  • Well, of course the motto of "garbage in -> garbage out" should not apply to questions and answers, but sometimes you just HAVE to do some guesswork about the question-openers' intention - at least to offer him the possibility to point out in how far the answer deviates from what he *expected* as an answer. However, now that the question has been clarified, I have clarified my answer. And nobody lost an eye :-) – Marco13 Feb 04 '14 at 15:55
  • *"but sometimes you just HAVE to.."* ..clarify the ultimate goal via ***comments*** before jumping in feet first. ;) – Andrew Thompson Feb 04 '14 at 16:18
  • I'll try to obey this - I'm rather new to StackOverflow, still learning the "best practices" (e.g. no discussion comments like ... THIS one ;-)) – Marco13 Feb 04 '14 at 16:22