views:

393

answers:

2

I have only JTabbedPane inside JFrame. JTabbedPane sets its dimensions to biggest page width/height. As pages has different size is it possible to force JTabbedPane to change its dimensions when selecting other page?

http://grab.by/3hIg

Top one is how it behave now and bottom one is how i want it to behave (i resized frame by hand)

+1  A: 

This is fairly simple. It involves dynamic calculation of differences between your pages dimensions and the using them to force preferred size on you JTabbedPane. I did a quick experiment and it worked. So instead of putting a lot of text here - here is the code. It is not perfect but you should get an idea. Questions are welcome, of course.

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Test {

    private static int maxW = 0;
    private static int maxH = 0;

    public static void main(String[] args) {


        final JFrame f = new JFrame();

        final JTabbedPane tabs = new JTabbedPane();

        tabs.add( createPanel(Color.RED, 100, 100), "Red");
        tabs.add( createPanel(Color.GREEN, 200, 200), "Green");
        tabs.add( createPanel(Color.BLUE, 300, 300), "Blue");

        final Dimension originalTabsDim = tabs.getPreferredSize();

        tabs.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {

                Component p =   ((JTabbedPane) e.getSource()).getSelectedComponent();
                Dimension panelDim = p.getPreferredSize();

                Dimension nd = new Dimension(
                        originalTabsDim.width - ( maxW - panelDim.width),
                        originalTabsDim.height - ( maxH - panelDim.height) );

                tabs.setPreferredSize(nd);

                f.pack();
            }

        });

        f.setContentPane(tabs);
        f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        f.pack();
        f.setLocationRelativeTo(null);

        f.setVisible(true);


    }

    private static final JPanel createPanel( Color color, int w, int h ) {

        JPanel p = new JPanel();
        p.setBackground(color);
        p.setPreferredSize( new Dimension(w, h));

        maxW = Math.max(w, maxW);
        maxH = Math.max(h, maxH);

        return p;

    }

}
eugener
Ok, that works great (even with scala-swing) but is it possible to do that without setting panel width and height?
teamon
Frame packs to the preferred size of it's content. You can have separate content page(with tabbed pane embedded) and set preferred dimension to it instead of tabbed pane itself, but you have to set it to something.
eugener
A: 

I think another option is to dynamically change the panels of each tab when the tab is selected:

  1. install a listener on JTabbedPane selection
  2. install an empty panel on every tab but the selected tab by default (that contains the real panel for that tab)
  3. in the selection listener:
    • remove the panel from the previously selected tab (ie, replace it with an empty panel)
    • change the empty panel by the real panel in the newly selected tab
    • call pack() on the window/dialog containing the JTabbedPane

Disclaimer: I haven't tested this approach but I believe it should work according to what you want.

Please also note that dynamically changing the size of the dialog based on the selected tab is not very user-friendly from a pure GUI viewpoint.

jfpoilpret