Properties提供的应用程序解决方案主要存在两个问题:

(1)配置文件不能放在主目录中,因为某些OS(如Win9X)没有主目录的概念;

(2)没有标准的文件命名规则,存在文件名冲突的可能性。

Java中的Preferences类可以解决这些问题。Preferences提供一个存储配置信息的中心知识库,与平台无关。在Windows系统中,它存储在注册表中,在Linux中存储在本地文件系统中。它的实现是透明的,程序员无需深究它的底层是如何实现的。

Preferences的中心知识库是树状结构,因此可以避免文件名冲突。每个用户都有一棵树,存放与本用户有关的配置;还有一个系统树,存放全体用户的公共信息。内部的配置信息仍然以key-value的结构进行存储。

Preferences的使用步骤如下:

(1)获得根节点

Preferences root = Preferences.userRoot();

Preferences root = Preferences.systemRoot();

如果配置信息位于用户树,则获取用户树的根节点,否则获取系统树根节点;

(2)获取配置节点

preferences = root.node("path");

path是配置节点相对于根节点的路径;

如果节点的路径名与类的包名相同,则可通过类的对象直接获得配置节点:

Preferences node = Preferences.userNodeForPackage(this.getClass());
Preferences node = Preferences.systemNodeForPackage(this.getClass());

(3)读取配置项

String title =  preferences.get("title", "default title");

Preferences要求读取配置项时必须指定默认值。因为在实际环境中总会有各种不如意,比如系统中还没有中心知识库,或者网络暂时不可用等等。

(4)设置配置项

preferences.put(key, value);

(5)同步配置项

preferences.flush();

flush()方法用于立即将配置项写入到文件中。

下面是Preferences类中的常用方法:

示例代码如下:

PreferencesDemo.java

package ConfigByPreferencesDemo;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.prefs.BackingStoreException;
import java.util.prefs.InvalidPreferencesFormatException;
import java.util.prefs.Preferences;
import javax.swing.*; /*
* 功能:演示Preferences的用法,实现JFrame窗体参数的修改、保存以及导入导出到xml文件中。
* 版本:20150807
* 结构:PreferencesDemo[主窗体],PreferencesDialog
*/
public class PreferencesDemo extends JFrame { private Preferences preferences;//配置内容 public PreferencesDemo() {
// 加载配置
loadPreferences();
// 设置窗体属性
initFrame();
} public void loadPreferences() {
/*
* 加载配置,它位于注册表
*/
Preferences root = Preferences.userRoot();//HKEY_CURRENT_USER\Software\JavaSoft\Prefs
preferences = root.node("/com/horstmann/corejava");
} public void updatePreferencesValue(String key, String value){
/*
* 功能:更新Preferences的内容
*/
preferences.put(key, value);
} public void flushPreferences()
{
/*
* 功能:将最新Preferences的值写入配置文件
*/
try {
preferences.flush();
} catch (BackingStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public String getPreferencesValue(String key){
/*
* 功能:根据key获取configProperties中对应的value
*/
return preferences.get(key, "0");
} public void exportPreferences(OutputStream out) {
/*
* 导出配置
*/
try {
preferences.exportSubtree(out);
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BackingStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public void importPreferences(InputStream in) {
/*
* 导入配置
*/
try {
Preferences.importPreferences(in);
in.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InvalidPreferencesFormatException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} public void initFrame() {
//获取参数,如果不存在则取默认值
String left = preferences.get("left", "0");
String top = preferences.get("top", "0");
String width = preferences.get("width", "300");
String height = preferences.get("height", "200");
String title = preferences.get("title", "default title"); JMenuBar menubar = new JMenuBar();
JMenu windowMenu = new JMenu("Window");
windowMenu.setMnemonic('W');
JMenuItem preferencesItem = new JMenuItem("Preferences");
preferencesItem.setMnemonic('P');
preferencesItem.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
PreferencesDialog optionsDialog = new PreferencesDialog(PreferencesDemo.this);
optionsDialog.setVisible(true);
}
});
setJMenuBar(menubar);
menubar.add(windowMenu);
windowMenu.add(preferencesItem); setBounds(Integer.parseInt(left), Integer.parseInt(top), Integer.parseInt(width), Integer.parseInt(height));
setTitle(title);
setDefaultCloseOperation(EXIT_ON_CLOSE);
} public static void main(String[] args) {
// TODO Auto-generated method stub
PreferencesDemo preferencesDemo = new PreferencesDemo();
preferencesDemo.setVisible(true);
}
}

PreferencesDialog.java

package ConfigByPreferencesDemo;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.swing.*;
import javax.swing.filechooser.*; /*
* @功能:修改配置对话框
* @版本:20150807
*/
class PreferencesDialog extends JDialog { PreferencesDemo preferencesDemo;// 父窗体
private JTextField xField;
private JTextField yField;
private JTextField widthField;
private JTextField heightField;
private JTextField titleField; private JButton importButton;// 导入配置
private JButton exportButton;// 导出配置
private JButton saveButton;// 保存
private JButton cancelButton;// 取消 private JFileChooser fileChooser;// 文件选择器,用于导入导出配置 public PreferencesDialog(PreferencesDemo parent) {
super(parent, true);
preferencesDemo = parent; // 提取主配置信息,作为控件的默认值
String xPosition = preferencesDemo.getPreferencesValue("left");
String yPosition = preferencesDemo.getPreferencesValue("top");
String width = preferencesDemo.getPreferencesValue("width");
String height = preferencesDemo.getPreferencesValue("height");
String title = preferencesDemo.getPreferencesValue("title"); // 本UI包含2个panel
JPanel inputPanel = new JPanel();
JPanel buttonPanel = new JPanel(); // 构造inputPanel
inputPanel.setLayout(new GridLayout()); inputPanel.add(new JLabel("xPosition:"));
xField = (JTextField) inputPanel.add(new JTextField(xPosition));
inputPanel.add(inputPanel.add(new JLabel("yPosition:")));
yField = (JTextField) inputPanel.add(new JTextField(yPosition));
inputPanel.add(inputPanel.add(new JLabel("witdh:")));
widthField = (JTextField) inputPanel.add(new JTextField(width));
inputPanel.add(inputPanel.add(new JLabel("height:")));
heightField = (JTextField) inputPanel.add(new JTextField(height));
inputPanel.add(inputPanel.add(new JLabel("title:")));
titleField = (JTextField) inputPanel.add(new JTextField(title)); inputPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5)); // 构造buttonPanel importButton = new JButton("import");
importButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
InputStream in = null;
if (fileChooser.showSaveDialog(PreferencesDialog.this) == JFileChooser.APPROVE_OPTION) {
try {
in = new FileInputStream(fileChooser.getSelectedFile()); } catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
preferencesDemo.importPreferences(in);//导入配置内容 int result = JOptionPane.showConfirmDialog(PreferencesDialog.this, "是否立即更新窗体?", "导入成功", JOptionPane.YES_NO_OPTION);
if(result == JOptionPane.YES_OPTION){
validateParentWindow();//更新父窗体界面
}
}
}
}); exportButton = new JButton("export");
exportButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (fileChooser.showSaveDialog(PreferencesDialog.this) == JFileChooser.APPROVE_OPTION) {
try {
OutputStream out = new FileOutputStream(fileChooser
.getSelectedFile());
preferencesDemo.exportPreferences(out);//导出配置内容
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
JOptionPane.showMessageDialog(PreferencesDialog.this, "导出成功");
setVisible(false);
}
}); saveButton = new JButton("save");
saveButton.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) { preferencesDemo.updatePreferencesValue("left", xField.getText()
.trim());
preferencesDemo.updatePreferencesValue("top", yField.getText()
.trim());
preferencesDemo.updatePreferencesValue("width", widthField
.getText().trim());
preferencesDemo.updatePreferencesValue("height", heightField
.getText().trim());
preferencesDemo.updatePreferencesValue("title", titleField
.getText().trim()); preferencesDemo.flushPreferences();// 写入配置文件
int result = JOptionPane.showConfirmDialog(PreferencesDialog.this, "是否立即更新窗体?", "保存成功", JOptionPane.YES_NO_OPTION);
if(result == JOptionPane.YES_OPTION){
validateParentWindow();//更新父窗体界面
}
}
}); cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
setVisible(false);
}
}); buttonPanel.add(importButton);
buttonPanel.add(exportButton);
buttonPanel.add(saveButton);
buttonPanel.add(cancelButton);
buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5)); // 构造主框架
getContentPane().setLayout(new BorderLayout());
getContentPane().add(inputPanel, BorderLayout.CENTER);
getContentPane().add(buttonPanel, BorderLayout.SOUTH); // 设置窗体属性
setTitle("更改主窗体配置");
setLocationRelativeTo(inputPanel);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack(); // 初始化文件选择器
initFileChooser();
} private void validateParentWindow(){
setVisible(false);
preferencesDemo.initFrame();
preferencesDemo.validate();
} private void initFileChooser() {
fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File("."));
fileChooser.setFileFilter(new FileFilter() { @Override
public String getDescription() {
// TODO Auto-generated method stub
return "XML files";
} @Override
public boolean accept(File f) {
// TODO Auto-generated method stub
return f.getName().toLowerCase().endsWith(".xml")
|| f.isDirectory();
}
});
}
}

运行效果如下:

程序初始界面

配置导入导出-文件选择界面

配置更改后询问是否更新窗体

Java-Preferences用法-入门的更多相关文章

  1. Java入门-浅析Java学习从入门到精通【转】

    一. JDK (Java Development Kit)  JDK是整个Java的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具和Java基础的类库 ...

  2. Java Web快速入门——全十讲

    Java Web快速入门——全十讲 这是一次培训的讲义,就是我在给学生讲的过程中记录下来的,非常完整,原来发表在Blog上,我感觉这里的学生可能更需要. 内容比较长,你可以先收藏起来,慢慢看. 第一讲 ...

  3. 【JAVA零基础入门系列】Day4 变量与常量

    这一篇主要讲解Java中的变量,什么是变量,变量的作用以及如何声明,使用变量. 那么什么是变量?对于初学者而言,可以将变量理解为盒子,这些盒子可以用来存放数据,不同类型的数据需要放在对应类型的盒子里. ...

  4. 【JAVA零基础入门系列】Day5 Java中的运算符

    运算符,顾名思义就是用于运算的符号,比如最简单的+-*/,这些运算符可以用来进行数学运算,举个最简单的栗子: 已知长方形的长为3cm,高为4cm,求长方形的面积. 好,我们先新建一个项目,命名为Rec ...

  5. 【JAVA零基础入门系列】Day8 Java的控制流程

    什么是控制流程?简单来说就是控制程序运行逻辑的,因为程序一般而言不会直接一步运行到底,而是需要加上一些判断,一些循环等等.举个栗子,就好比你准备出门买个苹果,把这个过程当成程序的话,可能需要先判断一下 ...

  6. 【JAVA零基础入门系列】Day7 Java输入与输出

    [JAVA零基础入门系列](已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day ...

  7. JAVA WEB快速入门之从编写一个基于SpringBoot+Mybatis快速创建的REST API项目了解SpringBoot、SpringMVC REST API、Mybatis等相关知识

    JAVA WEB快速入门系列之前的相关文章如下:(文章全部本人[梦在旅途原创],文中内容可能部份图片.代码参照网上资源) 第一篇:JAVA WEB快速入门之环境搭建 第二篇:JAVA WEB快速入门之 ...

  8. JAVA WEB快速入门之从编写一个基于SpringMVC框架的网站了解Maven、SpringMVC、SpringJDBC

    接上篇<JAVA WEB快速入门之通过一个简单的Spring项目了解Spring的核心(AOP.IOC)>,了解了Spring的核心(AOP.IOC)后,我们再来学习与实践Maven.Sp ...

  9. JAVA WEB快速入门之通过一个简单的Spring项目了解Spring的核心(AOP、IOC)

    接上篇<JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构.调试.部署>,通过一个简单的JSP WEB网站了解了JAVA WEB相关的知识,比如:Ser ...

  10. JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构、调试、部署

    接上篇<JAVA WEB快速入门之环境搭建>,在完成了环境搭建后(JDK.Tomcat.IDE),现在是万事具备,就差写代码了,今天就来从编写一个JSP WEB网站了解JSP WEB网站的 ...

随机推荐

  1. JS正则密码复杂度校验之:至少有多种字符中的其中几种

    概述 续接上文的密码校验要求: 这个需求有两个难点,一,是如何使用正则匹配所有半角英文标点符号,二,是如何验证密码段中在要求的四种(大写字母,小写字母,数字,标点符号)类型中至少存在三种. 第一个难点 ...

  2. FPS手游如何脱颖而出?看《CF手游》的性能突破之路

    WeTest导读 俗话说:用户体验不谈性能就是耍流氓. 在PC游戏上的性能问题并没有那么明显, 加个内存换个CPU或者刷个主频就能轻松搞定:到了手游时代后情况则显得比较严峻,捉襟见肘的内存使得资源加载 ...

  3. python--------------常用模块之正则

    一.认识模块  什么是模块:一个模块就是一个包含了python定义和声明的文件,文件名就是加上.py的后缀,但其实import加载的模块分为四个通用类别 : 1.使用python编写的代码(.py文件 ...

  4. C++中的继承(3)作用域与重定义,赋值兼容规则

    作用域与重定义(同名隐藏) 一样的,先上代码 1 class A 2 { 3 public: 4 int a_data; 5 void a() 6 { 7 cout << "A& ...

  5. Vue动态组件

    前面的话 让多个组件使用同一个挂载点,并动态切换,这就是动态组件.本文将详细介绍Vue动态组件 概述 通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,可以实现动 ...

  6. 1>MSBUILD : cordova-build error BLD401: 错误: BLD00401: 找不到模块“C:\Users\z-pc\AppData\Roaming\npm\node_modules\vs-tac\app.js”。请转到“工具”-->“选项”-->“Apache Cordova 工具”-->“Cordova 工具”-->“清除 Cordova 缓存”,然后尝试重新生成

    1>------ 已启动全部重新生成: 项目: BlankCordovaApp2, 配置: Debug Android ------1>  Your environment has bee ...

  7. expander graph&random walk的一个小应用

    此文主要总结的是一种随机算法,旨在判断一个expander图上两点是否连通.复杂度O(logn).算法思路清奇. expander graph博大精深,如果对expander graph的生成,fam ...

  8. 【Java学习笔记之三十一】详解Java8 lambda表达式

    Java 8 发布日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Java 8之前 ...

  9. thinkjs学习-this.assign传递数据和ajax调用后台接口

    在页面加载时,就需要显示在页面上的数据,可以在后台使用this.assign赋值,在前台通过ejs等模板获取:用户点击按钮,或者触发某些事件和后台进行交互时,就需要用到ajax调用后台接口.本文通过一 ...

  10. JavaScrpt笔记之第二天

    JavaScript正则表达式regex 1.郑则表达式是有一个字符序列形成的搜索模式. *语法:/正则表达式主题/修饰符(可选) *正则表达式修饰符:i部分大小写:g全局搜索:m多行匹配 *[abc ...