Java JTable列顺序和列宽度保存在用户本地


上周碰到了一个棘手的需求,就是要把用JTable的列顺序和列宽度保存下来,这次用户调整了列宽度,关闭程序,下次再打开时,这个列的宽还是要保持,因为SWing的特性,都是在程序启动时就确定了列顺序和列宽度,而这个程序又是已经投入生产了的,所以并不好做,但是办法总比问题多,所以我详细阅读了JTable这一块儿的源代码,下面贴出来做个分享。 

修改列顺序:

DefaultTableColumnModel columnModel = new DefaultTableColumnModel(){
			@Override
			public void moveColumn(int columnIndex, int newIndex) {
//				修改列顺序
				super.moveColumn(columnIndex, newIndex);
				if(columnIndex != newIndex)
					//入库操作,在这里修改数据库里的顺序
			}
		};

 重写TableColumnModel的moveColumn方法,可以在改变列顺序时触发,我是在本地嵌入了一个H2Database(一个运行在JDK平台上的微型数据库),所以很方便,如果没有的,也可以写入到文件里面。

至于加载列顺序的方法就不贴了,反正就是把在数据库里的顺序加载出来,替换掉在定义JTable时所定义的那个顺序,然后放入TableModel。

加载列宽度:

table = new JTable(defaultTableModel, columnModel) {
			@Override
			public void createDefaultColumnsFromModel() {
//				重写该方法,在创建Column时设置数据库里的宽度
				TableModel m = getModel();
				if (m != null) {
					TableColumnModel cm = getColumnModel();
					while (cm.getColumnCount() > 0) {
						cm.removeColumn(cm.getColumn(0));
					}

					String[] columnNames = new String[m.getColumnCount()];
					for(int i = 0; i < m.getColumnCount(); i++){
						columnNames[i] = m.getColumnName(i);
					}
//                            		操作h2数据库
                        Map columnWidthMap = H2Client.getInstantce().buildTableWidth(module.getClass().getName(), columnNames); for (int i = 0; i < m.getColumnCount(); i++) { TableColumn newColumn = new TableColumn(i,columnWidthMap.get(m.getColumnName(i))); addColumn(newColumn); } } } };

 重写JTable类的createDefaultColumnsFromModel方法,这个方法是根据Model自动创建Column的,当然,也可以拖动创建,那就不用重写这个方法了。

设置宽度:

Enumeration tableColumns = table.getColumnModel().getColumns();
		while(tableColumns.hasMoreElements()){
			TableColumn c = tableColumns.nextElement();
			c.addPropertyChangeListener(new PropertyChangeListener() {
				
				@Override
				public void propertyChange(PropertyChangeEvent evt) {
					if("preferredWidth".equals(evt.getPropertyName())){
//						在设置宽度时会触发该事件,把新的宽度设置入数据库
						TableColumn tc = (TableColumn)evt.getSource();
						String columnName = tc.getHeaderValue().toString();
						String tableName = module.getClass().getName();
						int width = Integer.valueOf(evt.getNewValue().toString());
//                            数据库操作 H2Client.getInstantce().updateColumnWidth(tableName, columnName, width); } } }); }

 给TableColumn加上PropertyChangeListener属性修改事件,宽度修改时,属性为:preferredWidth,把新宽度保存下来。

好了,就到这儿了,欢迎留言。