在Java SE上使用Headless模式的超级指南_java

 这篇文章介绍怎样在标准Java(Java SE,也称作J2SE)平台上用Headless模式。

Headless模式是在缺少显示屏、键盘或者鼠标时的系统配置。听起来不可思议,但事实上你可以在这中模式下完成不同的操作,甚至是用图形数据也可以。

哪里才能用到此模式呢?想想你的应用不停的生成一张图片,比如,当用户每次登陆系统是都要生成一张认证图片。当创建图片时,你得应用既不需要显示器也不需要键盘。让我们假设一下,现在你的应用有个主架构或者专有服务器,但这个服务没有显示器,键盘或者鼠标。理想的决定是用环境的大量视觉计算能力而不是非视觉特性。在Headless模式下生成的图片可以传递到Headful系统进行更深层次渲染。

在java.awt.toolkit和java.awt.graphicsenvironment类中有许多方法,除了对字体,图像和打印的操作外还有调用显示器,键盘和鼠标的方法。但是有一些类中,比如Canvas 和 Panel,可以在headless模式下执行。在J2SE 1.4平台之后就提供了对Headless模式的支持。

注:这篇文章重点讲的是Java SE6 平台版本的文档。任何API的增加或其他增强Java SE平台的规范是由JSR270专家组(JSR 270 Expert Group.)的审查和批准。

Toolkit
java.awt.Toolkit类是Abstract Window Toolkit (AWT)的 所有实现类的抽象父类。Toolkit的子类用于把各种AWT组件绑定到特定的本地toolkit实现上去。

如果显示设备,键盘或鼠标不支持的话,很多组件都会受影响。一个合适的类构造器应当抛出一个HeadlessException异常:

  •     Button
  •     Checkbox
  •     Choice
  •     Dialog
  •     FileDialog
  •     Frame
  •     Label
  •     List
  •     Menu
  •     MenuBar
  •     MenuItem
  •     PopupMenu
  •     Scrollbar
  •     ScrollPane
  •     TextArea
  •     TextField
  •     Window

这种重量级的组件需要有一个操作系统级别上对等的图形函数来支持它,在headless的机器上它们将不能正常工作。

与Canvas、Panel和Image组件相关的组件不需要抛出HeadlessException异常,因为这些组件在操作系统级别上的对等图形函数可以使用空函数,然后作为轻量级组件来处理。

一个Headless的toolkit也会把Java组件绑定到本地资源上去,但是它只有在资源中不包含显示设备或输入设备时才会这样做。
Graphics Environment

java.awt.GraphicsEnvironment类是一个抽象类,它描述了在给定平台中,可以在Java技术中使用的由GraphicsDevice对象和Font对象组成的集合。该GraphicsEnvironment中的资源可以是本地的也可以是远程设备。GraphicsDevice对象可以是显示器,打印机或者图形缓存等,并且它们是Graphics2D 绘制函数的目标。每一个GraphicsDevice都有许多与之关联的GraphicsConfiguration对象。这些对象指定了不同的配置环境,在这些配置环境中可以使用GraphicsDevice。

Table 1 显示GraphicsEnvironment 方法,检查Headless模式支持
Table 1.  Headless 模式方法   

注意:isHeadless()方法检查特定的系统属性,java.awt.headless而不是系统的硬件配置.

HeadlessException 抛出的代码,这取决于display device、keyboard、mouse在一个环境称为不支持任何这些.唯一的例外是来自一个UnsupportedOperationException,本身就是来源于一个RuntimeException.
设置 Headless模式

使用Headless模式操作,您必须首先了解如何检查和设置系统属性与此相关的模式。此外,你必须了解如何创建一个默认的工具包使用工具箱的无头实现类.

系统属性配置

为了启用headless模式,需要使用setProperty()方法去设置相应的系统属性。本方法可以让你用期望的值来设置系统属性。
 

System.setProperty("java.awt.headless", "true");

上面的代码中,java.awt.headless是一个系统属性,true是我们设定的值。

如果你想在一个相同的程序中使用headless和传统环境,你可以使用下面的命令行来完成:

java -Djava.awt.headless=true 

创建默认Toolkit

如果名字为java.awt.headless的系统属性被设置为true,那么headless工具包就会被使用。接下来使用getDefaultToolkit()方法来创建一个headless toolkit的实例:
 

Toolkit tk = Toolkit.getDefaultToolkit();

Headless模式检查

要检查Headless模式的可用性,使用GraphicsEnvironment类的isHeadless()方法:
 

GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
boolean headless_check = ge.isHeadless();

该方法检查java.awt.headless系统属性。如果这个属性有一个为true的值,那么就会从工具包和依赖于一个显示器,键盘,鼠标的GraphicsEnvironment类的区域中抛出一个HeadlessException。
在Headless模式中操作

设置好headless模式并创建一个headless工具包的实例后,您的应用程序可以执行以下操作:

  •     创建轻量级组件,如Canvas,Panel,和Swing组件,除了top级别.
  •     收集关于可用的字体、字体指标和字体设置的信息
  •     设置颜色来渲染文本和图形
  •     创造和获取图像,为渲染准备图片
  •     使用java.awt.PrintJob, java.awt.print.*, 和 javax.print.* 类进行打印。
  •     发出"哔哔"音频。

Canvas(画布)

下面的代码会在屏幕上绘制出一个空白的矩形区域,你可以在上面绘制线条。可以使用Canvas类创建一个新的Canvas组件。
 

final Canvas c = new Canvas()
{
  public void paint(Graphics g)
  {
    Rectangle r = getBounds();
    g.drawLine(0, 0, r.width - 1, r.height - 1);
    g.drawLine(0, r.height - 1, r.width - 1, 0);
  }
};

Fonts(字体)

这段代码显示了怎么使用Font类画一个文本字符串并设置文字的字体。Graphics对象是用来绘制这个字符串的。
 

public void paint(Graphics g)
{
 g.setFont(new Font("Arial", Font.ITALIC, 12));
 g.drawString("Test", 32, 8);
}

Colors

这段代码显示了如何使用指定的红,绿,蓝的值来设置一条线的颜色。Graphics对象是用来绘制这条线的。
 

public void paint(Graphics g)
{
 g.setColor(new Color(255, 127, 0));
 g.drawLine(0, r.height - 1, r.width - 1, 0);
}

Images

在下面的代码中,javax.imageio.ImageIO类的使用read()方法对图1所示的grapefruit.jpg文件进行解码,并返回一个缓存图片。
 

Image i = null;
try
{
 File f = new File("grapefruit.jpg");
 i = ImageIO.read(f);
}
catch (Exception z)
{
 z.printStackTrace(System.err);
}

图1。grapefruit.jpg图像文件

Print

这段代码演示了如何打印已经准备好的画布,你可以使用paint方法自定义打印机的的默认画面。
 

PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(new Printable()
{
 public int print(Graphics g, PageFormat pf, int pageIndex)
 {
  if (pageIndex > 0)
  {
   return Printable.NO_SUCH_PAGE;
  }

  ((Graphics2D)g).translate(pf.getImageableX(),
         pf.getImageableY());

  // Paint canvas.
  c.paint(g);

  return Printable.PAGE_EXISTS;
 }
});

Beep

下面的这段代码展示了如果使用 Toolkit类的beep方法发出嘟嘟声。
 

Toolkit tk = Toolkit.getDefaultToolkit();
tk.beep();

使用Headless模式简单例子

以下的HeadlessBasics例子运用了文章中描述的所有功能。

要运行这个的例子,需要用javac对下面的代码进行编译。复制grapefruit.jpg图片文件到HeadlessBasics类所在的目录下面。
 

import java.awt.*;
import java.io.*;
import java.awt.print.*;

import javax.imageio.*;

public class HeadlessBasics
{
 public static void main(String[] args)
 {
  // Set system property.
  // Call this BEFORE the toolkit has been initialized, that is,
  // before Toolkit.getDefaultToolkit() has been called.
  System.setProperty("java.awt.headless", "true");

  // This triggers creation of the toolkit.
  // Because java.awt.headless property is set to true, this
  // will be an instance of headless toolkit.
  Toolkit tk = Toolkit.getDefaultToolkit();
  // Standard beep is available.
  tk.beep();

  // Check whether the application is
  // running in headless mode.
  GraphicsEnvironment ge =
  GraphicsEnvironment.getLocalGraphicsEnvironment();
  System.out.println("Headless mode: " + ge.isHeadless());

  // No top levels are allowed.
  boolean created = false;
  try
  {
   Frame f = new Frame("Frame");
   created = true;
  }
  catch (Exception z)
  {
   z.printStackTrace(System.err);
   created = false;
  }
  System.err.println("Frame is created: " + created);

  // No other components except Canvas and Panel are allowed.
  created = false;
  try
  {
   Button b = new Button("Button");
   created = true;
  }
  catch (Exception z)
  {
   z.printStackTrace(System.err);
   created = false;
  }
  System.err.println("Button is created: " + created);

  // Canvases can be created.
  final Canvas c = new Canvas()
  {
   public void paint(Graphics g)
   {
    Rectangle r = getBounds();
    g.drawLine(0, 0, r.width - 1, r.height - 1);
    // Colors work too.
    g.setColor(new Color(255, 127, 0));
    g.drawLine(0, r.height - 1, r.width - 1, 0);
    // And fonts
    g.setFont(new Font("Arial", Font.ITALIC, 12));
    g.drawString("Test", 32, 8);
   }
  };
  // And all the operations work correctly.
  c.setBounds(32, 32, 128, 128);

  // Images are available.
  Image i = null;
  try
  {
   File f = new File("grapefruit.jpg");
   i = ImageIO.read(f);
  }
  catch (Exception z)
  {
   z.printStackTrace(System.err);
  }
  final Image im = i;

  // Print system is available.
  PrinterJob pj = PrinterJob.getPrinterJob();
  pj.setPrintable(new Printable()
  {
   public int print(Graphics g, PageFormat pf, int pageIndex)
   {
    if (pageIndex > 0)
    {
     return Printable.NO_SUCH_PAGE;
    }
    ((Graphics2D)g).translate(pf.getImageableX(),
           pf.getImageableY());

    // Paint the canvas.
    c.paint(g);

    // Paint the image.
    if (im != null)
    {
     g.drawImage(im, 32, 32, 64, 64, null);
    }

    return Printable.PAGE_EXISTS;
   }
  });
  try
  {
   pj.print();
  }
  catch (Exception z)
  {
   z.printStackTrace(System.err);
  }
 }
}

图2显示了这个例子中的打印输出结果。

图2。HeadlessBasics的打印输出。

此外,你可以看到以下的信息:
 

Headless mode: true
java.awt.HeadlessException
at java.awt.GraphicsEnvironment.checkHeadless(Unknown Source)
at java.awt.Window.<init>(Unknown Source)
at java.awt.Frame.<init>(Unknown Source)
at HeadlessBasics.main(HeadlessBasics.java:24)
Frame is created: false
java.awt.HeadlessException
at java.awt.GraphicsEnvironment.checkHeadless(Unknown Source)
at java.awt.Button.<init>(Unknown Source)
at HeadlessBasics.main(HeadlessBasics.java:39)
Button is created: false

注:出于演示的目的,最初的代码会导致此应用程序抛出2个java.awt.HeadlessExceptions异常。

作为上一种方式的替代,你可以把标准输出信息放到一个文件中,然后把文件打印出来。在这种情况下,使用下面的命令行来运行这个例子:

java HeadlessBasics 2> standard_output.txt 

把现有的应用程序转换为Headless模式。

你怎么把现有的应用程序转换为可执行的headless模式?要执行此转换的最有效的方法是分析你的源代码以确定任何的功能都是依赖于Headless模式的。换句话说,要实现相同的功能,你必须找到那些会抛出HeadlessException异常的类和方法,然后使用独立的headless模式替换这些类和方法。

你可以使用Java SE 6 API说明来判断一个特定的类或方法是否支持headless模式。如果一个特定的组件不支持headless模式,你的程序需要捕获的唯一的异常是HeadlessException。它会在其它可能的异常之前被抛出。这也是为什么在本节的代码示例"举例: 使用Headless模式"中,没有什么特殊的必要性来捕获其它异常。

你肯定会发现其它有用的方法来使用headless模式带来的好处。我们希望本文能帮你完成此项任务,在Java SE平台中玩出一片新天地。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
Headless
java.awt.headless、java headless、java8runtimeheadless、iphonese 16g生存指南、苹果se手机操作指南,以便于您获取更多的相关知识。

时间: 2024-08-03 16:21:17

在Java SE上使用Headless模式的超级指南_java的相关文章

Java文件上传下载、邮件收发实例代码_java

文件上传下载 前台: 1. 提交方式:post 2. 表单中有文件上传的表单项: <input type="file" /> 3. 指定表单类型: 默认类型:enctype="application/x-www-form-urlencoded" 文件上传类型:multipart/form-data FileUpload 文件上传功能开发中比较常用,apache也提供了文件上传组件! FileUpload组件: 1. 下载源码 2. 项目中引入jar文件

简述Java异步上传文件的三种方式_java

本文为大家分享了三种Java异步上传文件方式,供大家参考,具体内容如下 用第三方控件,如Flash,ActiveX等浏览器插件上传. 使用隐藏的iframe模拟异步上传. 使用XMLHttpRequest2来实现异步上传. 第一种使用浏览器插件上传,需要一定的底层编码功底,在这里我就不讲了,以免误人子弟,提出这点大家可以自行百度. 第二种使用隐藏的iframe模拟异步上传.为什么在这里说的是模拟呢?因为我们其实是将返回结果放在了一个隐藏的iframe中,所以才没有使当前页面跳转,感觉就像是异步操

Java设计模式之中介者模式(Mediator Pattern)简介_java

Java设计模式的中介者模式是行为模式之一.定义一个中介对象来封装系列对象之间的交互.中介者使各个对象不需要显式地相互引用,从而使其耦合性松散,并且可以独立地改变他们之间的交互. 如下图所示: 生产者.消费者.代理商之间的中介模式实例: public abstract class PersonColleague { protected Mediator mediator; public Mediator getMediator() { return mediator; } public void

Java设计模式编程之解释器模式的简单讲解_java

0.解释器(Interpreter)模式定义 :给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子. 属于行为型模式. 解释器模式在实际的系统开发中使用的非常少,因为它会引起效率.性能以及维护等问题. 解释器模式的通用类图如图所示. 1.解释器模式的优点 解释器是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了. 2.解释器模式的缺点 解释器模式会引起类膨胀:每个语法

举例讲解Java设计模式编程中模板方法模式的运用实例_java

模板方法模式定义为: 在一个方法中定义了一个算法的骨架或者步骤,而将一些步骤延迟到子类中去实现.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某一些步骤. 模板方法在基类中定义了一个操作的流程顺序,能够保证该步骤按序进行,有一些步骤的具体实现在基类中已经声明,而将一些变化的步骤的具体实现交给了子类去实现,从而就达到了延迟一些步骤到子类中,模板方法一个最大的好处就是能够设定一个业务流程能够按照一定严格的顺序执行,控制了整个算法的执行步骤. 这个方法将算法定义成一组步骤,其中凡是想让

Java SE 6之GUI:让界面更加绚丽(上)

本文为原创,如需转载,请注明作者和出处,谢谢! 本文曾发表于天极网:http://dev.yesky.com/185/2690685.shtml Java SE 6之GUI:让界面更加绚丽(下) Java是一种非常强大的编程语言,但Java的GUI能力一直是它的软肋.虽然Java提供2种图形解决方案,AWT和Swing.但这2种图形库的功能十分有限,使用它们并不能带来更多的用户体验.而且AWT和Swing的更新速度很慢.一直到Java SE 5也没什么明显的变化.幸好Java SE 6终于为它们

Java SE 6在Solaris的可观察性特征分析

Java平台标准版(Java SE)6,代码名为"Mustang",是最新的Java SE发行版本(正在开发中).Java SE 6源码和二进制代码都可以在www.Java.net上下载.Java SE 6平台要到2006年秋天才能正式发布.不过,现在你可以下载试用Java SE 6 Beta版. Java SE 6平台中提供了多种可观察性(observability)工具,这其中的许多工具都可在系统中运行,而这些工具中的只有极少数被用于挂起进程或核心复制处理.因此,在本文中,我们将分

Java SE 6性能白皮书

1 简介 Java SE 6(Java Platform Standard Edition 6)的一个主要设计原则就是以性能缺陷为目标,通过当前最流行的一些 Java 基准测试以及与 Java 社区的紧密协作来确定对性能影响最大的增强关键领域,从而提高性能和可伸缩性. 本指南将概述 Java Standard Edition 6 中新增功能和可伸缩性改进,同时提供各种行业标准和内部开发的基准测试结果,以便演示这些性能改进的影响. 2 新增功能和性能增强 Java SE 6 引入了一些新的功能和性

Java SE 6之GUI:让界面更加绚丽(下)

本文为原创,如需转载,请注明作者和出处,谢谢! Java SE 6之GUI:让界面更加绚丽( 上) 在上一篇中我介绍了Java SE 6在GUI上的部分改进.在这篇 文章中我接着介绍另外几种新的GUI功能.这些功能是: 1.  带有排序和过滤功能的JTable. 2.  增强的JTabbedPane组件 3.  增强的打印功能 4.  增强的拖放功能 一.带有排序和过滤功能的JTable.     在Java SE 6中除了 java.awt被更新外,javax.swing同时也有了很大的改进.