GraphicalEnvironment关闭第二个屏幕后不更新屏幕设备 [英] GraphicalEnvironment does not update screen devices after switching off second screen

查看:190
本文介绍了GraphicalEnvironment关闭第二个屏幕后不更新屏幕设备的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个监视器结果
我写的非常小的Java Swing的code,收集所有的屏幕设备的信息结合起来通过控制面板中设置显示改变显示模式有一个或两个显示屏。
和code象下面这样:

I have two monitors
I write very small Swing Java code to collect info of all screen devices combine changing display mode with one or two display screen by setting Display in Control Panel. And code like below:

import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;


public class Main {

    public static void main(String[] args) {
        final JFrame frame = new JFrame("Demo get info screen devices");
        JButton button = new JButton("Print info screen devices");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                printInfoAllScreenDevices();
            }
        });
        frame.add(button);
        frame.setSize(500, 300);
        frame.setVisible(true);
    }
    private static void printInfoAllScreenDevices() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] graphicsDevices = ge.getScreenDevices();
        System.out.println("Number of screen devices:" + graphicsDevices.length);
    }
} 

首先,我开始与两个屏幕的程序,然后我点击按钮(打印信息屏幕设备)。在输出显示

First I start program with two screens and then I click to button ("Print info screen devices"). In output shows

Number of screen devices:2

正确!结果
接下来,我改变了一个显示模式。最后,再次点击按钮,导致仍然2.其实只有1屏幕设备。结果
我检查GraphicsEnvironment.getLocalGraphicsEnvironment()创​​建这样一个单实例。这意味着不能更新?还有一件事,我不想再接近PROGRAME和开放。结果
我怎样才能得到这样的情况下,屏幕的设备的正确的信息?结果
而且我也希望Java将决定哪些类(扩展GraphicsEnvironment中)提供屏幕设备的信息,依赖于操作系统。结果
感谢您的前进!

Correct!
Next I changed to one display mode. Finally, click button again and result still 2. Actually only 1 screen device.
I check that GraphicsEnvironment.getLocalGraphicsEnvironment() create a instance like singleton. It means can not update? One more thing, I don't want close programe and open again.
How can I get right information of screen devices like this case?
And I also want Java will decide which class (extend GraphicsEnvironment) provide info of screen devices, depend on operation system.
Thanks for your advance!

推荐答案

这可能会非常棘手。但是,从快看看源$ C ​​$ C,你可以尝试一些反思。

It may be tricky. But from a quick look at the source code, you might try some reflection.

免责声明:很多东西都可以使用反射时出错。你应该知道,你是依靠不确定的行为在这里的事实。如果底层实现的改变,那么下面的示例程序可能不再工作...

Disclaimer: Many things can go wrong when using reflection. You should be aware of the fact that you are relying on unspecified behavior here. If the underlying implementation changes, then the following example program might no longer work...

...虽然我认为这是不可能的,至少

以下是演示如何这可能工作的例子:

The following is an example showing how this might work:

import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class GraphicsEnvironmentTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("Demo get info screen devices");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton button = new JButton("Print info screen devices");
        button.addActionListener(new ActionListener()
        {

            @Override
            public void actionPerformed(ActionEvent e)
            {
                printInfoAllScreenDevices();
            }
        });
        frame.add(button);
        frame.setSize(500, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static void printInfoAllScreenDevices() 
    {
        GraphicsDevice graphicsDevices[] = getGraphicsDevices();
        System.out.println("Found "+graphicsDevices.length+" devices:");
        for (int i=0; i<graphicsDevices.length; i++)
        {
            System.out.println(graphicsDevices[i]);
        }
    }

    /**
     * Queries the local graphics environment for the available graphics
     * devices. This uses reflection internally. If anything goes wrong
     * with the reflective call, a RuntimeException will be thrown.
     * 
     * @return The available graphics devices.
     * @throws RuntimeException If the reflective calls fail
     */
    private static GraphicsDevice[] getGraphicsDevices() 
    {
        GraphicsEnvironment graphicsEnvironment = 
            GraphicsEnvironment.getLocalGraphicsEnvironment();
        Class<?> c = graphicsEnvironment.getClass();
        Method getNumScreensMethod = null;
        boolean getNumScreensMethodWasAccessible = false; 
        Method makeScreenDeviceMethod = null;
        boolean makeScreenDeviceMethodWasAccessible = false;
        try
        {
            getNumScreensMethod = 
                c.getDeclaredMethod("getNumScreens");
            getNumScreensMethodWasAccessible =
                getNumScreensMethod.isAccessible();
            getNumScreensMethod.setAccessible(true);

            makeScreenDeviceMethod = 
                c.getDeclaredMethod("makeScreenDevice", int.class);
            makeScreenDeviceMethodWasAccessible =
                makeScreenDeviceMethod.isAccessible();
            makeScreenDeviceMethod.setAccessible(true);

            int numScreens = 
                (Integer) getNumScreensMethod.invoke(graphicsEnvironment);
            GraphicsDevice graphicsDevices[] = new GraphicsDevice[numScreens];
            for (int i = 0; i < numScreens; i++)
            {
                Object object = 
                    makeScreenDeviceMethod.invoke(graphicsEnvironment, i);
                graphicsDevices[i] = (GraphicsDevice) object;
            }
            return graphicsDevices;
        }
        catch (NoSuchMethodException e)
        {
            throw new RuntimeException(e);
        }
        catch (SecurityException e)
        {
            throw new RuntimeException(e);
        }
        catch (IllegalAccessException e)
        {
            throw new RuntimeException(e);
        }
        catch (IllegalArgumentException e)
        {
            throw new RuntimeException(e);
        }
        catch (InvocationTargetException e)
        {
            throw new RuntimeException(e);
        }
        finally
        {
            if (getNumScreensMethod != null)
            {
                getNumScreensMethod.setAccessible(
                    getNumScreensMethodWasAccessible);
            }
            if (makeScreenDeviceMethod != null)
            {
                makeScreenDeviceMethod.setAccessible(
                    makeScreenDeviceMethodWasAccessible);
            }
        }
    }

}

这篇关于GraphicalEnvironment关闭第二个屏幕后不更新屏幕设备的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆