今天看了《Developing Games in Java》的Full-Screen Graphics这一章感觉很有用,故现在将它摘录下来,供以后参考:
在Java中切换到全屏模式,需要知道的类有三个:
- Window类:它作为一个容器,用于承载屏幕中显示的内容,它是一个描象类,在这里使用它的子类JFrame。
- DislayMode类:它指定屏幕显示的一些属性,如:分辨率,颜色深度和屏幕刷新率。
- GraphicesDevice类:它实质的控制显示器显示的模式与属性。它被视为显卡的接口。GraphicesDevice对象是通过GraphicsEnvironment 对象得到的。
下面是的例子显示了互换至全屏模式的具体作法:
JFrame window = new JFrame();
// 这里的三个参数分别指的是:水平像素,垂直像素,颜色深度和屏幕刷新率(单位是HZ)
DisplayMode displayMode = new DisplayMode(800, 600, 16, 75);
// 得到GraphicsDevice对象
GraphicsEnvironment environment =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = environment.getDefaultScreenDevice();
// 将JFrame作为全屏窗体显示
device.setFullScreenWindow(window);
// 改变显示模式
device.setDisplayMode(displayMode);
回过头来,当切换至原先显示的模式时,只需将
window对象改为
null:
device.setFullScreenWindow(null);
注意:这里的代码还不全善,有些系统不允许切换至全屏模式时,调用 setDisplayMode()方法会抛出IllegalArgumentException异常。
默认状态下JFrame还会保留显示边框和标题栏,因此在全屏模式下通过调用JFrame对象的setUndecorated(true)来将其去除掉。同时当显示器退出全屏重加载时JFrame对象需要调用dispose()方法来消毁释放。这些操作在这里通过一个简单的SimpleScreenManager类来进行封装:
import java.awt.*;
import javax.swing.JFrame;
/**
* SimpleScreenManager类管理初始化和全屏显示
*/
public class SimpleScreenManager {
private GraphicsDevice device;
public SimpleScreenManager() {
GraphicsEnvironment environment =
GraphicsEnvironment.getLocalGraphicsEnvironment();
device = environment.getDefaultScreenDevice();
}
// 进入全屏模式
public void setFullScreen(DisplayMode displayMode, JFrame window) {
window.setUndecorated(true);
window.setResizable(false);
device.setFullScreenWindow(window);
if(displayMode != null && device.isDisplayChangeSupported()) {
try {
device.setDisplayMode(displayMode);
}catch(IllegalArgumentException ex) {
//系统不支持此模式时执行
}
}
}
// 返回当前全屏窗口window对象
public Window getFullScreenWindow() {
return device.getFullScreenWindow();
}
// 重载当前屏幕的显示模式,即退出全屏
public void restoreScreen() {
Window window = device.getFullScreenWindow();
if (window != null) {
window.dispose();
}
device.setFullScreenWindow(null);
}
}
下面编写一个测试类FullScreenTest,它切换至全屏模式在屏幕上显示“Hello World”5秒钟后自动退出。运行时可接收三个参数,即:水平的像素值、垂直的像素值和颜色深色,默认为800x600 16颜色深度,运行时可如下指定自定义的属性值:
java FullScreenTest 1024 768 32
对应的代码如下:
import java.awt.*;
import javax.swing.JFrame;
public class FullScreenTest extends JFrame {
public static void main(String[] args) {
DisplayMode displayMode;
if(args.length == 3) {
displayMode = new DisplayMode (
Integer.parseInt(args[0]),
Integer.parseInt(args[1]),
Integer.parseInt(args[2]),
DisplayMode.REFRESH_RATE_UNKNOWN);
} else {
displayMode = new DisplayMode(800, 600, 16,
DisplayMode.REFRESH_RATE_UNKNOWN);
}
FullScreenTest test = new FullScreenTest();
test.run(displayMode);
}
private static final long DEMO_TIME = 5000;
public void run(DisplayMode displayMode) {
setBackground(Color.blue);
setForeground(Color.white);
setFont(new Font("Dialog", Font.PLAIN, 78));
SimpleScreenManager screen = new SimpleScreenManager();
try {
screen.setFullScreen(displayMode, this);
try {
Thread.sleep(DEMO_TIME);
}catch(InterruptedException ex) {
}
} finally {
screen.restoreScreen();
}
}
public void paint(Graphics g) {
g.drawString("Hello Wrold!", 200, 500);
}
}
在显示时你会发现显示的字体边缘有距尺,很不光滑:
这就需要渲染处理一下,使字体的变的模糊一些来达到边缘与当前背景的隔合,实现光滑,而这需要使用Graphics2D对象,回过头来观察paint()方法接收一个Graphics对象来做为参数,进行图行的绘制。其实质上从Java SDK1.2开始为Graphics2D对象,pait()方法是一个老方法了。现更改pait()如下:
public void paint(Graphics g) {
if(g instanceof Graphics2D) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint (
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
g.drawString("Hello Wrold!", 200, 500);
}
这里的渲染处理是通过调用setRenderingHint()方法实现的,将对应的渲染处理在绘制几何图行或文字之前调用,就可实现对对应图形的渲染。这样的渲染其实还有很多,具体的可以参考ReneringHints类的相关API或文档来了解。
最终实现的效果如下: