0

I've initialized a GridBagLayout globally, then in my class constructor have instantiated it and added some buttons etc. to it.

How can I add things to it after the fact? Simple class extends JFrame. Whenever I try class.add(stuff, gridbagconstraints) after the fact (used just add(stuff, gribagconstraints) in constructor) Nothing happens and nothing is added to my layout.

Do I need to "refresh" the layout manager or something? It is declared globally.

Update: I've tried revalidate() but it does not seem to be working, here is a simplified version of my code with a test button in place for proof of concept:

public class MainGUI extends JPanel{
    static GridBagConstraints c;
    static MainGUI mainGUIclass;
    static JFrame mainGUIframe;

    public MainGUI() {
    this.setLayout(new GridBagLayout());
    c = new GridBagConstraints();

    saveButton = new JButton("Save and Exit");
    saveButton.setPreferredSize(new Dimension(200, 30));

    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 4;
    add(saveButton, c);
    }

public static void main(String[] args) {
    mainGUIframe = new JFrame("Message");

    mainGUIframe.setSize(800,800);

    mainGUIclass = new MainGUI();

    mainGUIframe.add(mainGUIclass);
    mainGUIframe.setVisible(true);


   //now the addition
    JButton newButton = new JButton("New Button");  

    newButton.setPreferredSize(new Dimension(200, 30));


    c.gridx = 5;
    c.gridy = 0;
    c.gridwidth = 4;
    mainGUIclass.add(newButton,c);

    //none of this seems to work
    mainGUIclass.revalidate();//?
    mainGUIclass.repaint();//?

  }
}

Update2: This appears to be an issue with the passbyvalue nature of java and another class(canvas) I am trying to add to my layout. Will update if I find a solution.

Update3: This is a thread problem, the class I'm calling is hanging the main window.

Edit: I provided the code as a reference, and tried to be complete to provide a complete picture, not to be easily compiled on its own. Thank you to all who offered your assistance.

Update4: Success! They key was that the mediaplayer class did an "isDisplayable()" check, which caused it to hang the program if the frame it was being added to was not get added to the gridbaglayout. A series of unfortunate looking pass by values (of JInternalFrames), preadding the internalframe to the gridbaglayout and a remote start of the media from another method allows what I am seeking to work.

Lorne Schultz
  • 167
  • 1
  • 15
  • 1
    The code you posted doesn't even compile. I dont' have time to fix your compile errors! Also you should NOT be using static variables. – camickr Sep 07 '11 at 17:22
  • @Time, What does a MediaPlayer have to do with anything? We are NOT mind readers which is why the code you post should be compile and demonstrate the problem you are having. A few lines of code is useless to us unless we know the context of how the code is used. – camickr Sep 07 '11 at 21:16

2 Answers2

4

You would call revalidate() on the container (if it derives from JComponent such as JPanel) that uses the layout to have the layouts re-set the components they contain. This should recurse through all the containers held by this layout, and they too should have their component layouts updated. The main exception to this that I know of would be components held in JScrollPanes, and for that, you'd need to call revalidate on the scrollpane's JViewport.

Also, sometimes you will need to call repaint() after revalidate(), especially if you have removed any components held by the container.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • just curiosity what did you means with `revalidate on the scrollpane's JViewport`, hmmm are you means moving with JViewport to the correct point after something removes-then-adds +1 – mKorbel Sep 07 '11 at 16:54
  • @mKorbel: if you add a component to a container held in a JScrollPane, then calling revalidate on the JScrollPane or on any container that holds it will not percolate to the containers held by the JScrollPane. You will instead need to call revalidate on the JViewport. – Hovercraft Full Of Eels Sep 07 '11 at 17:01
  • example http://stackoverflow.com/questions/6988317/dynamically-add-components-to-a-jdialog/6989230#6989230 – mKorbel Sep 07 '11 at 17:11
  • 1
    I usually revalidate() the panel I add the components to, whether the panel is added to a scrollpane or not. – camickr Sep 07 '11 at 17:17
  • @TimCurry: You're not updating your GridBagConstraint properly and this is why the button is not showing – Hovercraft Full Of Eels Sep 07 '11 at 17:19
  • @Hovercraft Full Of Eels really doesn't make me sence, why???, are you resize JPanel (or JComponent) inside JScrollPane after JComponent added, hmmm instead of schrinking all exists JComponents to the current JPanel size??? – mKorbel Sep 07 '11 at 17:23
  • See updates above, sorry about the prior omission, but that is not it I'm afraid. – Lorne Schultz Sep 07 '11 at 17:28
  • @Tim: it still doesn't compile. You're making this difficult. **Edit:** After editing your code, both buttons show. I don't see what the problem is? – Hovercraft Full Of Eels Sep 07 '11 at 17:31
3

In your example you are adding a button with exactly the same GridBagConstraints as the previous button. When I try running that code your buttons are laid on top of each other and so you will only see one of them. Try changing your GridBagConstraints so that the second button you add is placed in another location. It is recommended practice to instantiate a new GridBagConstraints for each constrained component to remove the chance of such programming errors occurring.

Also, with regards to your update, JFrame does not have a revalidate() function.

If you haven't already done so, it would be worth you reading thoroughly through this.

  • Sorry, this is not actually my code, but a simplification of it, I'd forgotten to add new gridbagconstraints in the example, not in my code though. See above for updates. This is not a problem with GridBagLayout specifically I imagine, but with updating any layout manager. – Lorne Schultz Sep 07 '11 at 17:22
  • @Tim: To be blunt: it's a bad simplification of it. Please post compilable or nearly compilable code. We will not be able to know what your real problem is if we have to deal with other problems that bad code generates. – Hovercraft Full Of Eels Sep 07 '11 at 17:25
  • What version of Java are you using? If I run the (now updated) code in your example I see both buttons just fine. –  Sep 07 '11 at 17:25