2

I have a JDialog with just a few components inside it. I want to make the dialog as small as possible. Currently I am using pack(). This has the unintended effect of reducing the dialog's width so much that the title is no longer completely in view. I want the dialog's width to always be great enough such that the title is always completely in view.

I am using swing. I realize that the title bar appearance/font is determined by the OS. I would prefer to stick with swing so at the moment i am planning on calculating the title string width based on the font of a JLabel. Then I will set the minimum width of one of my components equal to that.

Is there any better way to pack a JDialog while keeping its title visible?

Justin Wiseman
  • 780
  • 1
  • 8
  • 27

2 Answers2

6
 public static void adjustWidthForTitle(JDialog dialog)
{
    // make sure that the dialog is not smaller than its title
    // this is not an ideal method, but I can't figure out a better one
    Font defaultFont = UIManager.getDefaults().getFont("Label.font");
    int titleStringWidth = SwingUtilities.computeStringWidth(new JLabel().getFontMetrics(defaultFont),
            dialog.getTitle());

    // account for titlebar button widths. (estimated)
    titleStringWidth += 110;

    // set minimum width
    Dimension currentPreferred = dialog.getPreferredSize();

    // +10 accounts for the three dots that are appended when the title is too long
    if(currentPreferred.getWidth() + 10 <= titleStringWidth)
    {
        dialog.setPreferredSize(new Dimension(titleStringWidth, (int) currentPreferred.getHeight()));

    }
}

EDIT: after reading trashgod's post in the link, I adjusted my solution to override the getPreferredSize method. I think this way is better than my previous static method. Using the static method, I had to adjust it in a pack() sandwich. pack(),adjust(),pack(). This wasy doesn't require special consideration with pack().

JDialog dialog = new JDialog()
    {
        @Override
        public Dimension getPreferredSize()
        {
            Dimension retVal = super.getPreferredSize();

            String title = this.getTitle();

            if(title != null)
            {
                Font defaultFont = UIManager.getDefaults().getFont("Label.font");
                int titleStringWidth = SwingUtilities.computeStringWidth(new JLabel().getFontMetrics(defaultFont),
                        title);

                // account for titlebar button widths. (estimated)
                titleStringWidth += 110;

                // +10 accounts for the three dots that are appended when
                // the title is too long
                if(retVal.getWidth() + 10 <= titleStringWidth)
                {
                    retVal = new Dimension(titleStringWidth, (int) retVal.getHeight());
                }
            }
            return retVal;
        }

    };
Justin Wiseman
  • 780
  • 1
  • 8
  • 27
  • It's good that you use the preferred size as a basis, but consider: [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing](http://stackoverflow.com/q/7229226/230513)? – trashgod Sep 20 '12 at 19:36
  • Thanks for the link. I'm not sure how I would get a layout manager like form layout to accomplish this, but I took your advice about overriding getPreferredSize – Justin Wiseman Sep 21 '12 at 00:15
  • Thanks for bearing with me; +1 from yesterday. Sorry, I don't understand "form layout" in this context. – trashgod Sep 21 '12 at 00:34
  • JGoodies FormLayout is my goto layout manager. I don't think that it, or any other layout manager that I am aware of, is set up to handle window resizing. The accepted answer in your link seems to make the case that using layout managers should always be done instead of using setSize(). Is my case an exception? – Justin Wiseman Sep 21 '12 at 01:23
  • Ah, [`FormLayout`](http://www.jgoodies.com/freeware/libraries/forms/); still todo. :-) The accepted answer made the case _against_ `setPreferredSize()`; your calculation of `getPreferredSize()` based on the preferred size seems reasonable. Sadly, I can't think of a better estimate for the frame decorations. I'm wary of the whole exercise: I've got one too many closed-source, commercial applications featuring a non-resizable frame that probably looks _fine_ on the _developer's_ L&F. – trashgod Sep 21 '12 at 01:48
1

1) Use FontMetrics to find out the width of your title

2) Add to this value a number representing the window icon and the X (close) button (you should guess that).

3) Set the dialog's width with the above value.

You can't find the exact width size you need but this is a way to make a good guess.

Rempelos
  • 1,220
  • 10
  • 18