29

I would like to get the effective screen size. That is: the size of the screen without the taskbar (or the equivalent on Linux/Mac).

I am currently using...

component.getGraphicsConfiguration().getBounds()

...and subtracting the default taskbar size depending on the OS, but I would like a way that works even if the user has resized/moved the taskbar.

Nathan
  • 8,093
  • 8
  • 50
  • 76
Rasmus Faber
  • 48,631
  • 24
  • 141
  • 189

4 Answers4

59

GraphicsEnvironment has a method which returns the maximum available size, accounting all taskbars etc. no matter where they are aligned:

GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds()

Note: On multi-monitor systems, getMaximumWindowBounds() returns the bounds of the entire display area. To get the usable bounds of a single display, use GraphicsConfiguration.getBounds() and Toolkit.getScreenInsets() as shown in other answers.

Nathan
  • 8,093
  • 8
  • 50
  • 76
moeTi
  • 3,884
  • 24
  • 37
  • 5
    In my case it returns whole height. (when taskbar is transparent and windows could go below) – Lukino Jan 26 '15 at 10:39
44

This could determine the screen size in pixels without the taskbar

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

EDIT

Can someone please run this code on Xx_nix and Mac OSX and check if JDialog is really placed in the bottom right corner?

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();
            }
        });
    }
}
ave4496
  • 2,950
  • 3
  • 21
  • 48
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • 3
    It can probably be fixed, but it looks like this won't work in a multi-screen setup. – Rasmus Faber Apr 12 '12 at 16:20
  • there are two levels, are meaning ??? `1)` one container fills two or more multi_monitors (not tested in Java7, but Java6 not supported), or `2)` one container placed on one of multi_monitors (answered by alain.janinm), – mKorbel Apr 12 '12 at 17:03
  • @mKorbel: Tested OK on a single-screen Mac. @Rasmus: You can get the bounds of any [`GraphicsDevice`](http://docs.oracle.com/javase/6/docs/api/java/awt/GraphicsDevice.html) and available `GraphicsConfiguration` in the `GraphicsEnvironment`. – trashgod Apr 12 '12 at 18:13
  • 1
    @mKorbel: Your code will have problems if the dialog is not placed on the primary screen: `screenSize` will be the size of the primary screen, but `scnMax` will be the screen-insets of the screen the dialog is placed on. Also, some platforms (such as newer versions of Ubuntu) has the taskbar placed on the left side. That being said, those problems are easily fixed, and I expect to accept your answer once I have completed testing. – Rasmus Faber Apr 12 '12 at 18:55
  • @Rasmus Faber sorry I'm not Xxx_nix user (excluding WinOS) with GUI interface, then I can't to testing toolbar placed on the left side, btw that's reason I sent my ask for testing on Xx_nix and Mac OSX – mKorbel Apr 12 '12 at 20:00
  • 1
    I have marked this as the answer, but see also [my own answer below](http://stackoverflow.com/a/10139113/5542), which fixes the problems with multiple monitors and taskbars that are placed in the side or top of the screen. I have tested that code on Ubuntu 10.04, Ubuntu 10.10, Windows 7 and Mac OS X 10.7. – Rasmus Faber Apr 13 '12 at 11:09
15

Here is the code I ended up using:

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;
Rasmus Faber
  • 48,631
  • 24
  • 141
  • 189
  • 1
    @mKorbel: I have tested it on Ubuntu, OS X and Windows 7. It will be tested on several more platforms once the application moves to test (and I will be sure to note here, if we encounter issues anywhere). – Rasmus Faber Apr 13 '12 at 11:11
3

Here's a method I wrote to quickly do the calculations by subtracting the margins and centering it in the screen.

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);
}
server_kitten
  • 386
  • 3
  • 13