【问题标题】:non resizable window border and positioning不可调整大小的窗口边框和定位
【发布时间】:2012-09-13 19:08:48
【问题描述】:

如果我创建不可调整大小的 JFrame,并且启用了 windows Aero setLocation 似乎没有正确考虑窗口边框。

在下面的代码中,我希望第二帧位于第一帧的右侧,而不是边框​​重叠。如果 Aero 被禁用,或者如果我删除了对 setResizable 的调用,这将按预期完成。

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);

}
}

我做错了什么还是这是一个错误? 如何在不重叠边框的情况下并排显示 2 个不可调整大小的对话框?

编辑:添加屏幕截图(还将 frame2 更改为 JDialog 而不是 JFrame)

航空开启:

航空关闭:

Aero 开启但可调整大小:

【问题讨论】:

  • 为什么要并排显示 2 个不可调整大小的对话框而没有重叠的边框?
  • 我想显示 2 个最初并排放置的窗口
  • 请不要在不可调整大小的容器上设置任意边界。见The Use of Multiple JFrames, Good/Bad Practice?
  • 设置 JFrame#getRootPane().setBorder(someBorder); 会发生什么,因为 Areo 在底部和左侧都有阴影
  • @mKorbel 设置Border 设置内部Border 但对窗口边框没有影响

标签: java windows swing aero absolutelayout


【解决方案1】:

在不可调整大小的容器上设置边界有什么问题?

假设您调整边界以在您的平台上看起来不错。假设用户的平台有一个不同的字体,比如更大的FontMetrics。这个例子有点做作,但你明白了。如果您更改不可调整大小的容器的边界,请确保任何文本都可见,而不管主机平台的默认字体如何。

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();
            }
        });
    }
}

【讨论】:

  • 就调整大小而言,这是一个很好的观点(如果单独考虑我在 cmets 中提出的问题,这将是一个很好的答案),但是我最初的问题是定位。假设使用 pack() / no text / size 不会改变,甚至不会像我自己设计的示例那样空对话框/框架。
  • 尝试pack(),它会“使Window 的大小适合其子组件的首选大小和布局。”对不起,我不使用航空;显示您描述的问题的sscce 可能会有所帮助。
  • pack() 在这种情况下没有区别,因为窗口是空的(这就是为什么我没有在我的示例中包含它)。修改了代码使其可编译(仅添加了导入和主类...)。如果您不使用 Aero,则此代码不会有任何问题,因为此问题仅存在于 aero(请参见屏幕截图)
【解决方案2】:

这似乎不是 Java 问题,而是 aero appcompat 问题,如 here 所述。

我在 Java 中看到的一个解决方案是让窗口可调整大小,然后解决 setMaximumSize bug

【讨论】:

  • 好链接;平台拥有框架装饰,因此结果并不完全离谱; aqua 也有类似的异常情况。
猜你喜欢
  • 2011-02-25
  • 2013-07-12
  • 1970-01-01
  • 2011-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多