服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

给java程序穿花衣


  经常听朋友说,java编写的程序界面比较单一,不好进行个性化配置。现在让我们一起来了解有关java界面样式相关类的知识,以及如何用java写出变幻莫测的用户界面,让java程序也拥有时髦的换肤功能。
  实现原理
  java平台成熟后,设计人员与开发人员就认识到需要连续性好、兼容性好、容易使用的java程序界面。这时sun就推出了“look and feel”机制迎合这种需求。它提供了一种独特的、与平台无关的程序外观,以及标准的界面行为。它可以在各个平台上使用同一“look and feel”,从而缩短设计与开发周期,降低软件使用人员的培训费用。这是“look and feel”设计的初衷。现在我们来使用这种特性为java程序穿上花衣。
  
  要让java程序具备换肤功能,首先要求有以下jdk版本:
  
  1.sun jdk1.1.7b/swing1.1.1 (windows);
  
  2.sun jdk1.2.2 (windows、solaris、 linux);
  
  3.sun jdk 1.3 或以上版本 (windows)。
  
  我们先来熟悉“look and feel”几个相关的类以及api,以便来理解我们的换肤术。与“look and feel”密切相关的是lookandfeel抽象类和uimanager类。
  
  lookandfeel类
  
  lookandfeel是一个抽象类,除了提供了一些static方法,还定义了一些抽象的个性化设置方法来由子类实现。
  
  从jdk1.1.3开始,sun提供了三个lookandfeel的子类 javax.swing.plaf.metal.metallookandfeel、com.sun.java.swing.plaf.motif.motiflookandfeel、com.sun.java.swing.plaf.windows. windowslookandfeel。它们分别提供了“metal”、“motif”与“windows”的界面式样。也就是说,任何基于swing的界面程序本身都可以使用三种系统提供的皮肤。实际上我们也可以直接或间接继承lookandfeel类,自己编写一种“皮肤”。在这里我们要使用到一个开放源代码的产品skin look and feel 1.2.2,在http://www.l2fprod.com/可以找到它的全部源代码。skin look and feel本身还可以更换http://www.l2fprod.com/提供的各种“皮肤”,让你的程序可以各种“皮肤”示人。
  
  uimanager类
  
  这个类就是swing界面管理的核心,管理swing的小应用程序以及应用程序样式的状态。uimanager类提供了下列静态方法用于更换与管理“look and feel”:
  
  static void addauxiliarylookandfeel(lookandfeel laf)
  //增加一个“look and feel”到辅助的“look and feels”列表
  static lookandfeel[] getauxiliarylookandfeels()
  //返回辅助的“look and feels”列表(可能为空)。
  static string getcrossplatformlookandfeelclassname()
  //返回缺省的实现了跨平台的look and feel――即java look and feel(jlf)。
  static uimanager.lookandfeelinfo[] getinstalledlookandfeels()
  //返回了在目前已经安装的lookandfeel的信息。
  static lookandfeel getlookandfeel()
  //返回当前使用的look and feel
  static string getsystemlookandfeelclassname()
  //返回与当前系统相关的本地系统look and feel,如果没有实现本地look and
  feel则返回缺省的跨平台的look and feel。
  static void installlookandfeel(string name, string classname)
  //创建一个新的look and feel并安装到当前系统。
  static void installlookandfeel(uimanager.lookandfeelinfo info)
  //创建一个新的look and feel并安装到当前系统。
  static boolean removeauxiliarylookandfeel(lookandfeel laf)
  //从辅助的“look and feels”列表删除一个“look and feel”
  static void setinstalledlookandfeels(uimanager.lookandfeelinfo[] infos)
  //设置当前的已安装look and feel信。
  static void setlookandfeel(lookandfeel newlookandfeel)
  //设置当前使用的lookandfeel。
  static void setlookandfeel(string classname)
  //设置当前使用的lookandfeel。参数是类名。
  
  
  
  
  源码剖析
  
  
  下面的源代码可以在skin look and feel 1.2.2下的源代码根目录下找到(比如我下载的zip包是skinlf-1.2.2-20020611.zip,解压后,在src目录下的skinit.java)。
  
  public class skinit extends javax.swing.japplet
   {
   /**
   * the main program for the skinit class
   *
   * @param args the command line arguments
   * @exception exception description of exception
   */
   public static void main(string[] args) throws exception
  {
   if (args.length == 0) {
   printusage();
   }
   int mainclassnameindex = -1;
   string gtktheme = null;
   string kdetheme = null;
   string packtheme = null;
  
   for (int i = 0, c = args.length; i < c; i++) {
   if (args[i].equals("-gtk")) {
   gtktheme = args[++i];
  }
  else if (args[i].equals("-kde")) {
  kdetheme = args[++i];
  }
  else if (args[i].equals("-pack")) {
  packtheme = args[++i];
  }
  else {
  mainclassnameindex = i;
  break;
   }
  }
  
  string[] realargs = new string[args.length - mainclassnameindex - 1];
  for (int i = 0, c = realargs.length; i < c; i++) {
  realargs[i] = args[mainclassnameindex + i + 1];
  }
  
  // first try to find the class
  class clazz = null;
  try {
  clazz = class.forname(args[mainclassnameindex]);
  } catch (classnotfoundexception e) {
  system.err.println("the class " + args[mainclassnameindex] + "
  was not found in the classpath.");
  system.exit(1);
  } catch (throwable e) {
  e.printstacktrace();
  system.exit(1);
  }
  // if the class exists, get the main method
  method mainmethod = null;
  try {
  mainmethod = clazz.getmethod("main", new class[]{string[].class});
  } catch (nosuchmethodexception e) {
  system.err.println("no method public static void main(string[] args) in " +
  clazz.getname());
  system.exit(1);
  } catch (throwable e) {
  e.printstacktrace();
  system.exit(1);
  }
  // try to make sure the main method is accessible
  try {
  mainmethod.setaccessible(true);
  } catch (throwable e) {
  }
  // main class and main method found, time to load the skin
  skin skin = null;
  if (packtheme != null) {
  if (skinutils.debug) {
  system.out.println("loading themepack " + packtheme);
  }
  skin = skinlookandfeel.loadthemepack(packtheme);
  }
  else if (gtktheme != null) {
  if (kdetheme != null) {
  skin = new compoundskin(skinlookandfeel.loadskin(gtktheme),
  skinlookandfeel.loadskin(kdetheme));
  }
  else {
  skin = skinlookandfeel.loadskin(gtktheme);
   }
  }
  /*
  * try to use the user default skin
  */
  if (skin == null) {
  if (skinutils.debug) {
  system.out.println("trying user skin");
  }
  skin = skinlookandfeel.getskin();
  }
  if (skin != null) {
  skinlookandfeel.setskin(skin);
  skinlookandfeel lnf = new skinlookandfeel();
  uimanager.setlookandfeel(lnf);
  uimanager.addpropertychangelistener(
  new propertychangelistener() {
  public void propertychange(propertychangeevent event) {
  object newlf = event.getnewvalue();
  if ((newlf instanceof skinlookandfeel) == false) {
  try {
  uimanager.setlookandfeel(new skinlookandfeel());
  } catch (exception e) {
  e.printstacktrace();
   }
   }
   }
   });
  }
  else {
  system.out.println("no gtk theme provided, defaulting to application look and
  feel");
  }
  try {
  mainmethod.invoke(null, new object[]{realargs});
  } catch (illegalaccessexception e) {
  system.err.println("please make sure the class " + clazz.getname() +
  " and the method main(string[] args) are public.");
  system.exit(1);
  } catch (throwable e) {
  e.printstacktrace();
  system.exit(1);
  }
  }
  /**
  * description of the method
  */
  static void printusage() {
  string usage = "skinit - skin look and feel wrapper/n" +
  "usage: skinit [options] class [args...]/n" +
  "

扫描关注微信公众号