【问题标题】:Get effective screen size from Java从 Java 中获取有效的屏幕尺寸
【发布时间】:2012-04-12 12:37:11
【问题描述】:

我想获得有效的屏幕尺寸。即:没有任务栏的屏幕大小(或 Linux/Mac 上的等价物)。

我目前正在使用...

component.getGraphicsConfiguration().getBounds()

...并根据操作系统减去默认任务栏大小,但我想要一种即使用户调整/移动任务栏也能工作的方法。

【问题讨论】:

    标签: java swing awt


    【解决方案1】:

    GraphicsEnvironment 有一个方法可以返回最大可用大小,计算所有任务栏等,无论它们在哪里对齐:

    GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds()
    

    注意:在多显示器系统上,getMaximumWindowBounds() 返回整个显示区域的边界。要获得单个显示器的可用边界,请使用 GraphicsConfiguration.getBounds()Toolkit.getScreenInsets(),如其他答案所示。

    【讨论】:

    • 在我的情况下,它返回整个高度。 (当任务栏是透明的并且窗口可以在下方时)
    【解决方案2】:

    这可以确定没有任务栏的屏幕大小(以像素为单位)

    //size of the screen
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    
    //height of the task bar
    Insets scnMax = Toolkit.getDefaultToolkit().getScreenInsets(getGraphicsConfiguration());
    int taskBarSize = scnMax.bottom;
    
    //available size of the screen 
    setLocation(screenSize.width - getWidth(), screenSize.height - taskBarSize - getHeight());
    

    编辑

    有人可以在 Xx_nix 和 Mac OSX 上运行此代码并检查 JDialog 是否真的放在右下角吗?

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.UIManager.LookAndFeelInfo;
    
    public class NotificationPopup {
    
        private static final long serialVersionUID = 1L;
        private LinearGradientPaint lpg;
        private JDialog dialog = new JDialog();
        private BackgroundPanel panel = new BackgroundPanel();
    
        public NotificationPopup() {
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            Insets scnMax = Toolkit.getDefaultToolkit().
                    getScreenInsets(dialog.getGraphicsConfiguration());
            int taskBarSize = scnMax.bottom;
            panel.setLayout(new GridBagLayout());
            GridBagConstraints constraints = new GridBagConstraints();
            constraints.gridx = 0;
            constraints.gridy = 0;
            constraints.weightx = 1.0f;
            constraints.weighty = 1.0f;
            constraints.insets = new Insets(5, 5, 5, 5);
            constraints.fill = GridBagConstraints.BOTH;
            JLabel l = new JLabel("You have got 2 new Messages.");
            panel.add(l, constraints);
            constraints.gridx++;
            constraints.weightx = 0f;
            constraints.weighty = 0f;
            constraints.fill = GridBagConstraints.NONE;
            constraints.anchor = GridBagConstraints.NORTH;
            JButton b = new JButton(new AbstractAction("x") {
    
                private static final long serialVersionUID = 1L;
    
                @Override
                public void actionPerformed(final ActionEvent e) {
                    dialog.dispose();
                }
            });
            b.setOpaque(false);
            b.setMargin(new Insets(1, 4, 1, 4));
            b.setFocusable(false);
            panel.add(b, constraints);
            dialog.setUndecorated(true);
            dialog.setSize(300, 100);
            dialog.setLocation(screenSize.width - dialog.getWidth(),
                    screenSize.height - taskBarSize - dialog.getHeight());
            lpg = new LinearGradientPaint(0, 0, 0, dialog.getHeight() / 2,
                    new float[]{0f, 0.3f, 1f}, new Color[]{new Color(0.8f, 0.8f, 1f),
                        new Color(0.7f, 0.7f, 1f), new Color(0.6f, 0.6f, 1f)});
            dialog.setContentPane(panel);
            dialog.setVisible(true);
        }
    
        private class BackgroundPanel extends JPanel {
    
            private static final long serialVersionUID = 1L;
    
            BackgroundPanel() {
                setOpaque(true);
            }
    
            @Override
            protected void paintComponent(final Graphics g) {
                final Graphics2D g2d = (Graphics2D) g;
                g2d.setPaint(lpg);
                g2d.fillRect(1, 1, getWidth() - 2, getHeight() - 2);
                g2d.setColor(Color.BLACK);
                g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
            }
        }
    
        public static void main(final String[] args) {
            try {
                for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                    System.out.println(info.getName());
                    if ("Nimbus".equals(info.getName())) {
                        UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            } catch (UnsupportedLookAndFeelException e) {
            } catch (ClassNotFoundException e) {
            } catch (InstantiationException e) {
            } catch (IllegalAccessException e) {
            }
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
    
                    NotificationPopup notificationPopup = new NotificationPopup();
                }
            });
        }
    }
    

    【讨论】:

    • 它可能可以修复,但看起来这在多屏幕设置中不起作用。
    • 有两个层次,是什么意思??? 1) 一个容器填充两个或多个 multi_monitor(未在 Java7 中测试,但不支持 Java6),或 2) 一个容器放置在其中一个 multi_monitors 上(由 alain.janinm 回答),
    • @mKorbel:在单屏 Mac 上测试正常。 @Rasmus:您可以在GraphicsEnvironment 中获取任何GraphicsDevice 和可用GraphicsConfiguration 的边界。
    • @mKorbel:如果对话框没有放在主屏幕上,您的代码会出现问题:screenSize 将是主屏幕的大小,但 scnMax 将是屏幕插图对话框所在的屏幕。此外,某些平台(例如较新版本的 Ubuntu)的任务栏位于左侧。话虽如此,这些问题很容易解决,我希望在完成测试后接受您的回答。
    • @Rasmus Faber 抱歉,我不是具有 GUI 界面的 Xxx_nix 用户(不包括 WinOS),然后我无法测试放置在左侧的工具栏,顺便说一句,这就是我发送测试请求的原因Xx_nix 和 Mac OSX
    【解决方案3】:

    这是我最终使用的代码:

    GraphicsConfiguration gc = // ...
    
    Rectangle bounds = gc.getBounds();
    
    Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
    
    Rectangle effectiveScreenArea = new Rectangle();
    
    effectiveScreenArea.x = bounds.x + screenInsets.left;
    effectiveScreenArea.y = bounds.y + screenInsets.top;
    effectiveScreenArea.height = bounds.height - screenInsets.top - screenInsets.bottom;        
    effectiveScreenArea.width = bounds.width - screenInsets.left - screenInsets.right;
    

    【讨论】:

    • @mKorbel:我已经在 Ubuntu、OS X 和 Windows 7 上对其进行了测试。一旦应用程序进入测试阶段,它将在更多平台上进行测试(我一定会在这里指出,如果我们在任何地方遇到问题)。
    【解决方案4】:

    这是我编写的一种方法,通过减去边距并将其在屏幕中居中快速进行计算。

    public void setToEffectiveScreenSize() {
        double width, height, x, y;
    
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Insets bounds = Toolkit.getDefaultToolkit().getScreenInsets(frmMain.getGraphicsConfiguration());
    
        // Calculate the height/length by subtracting the margins
        // (x,y) = ( (screenHeight-windowHeight)/2, (screenWidth - windowWidth)/2 )
    
        width = screenSize.getWidth() - bounds.left - bounds.right;
        height = screenSize.getHeight() - bounds.top - bounds.bottom;
    
        // Now center the new rectangle inside the screen
        x = (screenSize.getHeight() - height) / 2.0;
        y = (screenSize.getWidth() - width) / 2.0;
    
        frmMain.setBounds((int)x,(int)y,(int)width,(int)height);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-29
      • 1970-01-01
      • 2015-07-31
      • 2011-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多