8

If i create non-resizable JFrames, and windows Aero is enabled setLocation does not seem to take account of the window border correctly.

In the following code I would expect the second frame to be positioned to the right of the first frame, instead the borders are overlapping. If Aero is disabled or if I remove the calls to setResizable this is done as expected.

import java.awt.Rectangle;
import javax.swing.JFrame;
public class FrameBorders {
public static void main(String[] args) {
    JFrame frame1 = new JFrame("frame 1");
    JFrame frame2 = new JFrame("frame 2");

    frame1.setResizable(false);
    frame2.setResizable(false);

    frame1.setVisible(true);        
    Rectangle bounds = frame1.getBounds();      
    frame2.setLocation(bounds.x+bounds.width, bounds.y);
    frame2.setVisible(true);

}
}

Am I doing something wrong or is this a bug? How can I display 2 unresizable dialogs side by side without having overlapping borders?

Edit: added screenshots (also changed frame2 to a JDialog instead of a JFrame)

Aero On: Aero On

Aero Off: Aero Off

Aero On but resizable: Aero On but resizable

msam
  • 4,259
  • 3
  • 19
  • 32
  • Why do you want to display 2 unresizable dialogs side by side without having overlapping borders? – Roman C Sep 21 '12 at 11:00
  • I want to display 2 windows which are initially positioned side by side – msam Sep 21 '12 at 11:03
  • 2
    Please don't set arbitrary bounds on a non-resizable container. See [*The Use of Multiple JFrames, Good/Bad Practice*](http://stackoverflow.com/a/9554657/230513)? – trashgod Sep 21 '12 at 11:11
  • whats happens when you to set JFrame#getRootPane().setBorder(someBorder);, because Areo has Shadows on the bottom and left side – mKorbel Sep 21 '12 at 11:15
  • @mKorbel setting the Border sets the internal Border but has no effect on the window border – msam Sep 21 '12 at 11:20
  • `1)` setting the Border sets the internal Border ---> sorry may bad I forgot that is for `Un_decorated JFrame`, `2)` then you have to calculating `Points` as pixels from shadows, could be different for each of themes, – mKorbel Sep 21 '12 at 11:24
  • @trashgod They can also be a JFrame and a JDialog as suggested in that post, or 2 JDialogs, the issue is still present. What are the problems with settings bounds on non-resizable containers? – msam Sep 21 '12 at 11:31
  • @mKorbel Not sure I understood but can I even get that information (the size of the extra border)? – msam Sep 21 '12 at 11:33
  • sorry right now I'm using WinXp, not able to use Win7 later, have to wait, but for better understanding for another readers to post here two screenshots with Areo on and off – mKorbel Sep 21 '12 at 11:37

2 Answers2

7

What are the problems with settings bounds on non-resizable containers?

Suppose you adjust the bounds to look good on your platform. Suppose the user's platform has a font with different, say larger, FontMetrics. This example is somewhat contrived, but you get the idea. If you change the bounds of a non-resizable container, be sure any text is visible regardless of the host platform's default font.

image

import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/**
 * @see http://stackoverflow.com/a/12532237/230513
 */
public class Evil extends JPanel {

    private static final String s =
        "Tomorrow's winning lottery numbers: 42, ";
    private JLabel label = new JLabel(s + "3, 1, 4, 1, 5, 9", JLabel.LEFT);

    public Evil() {
        this.add(label);
    }

    private void display() {
        JFrame f = new JFrame("Evil");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this, BorderLayout.WEST);
        f.pack();
        int w = SwingUtilities.computeStringWidth(
            label.getFontMetrics(label.getFont()), s);
        int h = f.getHeight();
        f.setSize(w, h);
        f.setResizable(false);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Evil().display();
            }
        });
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • This is a good point as far as resizing is concerned (and would be a good answer to the question I made in the comments if taken on its own), however my original problem is with positioning. Assume use of pack() / no text / size will not be changing or even empty dialogs/frames as in my own contrived example. – msam Sep 24 '12 at 06:51
  • 1
    Try `pack()`, which "Causes this `Window` to be sized to fit the preferred size and layouts of its subcomponents." Sorry, I don't use aero; an [sscce](http://sscce.org/) that exhibits the problem you describe may be helpful. – trashgod Sep 24 '12 at 11:15
  • pack() makes no difference in this case since the windows are empty (that's why i didn't include it in my example). Modified the code so that it's compilable (only added the imports and main class...). If you do not use Aero you will not have any problems with this code since this issue is only present with aero (see the screenshots) – msam Sep 24 '12 at 13:54
5

It seems that this is not a Java issue but rather an aero appcompat issue , as described here.

One solution that I see in Java is to let the windows be resizable then work around the setMaximumSize bug

Community
  • 1
  • 1
msam
  • 4,259
  • 3
  • 19
  • 32
  • Good link; the platform owns the frame decorations, so the result isn't _completely_ outrageous; `aqua` has its share of similar anomalies. – trashgod Sep 24 '12 at 18:33