问题
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 Off:
Aero On but resizable:
回答1:
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.
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();
}
});
}
}
回答2:
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
来源:https://stackoverflow.com/questions/12529200/non-resizable-window-border-and-positioning