1. /**
  2. * <p>Copyright: Copyright (c) 2002-2004</p>
  3. * <p>Company: JavaResearch(http://www.javaresearch.org)</p>
  4. */
  5. package org.jr.swing;
  6. import javax.swing.*;
  7. import java.util.*;
  8. import java.util.prefs.*;
  9. import java.awt.event.*;
  10. /**
  11. * 最近文件列表。
  12. * <p>最后更新日期:2003年6月2日
  13. * @author cherami@163.net
  14. * @since 0.6
  15. */
  16. public class RecentFiles {
  17. public static final int POPUP=0;
  18. public static final int LIST=1;
  19. public static final int AUTO=0;
  20. public static final int FULLPATH=1;
  21. public static final int FILENAME=1;
  22. private static final int MAX_SIZE=20;
  23. public static final String PREFERENCE_ROOT="recentfiles";
  24. int style;
  25. int contentType;
  26. int position;
  27. Preferences preference;
  28. ArrayList list;
  29. HashMap menuItemMap;
  30. int capacity;
  31. int size;
  32. JMenu parentMenu;
  33. RecentFileProcesser processer;
  34. boolean autoUpdatePreference;
  35. /**
  36. * 构造一个列表大小为10的RecentFilesManager。
  37. * @param parentMenu 列表菜单
  38. */
  39. public RecentFiles(JMenu parentMenu) {
  40. this(10, parentMenu, true);
  41. }
  42. /**
  43. * 根据指定的列表大小构造一个RecentFilesManager。
  44. * 如果指定的容量小于0则设置为缺省的10。
  45. * @param capacity 列表容量
  46. * @param parentMenu 列表菜单
  47. */
  48. public RecentFiles(int capacity, JMenu parentMenu) {
  49. this(capacity, parentMenu, true);
  50. }
  51. /**
  52. * 根据指定的列表大小和是否从参数选项里面读取列表构造一个RecentFilesManager。
  53. * @param capacity 列表容量
  54. * @param parentMenu 列表菜单
  55. * @param getFiles 是否从参数选项里面读取列表,为true是读取,否则不读取
  56. */
  57. public RecentFiles(int capacity, JMenu parentMenu, boolean getFiles) {
  58. if (capacity < 0 || capacity > MAX_SIZE) {
  59. capacity = 10;
  60. }
  61. list = new ArrayList(capacity);
  62. menuItemMap = new HashMap(capacity * 2);
  63. this.capacity = capacity;
  64. size = 0;
  65. this.parentMenu = parentMenu;
  66. if (getFiles == true) {
  67. getPreference();
  68. }
  69. }
  70. public RecentFiles(JMenu parentMenu, int style,int contentType,boolean getFiles) {
  71. this.parentMenu = parentMenu;
  72. this.style=style;
  73. this.contentType=contentType;
  74. if (getFiles == true) {
  75. getPreference();
  76. }
  77. }
  78. public void setProcesser(RecentFileProcesser processer) {
  79. this.processer=processer;
  80. }
  81. public RecentFileProcesser getProcesser() {
  82. return processer;
  83. }
  84. /**
  85. * 增加一项到最近文件列表中
  86. * @param filePath 文件的绝对路径
  87. */
  88. private void add(String filePath) {
  89. list.add(0, filePath);
  90. size++;
  91. if (size == 1) {
  92. parentMenu.addSeparator();
  93. }
  94. JMenuItem menuItem = createMenuItem(filePath);
  95. menuItemMap.put(filePath, menuItem);
  96. parentMenu.add(menuItem, position + 1);
  97. }
  98. /**
  99. * 从最近列表中删除一项
  100. * @param filePath 文件的绝对路径
  101. */
  102. private void remove(String filePath) {
  103. list.remove(filePath);
  104. size--;
  105. if (size == 0) {
  106. parentMenu.remove(position);
  107. }
  108. JMenuItem menuItem = (JMenuItem) menuItemMap.get(filePath);
  109. menuItemMap.remove(filePath);
  110. parentMenu.remove(menuItem);
  111. }
  112. /**
  113. * 将文件列表最后的一项删除。
  114. */
  115. public void removeLast() {
  116. if (size > 0) {
  117. String lastFile = (String) list.get(size - 1);
  118. remove(lastFile);
  119. }
  120. }
  121. /**
  122. * 添加一个文件到列表。
  123. * @param filePath 文件的绝对路径
  124. */
  125. public void addFile(String filePath) {
  126. if (list.size() < capacity && filePath != null) {
  127. if (!list.contains(filePath)) {
  128. add(filePath);
  129. refreshPreference();
  130. }
  131. else {
  132. remove(filePath);
  133. add(filePath);
  134. refreshPreference();
  135. }
  136. }
  137. else {
  138. if (!list.contains(filePath)) {
  139. removeLast();
  140. add(filePath);
  141. refreshPreference();
  142. }
  143. else {
  144. remove(filePath);
  145. add(filePath);
  146. refreshPreference();
  147. }
  148. }
  149. }
  150. /**
  151. * 清空文件列表。
  152. */
  153. public void clear() {
  154. if (size > 0) {
  155. list.clear();
  156. menuItemMap.clear();
  157. for (int i = position; i < position + size; i++) {
  158. parentMenu.remove(i);
  159. }
  160. size = 0;
  161. refreshPreference();
  162. }
  163. }
  164. /**
  165. * 重新设置列表的容量。
  166. * 如果新的容量小于已有文件的数量则会删除那些最旧的文件项。
  167. * @param capacity 新容量
  168. */
  169. public void setCapacity(int capacity) {
  170. if (capacity > 0) {
  171. this.capacity = capacity;
  172. if (size > capacity) {
  173. for (int i = size; i > capacity; i++) {
  174. removeLast();
  175. }
  176. size = capacity;
  177. refreshPreference();
  178. }
  179. }
  180. }
  181. /**
  182. * 返回文件列表数组,最新的文件在最前面。
  183. * @return 文件列表数组
  184. */
  185. public String[] getLists() {
  186. String[] result = new String[size];
  187. for (int i = 0; i < list.size(); i++) {
  188. result[i] = (String) list.get(i);
  189. }
  190. return result;
  191. }
  192. /**
  193. * 更新参数选项中的文件列表。
  194. */
  195. private void refreshPreference() {
  196. int i = 0;
  197. for (; i < list.size(); i++) {
  198. preference.put("recentfiles" + i, (String) list.get(i));
  199. }
  200. while (!preference.get("recentfiles" + i, "").equals("")) {
  201. preference.remove("recentfiles" + i);
  202. i++;
  203. }
  204. }
  205. /**
  206. * 从参数选项中读取文件列表。
  207. */
  208. private void getPreference() {
  209. int i = 0;
  210. String filePath = preference.get("recentfiles" + i, "");
  211. while (!filePath.equals("")) {
  212. add(filePath);
  213. i++;
  214. filePath = preference.get("recentfiles" + i, "");
  215. }
  216. preference.remove("recentfiles" + i);
  217. }
  218. /**
  219. * 创建一个最近文件菜单项
  220. * @param filePath 文件的绝对路径
  221. * @return 对应的菜单项
  222. */
  223. private JMenuItem createMenuItem(String filePath) {
  224. JMenuItem menuItem = new JMenuItem(getShortRecentName(filePath));
  225. menuItem.addActionListener(new RecentFileAction(filePath));
  226. menuItem.setToolTipText(filePath);
  227. return menuItem;
  228. }
  229. /**
  230. * 得到文件路径的缩短的形式。
  231. * @param filePath 文件路径
  232. * @return文件路径的缩短的形式
  233. */
  234. private String getShortRecentName(String filePath) {
  235. String result = filePath;
  236. /*if (filePath.length() > PATH_LENGTH) {
  237. String fileName = FileUtil.getFileName(filePath);
  238. int length = fileName.length();
  239. result = filePath.substring(0, 5);
  240. result = result + "...";
  241. result = result +
  242. filePath.substring(filePath.length() - PATH_LENGTH + 5);
  243. }*/
  244. return result;
  245. }
  246. /**
  247. * 最近打开文件事件处理器。
  248. */
  249. class RecentFileAction
  250. implements ActionListener {
  251. String filePath;
  252. public RecentFileAction(String filePath) {
  253. this.filePath = filePath;
  254. }
  255. public void actionPerformed(ActionEvent e) {
  256. if (processer!=null) {
  257. processer.dealWith(filePath);
  258. }
  259. }
  260. }
  261. }