以下是使用java swing写的一个小工具:
?
?
我现在不细说功能,而是说明如何保存使用痕迹,比如上图,我在"old path"输入了"com\common\jn\img\path.png",我想下次打开时"old path"自动保存上一次的记录.
如何实现呢?
(1)可以把文本框的内容保存到properties配置文件中;
(2)关闭窗口或者按下Ctrl+S 时触发保存事件
(3)下次启动窗口时,从配置文件中读取使用痕迹,并恢复到界面上.
具体实现如下
配置文件为
public static final String configFilePath="C:\\.path_config.properties";
?
(a)获取界面上文本框的内容,并设置到properties中,然后写入磁盘
/*** * 保存到配置文件中 * @throws IOException */ protected void saveConfig() throws IOException{ File configFile=new File(configFilePath); if(!configFile.exists()){ try { SystemHWUtil.createEmptyFile(configFile); } catch (IOException e) { e.printStackTrace(); GUIUtil23.errorDialog(e); } } CMDUtil.show(configFilePath);//因为隐藏文件是只读的 // FileUtils.writeToFile(configFilePath, content); if(ValueWidget.isNullOrEmpty(props)){ props= new Properties(); } String old_path=oldPathTF.getText(); if(!ValueWidget.isNullOrEmpty(old_path)){ props.setProperty(PROP_KEY_OLD_PATH, old_path); } String folder1=this.compareFolderPanel.getFolderOneTextField().getText(); if(!ValueWidget.isNullOrEmpty(folder1)){ props.setProperty(PROP_KEY_COMPARED_FOLDERONE, folder1); } String folder2=this.compareFolderPanel.getFolder2TextField().getText(); if(!ValueWidget.isNullOrEmpty(folder2)){ props.setProperty(PROP_KEY_COMPARED_FOLDER2, folder2); } String sourceFile=this.checkSamePanel.getSourceFileTF().getText(); if(!ValueWidget.isNullOrEmpty(sourceFile)){ props.setProperty(PROP_KEY_SOURCE_FILE, sourceFile); } String targetFile=this.checkSamePanel.getTargetFileTF().getText(); if(!ValueWidget.isNullOrEmpty(targetFile)){ props.setProperty(PROP_KEY_TARGET_FILE, targetFile); } /*** * 增量包中,复制class时是否弹出确认提示框 */ boolean isSure=createFolderByPackage.getSureCheckbox().isSelected(); props.setProperty(PROP_KEY_COPY_JAVA_SURE, String.valueOf(isSure)); boolean isCopyPath=copyCheckbox.isSelected(); props.setProperty(PROP_KEY_IS_COPY_PATH, String.valueOf(isCopyPath)); setCombox(PROP_KEY_ROOT_PATHS, this.createFolderByPackage.getRootFolderTextField(),this.createFolderByPackage.getRootPathComboBox()); setCombox(PROP_KEY_JAVA_FILE_PATHS, this.createFolderByPackage.getClassTextField(),this.createFolderByPackage.getJavaPathComboBox()); OutputStream out=new FileOutputStream(configFile); props.store(out, TimeHWUtil.formatDateTimeZH(null)); out.close();//及时关闭资源 CMDUtil.hide(configFilePath);//隐藏文件:attrib ".mqtt_client.properties" +H System.out.println("save complete."); } /*** * 以;;分隔 * @param prop_key * @param tf */ private void setCombox(String prop_key,JTextField tf,JComboBox<String>comboBox){ String rootPath=tf.getText(); if(ValueWidget.isNullOrEmpty(rootPath)){ return; } String roots=props.getProperty(prop_key); if(ValueWidget.isNullOrEmpty(roots)){ roots=rootPath; }else{ String roots_old[]=roots.split(SHAREDPICDIVISION); if(!SystemHWUtil.isContains(roots_old, rootPath)){ roots=roots+SHAREDPICDIVISION+rootPath; comboBox.addItem(rootPath); } String urls_old2[]=roots.split(SHAREDPICDIVISION); String urls_new[]=SystemHWUtil.unique(urls_old2); roots=StringUtils.join(urls_new, SHAREDPICDIVISION); } props.setProperty(prop_key, roots); }
?注意:CMDUtil.show 是去掉配置文件的隐藏属性,因为隐藏文件不可写.
(b)窗口关闭时触发保存事件
this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.out.println("closing...."); try { saveConfig(); } catch (IOException e1) { e1.printStackTrace(); GUIUtil23.errorDialog(e1); } super.windowClosing(e); } @Override public void windowClosed(WindowEvent e) { /*System.out.println("closed"); try { saveConfig(); } catch (IOException e1) { e1.printStackTrace(); }*/ super.windowClosed(e); } });
?注意:窗口关闭时只会执行windowClosing(),而不会执行windowClosed()
?
?
(c)增加全局快捷键
/*** * 增加全局快捷键.<Br> * Ctrl+S,导致"比例"文本框聚焦 */ protected void setGlobalShortCuts() { // Add global shortcuts Toolkit toolkit = Toolkit.getDefaultToolkit(); // 注册应用程序全局键盘事件, 所有的键盘事件都会被此事件监听器处理. toolkit.addAWTEventListener(new java.awt.event.AWTEventListener() { public void eventDispatched(AWTEvent event) { if (event.getClass() == KeyEvent.class) { KeyEvent kE = ((KeyEvent) event); // 处理按键事件 Ctrl+S if (kE.getKeyCode() == KeyEvent.VK_S && kE.isControlDown()&&!kE.isAltDown() && kE.getID() == KeyEvent.KEY_PRESSED) { try { saveConfig(); } catch (IOException e) { e.printStackTrace(); GUIUtil23.errorDialog(e); } } } } }, java.awt.AWTEvent.KEY_EVENT_MASK); }
?注意:为什么要加上条件 kE.getID() == KeyEvent.KEY_PRESSED,根本原因是为了防止触发两次
?
(d)启动程序时,先读取配置文件
/*** * 读取配置文件 * @throws IOException */ private void readConfig() throws IOException{ File configFile=new File(configFilePath); if(configFile.exists()){ InputStream inStream=new FileInputStream(configFile); props.load(inStream); inStream.close();//及时关闭资源 } String old_path=getPropValue(PROP_KEY_OLD_PATH); //"比较文件夹" String compared_folderOne=getPropValue(PROP_KEY_COMPARED_FOLDERONE); //"比较文件夹" String compared_folder2=getPropValue(PROP_KEY_COMPARED_FOLDER2); //增量包 String root_path=getPropValue(PROP_KEY_ROOT_PATHS); //增量包 String java_path=getPropValue(PROP_KEY_JAVA_FILE_PATHS); //比较二进制文件 String sourceFile=getPropValue(PROP_KEY_SOURCE_FILE); //比较二进制文件 String targetFile=getPropValue(PROP_KEY_TARGET_FILE); String isSureStr=getPropValue(PROP_KEY_COPY_JAVA_SURE); String isCopyPath=getPropValue(PROP_KEY_IS_COPY_PATH); if(!ValueWidget.isNullOrEmpty(old_path)){ oldPathTF.setText(old_path); } if(!ValueWidget.isNullOrEmpty(root_path)){ String roots[]=root_path.split(SHAREDPICDIVISION); ComponentUtil.fillComboBox(createFolderByPackage.getRootPathComboBox(), roots); } if(!ValueWidget.isNullOrEmpty(java_path)){ String java_paths[]=java_path.split(SHAREDPICDIVISION); ComponentUtil.fillComboBox(createFolderByPackage.getJavaPathComboBox(), java_paths); } if(!ValueWidget.isNullOrEmpty(compared_folderOne)){ compareFolderPanel.getFolderOneTextField().setText(compared_folderOne);; } if(!ValueWidget.isNullOrEmpty(compared_folder2)){ compareFolderPanel.getFolder2TextField().setText(compared_folder2);; } if(!ValueWidget.isNullOrEmpty(sourceFile)){ checkSamePanel.getSourceFileTF().setText(sourceFile); } if(!ValueWidget.isNullOrEmpty(targetFile)){ checkSamePanel.getTargetFileTF().setText(targetFile); } if(!ValueWidget.isNullOrEmpty(isSureStr)){ boolean isSure2=Boolean.parseBoolean(isSureStr); createFolderByPackage.getSureCheckbox().setSelected(isSure2); } if(!ValueWidget.isNullOrEmpty(isCopyPath)){ boolean isCopyPath2=Boolean.parseBoolean(isCopyPath); copyCheckbox.setSelected(isCopyPath2); } }
?
上述代码中的一些变量声明:
public static final String configFilePath="C:\\.path_config.properties"; private Properties props=new Properties(); /*** * path tools */ public static final String PROP_KEY_OLD_PATH="old_path"; /*** * 比较文件夹 */ public static final String PROP_KEY_COMPARED_FOLDERONE="compared_folderOne"; /*** * 比较文件夹 */ public static final String PROP_KEY_COMPARED_FOLDER2="compared_folder2"; /*** * 增量包 */ public static final String PROP_KEY_ROOT_PATHS="root_paths"; /** * 增量包的"class文件" */ public static final String PROP_KEY_JAVA_FILE_PATHS="java_paths"; /*** * 比较二进制文件 */ public static final String PROP_KEY_SOURCE_FILE="sourceFile"; /*** * 比较二进制文件 */ public static final String PROP_KEY_TARGET_FILE="targetFile"; /*** * 增量包中复制class时是否弹出确认提示框 */ public static final String PROP_KEY_COPY_JAVA_SURE="isSure"; /*** * 是否复制路径 */ public static final String PROP_KEY_IS_COPY_PATH="isCopyPath"; public static final String SHAREDPICDIVISION=";;";
?注意:
(1)window中隐藏文件是只读的,不可写
?
?
(2)对于下拉框,多个路径之间使用两个分号进行分割
配置文件范例:
?
?
项目采用maven构建,源码见附件
?