Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Swing GridBagLayout panel resize issues

I am working on a simple little swing application for a relative, but I'm having trouble implementing animations on it...

Here is a description of my layout:

I have a main window (created by instantiating, packing, and displaying a JFrame). I have told the content panel of the main window to use GridBagLayout as its layout. My grid is 2 grids wide, and 3 grids tall. In the first column I have three JButtons (A, B, and C), each taking up one row of vertical grid space, and one column of horizontal grid space. In the second column, I have another JPanel, which is one column wide, and three rows tall.

This second JPanel is also set to use GridBagLayout as its layout. In this case, there are two columns, and one row. The left column has a one collumn wide, one row tall JPanel with Button 1 inside of it. The right column consists of just a single JButton (Button 2), which is also one column wide, and one row tall.

Here is a screenshot of what I just described: Image of Layout

Now that you understand what the layout is, let me explain what I've been trying to do:

I've been trying to use the Universal Tween Engine to resize the Jpanel which contains Button 1. However, in my attempts, I get this as a result:

enter image description here

As you can probably see, the JPanel containing Button 1 has successfully resized! However, Button 2's size and position have not change at all, and, in fact, button 2 is getting cut off by the JPanel containing Button 1!

This is a problem, as I expected resizing the JPanel containing Button 1 to simultaneously change the cell sizes of its containing GridBagLayout. I was sorely mistaken on this matter, it seems.

So that brings me to my question... What do I need to do in order to "Update" my GridBagLayout so that it resizes its grids to accommodate the increase in size from the Jpanel containing Button 1? I have tried calling GridBagLayout.invalidatelayout() on my GridBaglayout, and I have also tried calling JFrame.getContentPane().invalidate() on my main window. Neither seemed to have had any effect.

Here is the compilable source code of my project:

ImageManager.java:

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import aurelienribon.tweenaccessors.swing.*;
import aurelienribon.utils.swing.*;
import aurelienribon.tweenengine.*;
import aurelienribon.tweenengine.equations.*;

public class ImageManager
{
    /**
     * @param args
     */

    public static JFrame mainwindow;
    public static TweenManager tweenManager;
    public static void main(String[] args)
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable() //For thread safety!
        {
            public void run()
            {
                InitGUI();
                InitTween();
            }
        });
    }


    private static void InitTween()
    {
        ((Window)mainwindow).addWindowListener(new WindowAdapter() {
            @Override public void windowOpened(WindowEvent e)
            {
                    new DrawingCanvas()
                    {
                            @Override protected void update(int elapsedMillis)
                            {
                                tweenManager.update(elapsedMillis);
                            }
                    }.start();
            }
        });
    }


    private static void InitGUI()
    {
        //Init the window and layout systems
        mainwindow = new JFrame("Imaffect");
        Container pane = mainwindow.getContentPane();
        pane.setLayout(new GridBagLayout());

            //Begin creating the UI!
            pane.add(new JButton("Button A"), new GridBagConstraints(0, 0, 1, 1, 0, 1, GridBagConstraints.PAGE_START, GridBagConstraints.VERTICAL, new Insets(0,0,0,0), 100, 0));
            pane.add(new JButton("Button B"), new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.PAGE_START, GridBagConstraints.VERTICAL, new Insets(0,0,0,0), 100, 100));
            pane.add(new JButton("Button C"), new GridBagConstraints(0, 2, 1, 1, 0, 0, GridBagConstraints.PAGE_START, GridBagConstraints.VERTICAL, new Insets(0,0,0,0), 100, 20));

            pane.add(InitPreviewGUI(), new GridBagConstraints(1, 0, 1, 3, 1, 1, GridBagConstraints.PAGE_START, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0, 0));


        //Finalize the window
        mainwindow.pack();
        mainwindow.setVisible(true);
    }


    private static JPanel InitPreviewGUI()
    {
        JPanel panel = new JPanel(new GridBagLayout());
        panel.add(InitSettingsGUI(), new GridBagConstraints(0, 0, 1, 1, 0, 1, GridBagConstraints.PAGE_START, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0, 0));
        panel.add(new JButton("Button 2"), new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.PAGE_START, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0, 0));


        return panel;
    }

    private static JPanel InitSettingsGUI()
    {
        JPanel panel = new JPanel();
            SetupSettingsTweens(panel);
            SetupSettingsContent(panel);
        return panel;
    }


    private static void SetupSettingsTweens(JPanel panel)
    {
        Tween.registerAccessor(Component.class, new ComponentAccessor());
        tweenManager = new TweenManager();
        Tween.to(panel, ComponentAccessor.WIDTH, 1000)
            .target(200)
            .ease(Cubic.INOUT)
            .repeatYoyo(-1, 200)
            .delay(500)
            .start(tweenManager);

    }

    private static void SetupSettingsContent(JPanel panel)
    {
        panel.add(new JButton("Button 1"));
    }
}

If you want to compile the code yourself, you will need the following three resources:

  1. Universal Tween Engine library jar
  2. DrawingCanvas.java (package aurelienribon.utils.swing)
  3. ComponentAccessor.java (package aurelienribon.tweenaccessors.swing)

If you would like to experience my problem first hand, without complicated project setup, you may download the Eclipse Juno project, or the runnable jar file:

  • Imaffect Eclipse Juno Project
  • Imaffect Runnable Jar File

If you would prefer to stay away from downloads, here is a list of what's going on:

  1. Set up GUI structure
  2. Set up requirements for tween (nothing special)
  3. Set up a thread that uses SwingUtilities.invokeAndWait to call a function called update()
  4. Whenever update() is called, it uses Container.setSize() to animate size change on the JPanel that contains Button 1.

Any help with this problem is greatly appreciated! Thankyou :)

P.S. If there is a duplicate of this question, I am very sorry. I googled around quite a bit, but I was unable to find anything even related to my problem.

like image 465
Georges Oates Larsen Avatar asked Oct 22 '22 15:10

Georges Oates Larsen


1 Answers

I would say in your update() method you should change preferred size of Button1 and call

container.revalidate();
container.repaint();

Changing the preferred size and revalidate() updates layout and repaint() reflects the changes.

Alternatively you can call setSize() for Button1 increasing width and in the same time decrease width of Button2 and again call repaint() (without revalidate() because revalidation would restore original layout).

like image 168
StanislavL Avatar answered Oct 24 '22 10:10

StanislavL