【问题标题】:JDialog on windows extends past the windows taskbar. Any workarounds?Windows 上的 JDialog 超出了 Windows 任务栏。任何解决方法?
【发布时间】:2012-11-13 22:04:15
【问题描述】:

This question 讨论了 JFrame 扩展到 Windows 任务栏的已知错误。 An answer 链接到错误报告(有各种重复)并提供解决方法。我发现这个问题也适用于 JDialogs。 JFrame 解决方法不适用。是否有类似的解决方法可以让 JDialogs 在 Windows 上表现自己?

示例代码:

import javax.swing.*;

public class Demo extends JDialog {
    public Demo() {
        setSize(250,12500);
        setVisible(true);
    }
    public static void main(String[] args) {
        new Demo();
    }
}

编辑:
看起来这不会在 JDK 中修复。 This bug report 以评论结束,“如果开发人员希望他们的窗口在屏幕上完全可见,他们应该考虑自己检查屏幕插图[如下面的解决方案],并重新布局他们的以不同的方式组件,或在调用 pack() 后手动调整窗口大小,或使用屏幕插入感知布局管理器[不像 BorderLayout 和 GridBagLayout 等更常见的布局管理器]。” p>

【问题讨论】:

  • setMaximumSize(new Dimension(x, y));?
  • 我希望有一个独立于分辨率的解决方案,就像链接的 JFrame 问题中的解决方案一样。
  • 你为什么设置这么大的尺寸?你能给我们一些关于你实际尝试做的事情的背景吗?
  • 我只是通过使 y 变得非常大来尽可能简单地揭示 JDK 错误。实际的界面是一个滚动窗格,上面有很多行,下面有一个 OK 按钮。在 Windows 上运行时,确定按钮被任务栏隐藏。
  • " 是否有类似的解决方法可以让 JDialogs 在 Windows 上表现自己?" 让它们比可用的屏幕尺寸小 10(?)%?

标签: java windows swing taskbar jdialog


【解决方案1】:

这将基本上确保对话框“适合”到指定的屏幕,方法是将其移动到指定设备的范围内并缩小它,使其左边缘和下边缘在指定设备的范围内。

这会查看设备边界和插图以计算对话框可以驻留的“安全”区域。

public class TestScreenSize {

    public static void main(String[] args) {
        new TestScreenSize();
    }

    public TestScreenSize() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                Test test = new Test();
                test.setLayout(new BorderLayout());
                test.setVisible(true);
                System.exit(0);
            }
        });
    }

    public class Test extends JDialog {

        public Test() {
            setModal(true);
            setLocation(0, 0);
            setSize(2000, 2000);
        }

        @Override
        public void setBounds(int x, int y, int width, int height) {
            Rectangle bounds = getSafeScreenBounds(new Point(x, y));
            if (x < bounds.x) {
                x = bounds.x;
            }
            if (y < bounds.y) {
                y = bounds.y;
            }
            if (width > bounds.width) {
                width = (bounds.x + bounds.width) - x;
            }
            if (height > bounds.height) {
                height = (bounds.y + bounds.height) - y;
            }
            super.setBounds(x, y, width, height);
        }

    }

    public static Rectangle getSafeScreenBounds(Point pos) {

        Rectangle bounds = getScreenBoundsAt(pos);
        Insets insets = getScreenInsetsAt(pos);

        bounds.x += insets.left;
        bounds.y += insets.top;
        bounds.width -= (insets.left + insets.right);
        bounds.height -= (insets.top + insets.bottom);

        return bounds;

    }

    public static Insets getScreenInsetsAt(Point pos) {
        GraphicsDevice gd = getGraphicsDeviceAt(pos);
        Insets insets = null;
        if (gd != null) {
            insets = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration());
        }
        return insets;
    }

    public static Rectangle getScreenBoundsAt(Point pos) {
        GraphicsDevice gd = getGraphicsDeviceAt(pos);
        Rectangle bounds = null;
        if (gd != null) {
            bounds = gd.getDefaultConfiguration().getBounds();
        }
        return bounds;
    }

    public static GraphicsDevice getGraphicsDeviceAt(Point pos) {

        GraphicsDevice device = null;

        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice lstGDs[] = ge.getScreenDevices();

        ArrayList<GraphicsDevice> lstDevices = new ArrayList<GraphicsDevice>(lstGDs.length);

        for (GraphicsDevice gd : lstGDs) {

            GraphicsConfiguration gc = gd.getDefaultConfiguration();
            Rectangle screenBounds = gc.getBounds();

            if (screenBounds.contains(pos)) {

                lstDevices.add(gd);

            }

        }

        if (lstDevices.size() > 0) {
            device = lstDevices.get(0);
        } else {
            device = ge.getDefaultScreenDevice();
        }

        return device;

    }
}

【讨论】:

  • frame.setExtendedState(frame.getExtendedState() | JFrame.ICONIFIED); frame.setExtendedState(frame.getExtendedState() & (~JFrame.ICONIFIED));
  • @mKorbel JDialog 没有扩展集 :(
  • 对,我的错……自动编译器打开了柜子中的一个抽屉,我想在早上刷新代码行...
  • 因为我使用模板。因为我个人不喜欢金属
【解决方案2】:

好的,下面没有魔法,但就像 max(a,b) 一样简单:

import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Toolkit;

import javax.swing.JDialog;

public class Demo extends JDialog {
   public Demo() {
      super((Frame)null, "Demo" );
      setDefaultCloseOperation( DISPOSE_ON_CLOSE );

      Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
      int width  = Math.min(    250, screenSize.width );
      int height = Math.min( 12_500, screenSize.height );
      pack();
      setSize( width, height );
      setVisible( true );
   }
   public static void main( String[] args ) {
      new Demo();
   }
}

【讨论】:

  • setSize()之前不要忽略pack()
  • getScreenSize 不会考虑任务栏,它是屏幕的原始分辨率。
猜你喜欢
  • 2011-12-21
  • 2010-11-27
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
  • 2010-12-18
相关资源
最近更新 更多