标签 ‘UI’
[10/17 周主题] – Axure入项目
很早就关注和试用Axure了,但是没在之前的项目中使用过,因为一些原因,借这次的这个web项目开始在公司推广Axure的使用,不过说到推广,现在也就我一人的用,其他项目要用还未知呢!
先看看Axure的Demo吧:http://www.axure.org/demo/
做过前端的人应该会更有感觉,操作上不会感觉太难,很快就可以上手,这要得益于Axure强大的组件库,基本上常用的组件都有,另外还有其他一些特殊的第三方组件提供下载。
这次项目中用Axure主要原因是界面框架的原因,如果UI和前端(我做)做完页面,把网页给客户看,那估计要费时不少,加上随时的改动,到后面会越做越忙,越做改动越大,所以就早动手,先用Axure把网站的各个页面框架和页码流程搭起来,跟客户一一确认,尽快完成这块的内容,再由UI去跟客户确认配色的问题,前端这个时候就可以开工了,跟之前的项目流程比,至少框架不会大动了!
第一次拿做好的页面框架给客户看,客户以为这么快页面就出来啦,很有兴趣,当然我就得必须解释解释了,这个只是框架图,和最终的效果图是有些距离的,这些页面只是将页面框架和流程展示下。
学习Axure,最主要就是多用,多看别人的Axure例子,如果一个效果自己一下子无法实现,可以在网上找别人的rp文件,仔细研究下,很快就可以自己做出来了!
再者Axure现在有好些模板,不一定就得自己去实现,Axure只是个工具,不管从哪个方面入手,达到你要的效果即可。
推荐区国内Axure推广比较有名的网站:http://www.axure.org/ 上面有很多教程和例子,可以进一步帮助学习Axure的使用。
Drawing in code
之前介绍了一个Swing做的原子钟的效果 “Swing Nixieclock(原子钟)效果”,作者放出了制作 Swing原子钟 制作的主要元素 – 原子钟的制造过程。

想看制作过程的移步这里:
先通过绘图工具,绘出原型,绘制过程以及绘制时的参数,要在Swing中使用。
将原型绘制过程中的一些数据,以Java Code 的形式在Swing中体现出来,步骤和通过绘图工具绘制时差不多,一步步来。
[10/01周主题] – Web 项目开发中的常见问题
这周来一直在赶一个Web项目,没多少时间focus到其他上面,于是这周的主题就干脆做个整理,整理下web项目开发时遇到的一些问题和解决办法。
本周主题:Web 项目开发中的常见问题
一、中文乱码
建议统一使用UTF8,或者全局做个filter处理。
二、表单校验
使用第三方校验框架, 而非自己去写,可以减少很多工作量。
三、Ajax的使用
首页尽量少用ajax,页面初次加载时常会加载不上来,尤其多个Ajax实例同时运行。
四、UI 规范
UI最好是出Demo,跟客户确认,定终稿,然后开发按最终效果图实现页面最好,否则没有页面或者效果图,即使有统一的规范,还是会浪费很多时间去调UI问题。
五、浏览器的兼容问题
虽然IE6基本上淘汰了,可老机器上使用IE6的还是不少的,Css 在处理兼容问题时,建议分开处理,在页面进行浏览器version判断,读取不同的css,这样管理和调整起来都方便。
六、比较完整的测试数据
页面框架搭完了,看着效果不错,可是填完数据后会发现和想象的不太一样。
七、用JPA Or JDBC 与数据库交互
JPA与JDBC相比之下,使用JPA大大减少了编程人员的工作量,因此还是偏向使用JPA,特殊环境下再选择JDBC
[09/49周主题] – Swing Tips
选择这个主题,是因为上周公司刚好做了一个有关“Beginning Java AWT and Swing” 的培训,借此机会正好总结一下这方面的使用技巧。对于Swing界面方面的研究,我仅仅是应用而已,公司里有几位同事在这方面的研究比较深,这块的应用和使用技巧分两部分, 一部分是Swing 使用本身的,另一部分是Design工具NetBeans的,如果是刚入门建议从这里看起:Creating a GUI With JFC/Swing。
本期主题:Swing Tips
一、性能问题
随着Java 6对于Swing性能的改进,Swing的运行速度已经开始得到了大大的提高,看看NetBeans就知道了,NetBeans就是Swing开发的,如果你跑Swing很慢,很耗资源,那么应该从自己的程序上找找问题,推荐使用NetBeans自带的Profile查找原因,教程在这里 – Profile Introduce 。
二、LookAndFeel
用Swing做企业应用时,LookAndFeel的选择和使用是决定这个项目能否被客户接受的一个很大因素,即要好看,又要考虑跨平台的兼容性,必要时自己还得设计部分LookAndFeel, 可以看看这里提供的一些开源LookAndFeel:http://www.open-open.com/61.htm 和http://www.javootoo.com/。
切换LookAndFeel:UIManager.setLookAndFeel(LookAndFeelName); SwingUtilities.updateComponentTreeUI(frame); frame.pack();
三、合理的控制初始化组件和组件初始化的顺序可以很大的提高性能
举个例子:之前我们项目中有一个地方,当打开程序时,会初始化几十个甚至成百个JPanel,这显然成为程序启动时慢的一个因素,也导致了用户体验的降低,这些JPanel完全可以在程序启动后再根据用户的需要去初始化,因为用户打开程序时这些Panel不是必须看到的。
四、要有统一的UI规范
比如Button的高度,进度条的高宽等,也可以通过UIManager给系统组件设置统一属性,比如统一设定Button的间距和字体:
UIManager.put("Button.margin", new Insets(2, 5, 2, 5)); UIManager.put("Button.font", new Font("宋体", Font.PLAIN, 13));
五、多线程的使用
用Swing做的都是界面的东西,如果界面假死或者用户等待事件太长,那么用户体验必然是不好的,这里就需要用到多线程的使用了,当界面处理一个请求时,不能让界面假死了,需要后台另一个线程去做处理,然后将结果返回到Swing线程,这块可以看看SwingWorker的介绍。
六、布局管理器
布局管理器的使用在Swing里面是比较重要的,它直接决定了你界面的显示效果,也是比较难用的一块,不好举例子,建议多了解每个布局管理器的使用场景。
七、JTable & JTree
在Swing组件的使用中除了布局管理器,估计就数JTable和JTree的使用稍微有点麻烦了,下面我就分享一些实际项目中JTable的一些实例,关于JTree,可以点这里:JTree 经验 总结 。
JTable相关
1、自定义表头排序
TableRowSorter rs = (TableRowSorter) table.getRowSorter(); Comparator<Integer> intComparator = new Comparator<Integer>() { public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); } }; rs.setComparator(3, intComparator);2、自定义Table Renderer
public class CommonTableCellRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean cellHasFocus, int row, int column) { JComponent comp = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, cellHasFocus, row, column); //表格的奇数偶数行交叉颜色显示 if (!isSelected) { if (row % 2 == 0) { comp.setBackground(UIConsts.HIGHLIGHTER_COLOR); } else { comp.setBackground(Color.white); } } //table column里面显示图标和对齐方式 switch (column) { case PaperTableModel.STATUS_COLUMN: switch ((EntityStatus) value) { case VALID: comp.setIcon(ENABLED_ICON); setHorizontalAlignment(JLabel.LEADING); break; case DISABLED: comp.setIcon(DISABLED_ICON); setHorizontalAlignment(JLabel.CENTER); break; } break; default: comp.setIcon(null); break; } return comp; } }3、自定义Table列宽
TableColumnModel colModel = table.getColumnModel(); colModel.getColumn(0).setPreferredWidth(70); colModel.getColumn(1).setPreferredWidth(55); colModel.getColumn(2).setPreferredWidth(120);4、禁止Table列拖动
table.getTableHeader().setReorderingAllowed(false);5、单选表格设置
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);6、设置表头默认支持排序
table.setAutoCreateRowSorter(true);7、设置列不可随容器组件大小变化自动调整宽度
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);8、固定Table上的某些列不滚动
这个需求是这样的,比如Table上左边有部分数据,是后面数据所共有的属性,那么当后面数据很多时,显示不下会出现滚动条,但是滚动时又不想让左侧的共有属性动,只滚动右侧的数据部分。
实现原理是:scrollPane里面放置一个表格,然后在scrollPane的左上角放置以共有属性的部分为Model的表格,剩下的右侧就是剩余的纯数据表格。
最终效果就是表格左侧的列锁定了,右侧数据出现滚动条时,可以滚动,但左侧不动。
核心代码:比如有HeaderTable和ReportTable, 其中ReportTable是放置在一个ScrollPanel里面,Model是所有数据的Model,将左侧的数据和右侧的数据分开//找到主表所在的scrollPane JScrollPane scrollPane = (JScrollPane) SwingUtilities. getAncestorOfClass(JScrollPane.class, reportTable.getTable()); //中间处理headerTable的数据和reportTable剩余的数据 //将新表HeaderTable放在scrollPane的左上角 scrollPane.setRowHeaderView(headerTable.getTable()); scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, headerTable.getTable().getTableHeader());9、Table上的直接编辑功能
两点:
1、重写 public boolean isCellEditable(int row, int columnIndex) 方法,定义可编辑的行列。
2、重写 public void setValueAt(Object obj, int rowIndex, int columnIndex) 方法,拿到原来的对象,设置新的对象值。10、Table的Excel导出功能
表格上的Excel导出功能还是比较实用的功能,企业应用一般都会用到,这里提供相关代码
try { WritableCellFormat titleFormat = new WritableCellFormat( new WritableFont(WritableFont.createFont("黑体"), 16, WritableFont.NO_BOLD)); titleFormat.setVerticalAlignment(VerticalAlignment.CENTRE); // 垂直对齐 titleFormat.setAlignment(Alignment.CENTRE); // 水平对齐 titleFormat.setWrap(true); // 是否换行 WritableCellFormat headerFormat = new WritableCellFormat(); headerFormat.setBorder(Border.ALL, BorderLineStyle.THIN); // 线条 headerFormat.setVerticalAlignment(VerticalAlignment.CENTRE); // 垂直对齐 headerFormat.setAlignment(Alignment.CENTRE); // 水平对齐 headerFormat.setWrap(true); // 是否换行 WritableCellFormat countFormat = new WritableCellFormat( new NumberFormat("0.000")); countFormat.setBorder(Border.ALL, BorderLineStyle.THIN); // 线条 countFormat.setVerticalAlignment(VerticalAlignment.CENTRE); // 垂直对齐 countFormat.setAlignment(Alignment.RIGHT); // 水平对齐 countFormat.setWrap(true); // 是否换行 WritableCellFormat moneyFormat = new WritableCellFormat( new NumberFormat("0.00")); moneyFormat.setBorder(Border.ALL, BorderLineStyle.THIN); // 线条 moneyFormat.setVerticalAlignment(VerticalAlignment.CENTRE); // 垂直对齐 moneyFormat.setAlignment(Alignment.RIGHT); // 水平对齐 moneyFormat.setWrap(true); // 是否换行 WritableCellFormat intFormat = new WritableCellFormat( new NumberFormat("0")); intFormat.setBorder(Border.ALL, BorderLineStyle.THIN); // 线条 intFormat.setVerticalAlignment(VerticalAlignment.CENTRE); // 垂直对齐 intFormat.setAlignment(Alignment.RIGHT); // 水平对齐 intFormat.setWrap(true); // 是否换行 WritableWorkbook book = Workbook.createWorkbook(exportFile); WritableSheet sheet = book.createSheet("综合统计报表", 0); int titleRow = 0; int headerRow = 3; int dataRow = 5; sheet.mergeCells(0, titleRow, model.getColumnCount() - 1, titleRow); Label titleLab = new Label(0, titleRow, tableTitleTxfd.getText(), titleFormat); sheet.addCell(titleLab); //生成表头 for (int j = 0; j < model.getColumnCount(); j++) { sheet.mergeCells(j, headerRow, j, headerRow + 1); Label lab = new Label(j, headerRow, model.getColumnName( j), headerFormat); sheet.addCell(lab); } for (int row = 0; row < model.getRowCount(); row++) { for (int col = 0; col < model.getColumnCount(); col++) { Object obj = model.getValueAt(row, col); if (obj instanceof String) { Label lab = new Label(col, dataRow + row, (String) obj, headerFormat); sheet.addCell(lab); } else if (obj instanceof Integer) { Number labelN = new Number(col, dataRow + row, (Integer) obj, intFormat); sheet.addCell(labelN); } else { Label lab = new Label(col, dataRow + row, "", headerFormat); sheet.addCell(lab); } } } //生成表尾 int footerRow = dataRow + model.getRowCount() + 1; int step = (int) (((double) (model.getColumnCount() - 2) / 3) + 1); Label footerLab = new Label(0, footerRow, "部门负责人:"); sheet.addCell(footerLab); footerLab = new Label(step, footerRow, "制表:" + creatorTxfd.getText()); sheet.addCell(footerLab); footerLab = new Label(model.getColumnCount() - 2, footerRow, NazcaFormater.getSimpleDateString(new Date())); sheet.addCell(footerLab); sheet.setColumnView(0, 16); sheet.setRowView(titleRow, 600); book.write(); book.close(); //导出成功 } catch (Throwable ex) { //导出报表失败 ex.printStackTrace(); }11、Table的打印功能
打印这块,之前已经提过,可以参考之前的文章 JTable Print
12、在Table上选择多行
int rowcounts=table.getSelectedRows().length; if(rowcounts>1) int[] rows=table.getSelectedRows(); for(int i=0;i<rows.length;i++){ String value=(String) tableModel.getValueAt(i, 1); } }
NetBeans 6+ Tips
这里说NetBeans,主要是因为目前Swing开发方面,还没有哪个IDE能胜过NetBeans。
一、NetBeans的配置
1、配置为英文,大部分时间我们下载的都是中文的版本,可以通过在/$NetBeans_HOME/etc/netbeans.conf中添加 –locale en_US, 让启动时显示为英文,这个之前也有文章介绍:Netbeans 英文界面 和 最简单的Netbeans中英文切换
2、优化配置可以看之前介绍的这篇文章,就不重复了:Netbeans 6.5 优化建议二、经验分享
1、Swing的Debug虽然被很多人说不好用,但是在用NetBeans时,多用Debug可以提高效率,因为Debug模式下的修改,大部分只要点击应用,就可以不用重启项目而看到效果。
2、很好用的快捷键和快速补齐(限Windows + Linux下,如果在Mac下改成 ⌘ 试试),如:快捷键: Ctrl+R Rename Alt+Enter Fix Error(Eclipse Ctrl+1) Alt+Shift+F Quick Format Alt+Shift+I Fix Import F9 Build File F6 Run Main Project Shift+F6 Run File Ctrl+| Insert Code 快速补齐(英文输入状态下,输入完后按Tab键,也可以自己配置为其他键,在Options - Editor - Code Templates下): psvm public static void main sout System.out.println im implements Psfs public static final String psfi private static final String fore for($ : $){} fori for(int i = 0; i < arr.length; i++){} forl for(int i = 0; i < list.size(); i++){}三、插件分享
我们都知道NetBeans上的插件很多,可以说NetBeans正是因为这些插件才强大起来,支持的功能也更多了。分享的这几个插件是平时工作时,可以显著提高效率的,不好的不推荐,你如果有好的也别忘记分享下。1、Path Tools – 可以直接查找到类或者文件夹所在的磁盘位置,基本是我每次装完NetBeans的后第一个装的插件。
2、SQE(Software Quality Environment) – 是最近同事刚刚推荐的一个插件,看名字就知道了,是一个类似Firebug的插件,可以发现程序中存在的一些显著的错误,很不错。
3、UUID Generator - 同事写的一个快速生成UUID的插件。
4、SwingX 插件 – 用来添加一些SwingX组件的。
5、iReport – 打印报表用的插件,结合JasperReport使用。


