这个问题讨论了JFrame扩展到Windows任务栏的已知错误。 答案链接到错误报告(具有各种重复项)并提供解决方法。 我发现问题也适用于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中修复。 这个错误报告以“如果开发人员想要在屏幕上完全显示他们的窗口,他们应该考虑检查屏幕插图本身[如下面的解决方案]” ,并以不同的方式重新布局他们的组件的评论关闭。在调用pack()之后手动重新调整窗口大小,或者使用支持screen-insets的布局管理器[与BorderLayout和GridBagLayout等更常见的布局管理器不同] 。
This question discusses a known bug where JFrames extend into the windows taskbar. An answer links to the bug report (which has various duplicates) and provides a workaround. I've discovered that the problem also holds for JDialogs. The JFrame workaround does not apply. Is there a similar workaround to make JDialogs behave themselves on windows?
Example code:
import javax.swing.*; public class Demo extends JDialog { public Demo() { setSize(250,12500); setVisible(true); } public static void main(String[] args) { new Demo(); } }Edit: It looks like this will not be fixed in the JDK. This bug report closes with the comment that "If a developer wants to keep their windows entirely visible on the screen, they should consider checking the screen insets themselves [like the solution below], and re-layout their component in a different way, or re-size the window manually after calling pack(), or use a screen-insets-aware layout manager [unlike more common ones like BorderLayout and GridBagLayout]."
最满意答案
这基本上可以确保对话框“适合”指定的屏幕,方法是将其移动到指定设备的范围内并缩小它,使其左下边缘在指定设备的范围内。
这将查看设备边界和插入,以计算对话框可以驻留的“安全”区域。
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; } }This will basically make sure that the dialog "fits" into the specified screen by moving it to be within the bounds of the specified device and shrinking it so that it's left and bottom edges are within the bounds of the specified device.
This looks at the devices bounds and insets to calculate the "safe" area that the dialog can reside.
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; } }更多推荐
发布评论