我有两个显示器
我编写了非常小的 Swing Java 代码来收集所有屏幕设备的信息,通过在控制面板中设置“显示”来结合更改显示模式与一两个显示屏。
代码如下:
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);
}
}
首先,我启动带有两个屏幕的程序,然后单击按钮(“打印信息屏幕设备”)。在输出中显示
Number of screen devices:2
正确!
接下来我更改为一种显示模式。最后,再次点击按钮,结果仍然是2。实际上只有1个屏幕设备。
我检查 GraphicsEnvironment.getLocalGraphicsEnvironment() 是否创建一个类似单例的实例。意思是不能更新?还有一件事,我不想关闭程序并再次打开。
像这种情况如何才能获得正确的屏幕设备信息?
我还希望Java将决定哪个类(扩展GraphicsEnvironment)提供屏幕设备的信息,取决于操作系统。
感谢您的提前!
最佳答案
这可能很棘手。但快速浏览一下源代码,您可能会尝试一些反射。
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...
...although I consider this as "unlikely", at least
以下示例展示了其工作原理:
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);
}
}
}
}
关于java - 关闭第二个屏幕后,图形环境不会更新屏幕设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26912360/