一、性能问题
随着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:
1 | UIManager.setLookAndFeel(LookAndFeelName); |
2 | SwingUtilities.updateComponentTreeUI(frame); |
三、合理的控制初始化组件和组件初始化的顺序可以很大的提高性能
举个例子:之前我们项目中有一个地方,当打开程序时,会初始化几十个甚至成百个JPanel,这显然成为程序启动时慢的一个因素,也导致了用户体验的降低,这些JPanel完全可以在程序启动后再根据用户的需要去初始化,因为用户打开程序时这些Panel不是必须看到的。
四、要有统一的UI规范
比如Button的高度,进度条的高宽等,也可以通过UIManager给系统组件设置统一属性,比如统一设定Button的间距和字体:
1 | UIManager.put( "Button.margin" , new Insets( 2 , 5 , 2 , 5 )); |
2 | UIManager.put( "Button.font" , new Font( "宋体" , Font.PLAIN, 13 )); |
五、多线程的使用
用Swing做的都是界面的东西,如果界面假死或者用户等待事件太长,那么用户体验必然是不好的,这里就需要用到多线程的使用了,当界面处理一个请求时,不能让界面假死了,需要后台另一个线程去做处理,然后将结果返回到Swing线程,这块可以看看SwingWorker的介绍。
六、布局管理器
布局管理器的使用在Swing里面是比较重要的,它直接决定了你界面的显示效果,也是比较难用的一块,不好举例子,建议多了解每个布局管理器的使用场景。
七、JTable & JTree
在Swing组件的使用中除了布局管理器,估计就数JTable和JTree的使用稍微有点麻烦了,下面我就分享一些实际项目中JTable的一些实例,关于JTree,可以点这里:JTree 经验 总结 。
JTable相关
1、自定义表头排序
1 | TableRowSorter rs = (TableRowSorter) table.getRowSorter(); |
2 | Comparator<Integer> intComparator = new Comparator<Integer>() { |
4 | public int compare(Integer o1, Integer o2) { |
5 | return o1.compareTo(o2); |
8 | rs.setComparator( 3 , intComparator); |
2、自定义Table Renderer
01 | public class CommonTableCellRenderer extends DefaultTableCellRenderer { |
04 | public Component getTableCellRendererComponent(JTable table, Object value, |
05 | boolean isSelected, boolean cellHasFocus, int row, int column) { |
06 | JComponent comp = (JComponent) super .getTableCellRendererComponent(table, value, |
07 | isSelected, cellHasFocus, row, column); |
11 | comp.setBackground(UIConsts.HIGHLIGHTER_COLOR); |
13 | comp.setBackground(Color.white); |
19 | case PaperTableModel.STATUS_COLUMN: |
20 | switch ((EntityStatus) value) { |
22 | comp.setIcon(ENABLED_ICON); |
23 | setHorizontalAlignment(JLabel.LEADING); |
26 | comp.setIcon(DISABLED_ICON); |
27 | setHorizontalAlignment(JLabel.CENTER); |
3、自定义Table列宽
1 | TableColumnModel colModel = table.getColumnModel(); |
2 | colModel.getColumn( 0 ).setPreferredWidth( 70 ); |
3 | colModel.getColumn( 1 ).setPreferredWidth( 55 ); |
4 | colModel.getColumn( 2 ).setPreferredWidth( 120 ); |
4、禁止Table列拖动
1 | table.getTableHeader().setReorderingAllowed( false ); |
5、单选表格设置
1 | table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); |
6、设置表头默认支持排序
1 | table.setAutoCreateRowSorter( true ); |
7、设置列不可随容器组件大小变化自动调整宽度
1 | table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); |
8、固定Table上的某些列不滚动
这个需求是这样的,比如Table上左边有部分数据,是后面数据所共有的属性,那么当后面数据很多时,显示不下会出现滚动条,但是滚动时又不想让左侧的共有属性动,只滚动右侧的数据部分。
实现原理是:scrollPane里面放置一个表格,然后在scrollPane的左上角放置以共有属性的部分为Model的表格,剩下的右侧就是剩余的纯数据表格。
最终效果就是表格左侧的列锁定了,右侧数据出现滚动条时,可以滚动,但左侧不动。
核心代码:比如有HeaderTable和ReportTable, 其中ReportTable是放置在一个ScrollPanel里面,Model是所有数据的Model,将左侧的数据和右侧的数据分开
02 | JScrollPane scrollPane = (JScrollPane) SwingUtilities. |
03 | getAncestorOfClass(JScrollPane. class , |
04 | reportTable.getTable()); |
09 | scrollPane.setRowHeaderView(headerTable.getTable()); |
10 | scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, |
11 | headerTable.getTable().getTableHeader()); |
9、Table上的直接编辑功能
两点:
1、重写 public boolean isCellEditable(int row, int columnIndex) 方法,定义可编辑的行列。
2、重写 public void setValueAt(Object obj, int rowIndex, int columnIndex) 方法,拿到原来的对象,设置新的对象值。