View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.gui.table;
21  
22  import java.beans.PropertyChangeEvent;
23  import java.beans.PropertyChangeListener;
24  import java.util.Arrays;
25  import java.util.HashSet;
26  
27  import javax.swing.event.ChangeEvent;
28  import javax.swing.event.ListSelectionEvent;
29  import javax.swing.event.TableColumnModelEvent;
30  import javax.swing.event.TableColumnModelListener;
31  import javax.swing.table.TableColumnModel;
32  
33  import org.xnap.util.TablePreferencesProvider;
34  
35  /***
36   * Takes care of the table preferences.
37   */
38  public class TablePreferencesHandler 
39      implements PropertyChangeListener, TableHeaderListener
40  {
41  
42      //--- Data field(s) ---
43  
44      private TablePreferencesProvider prefs;
45      private String table;
46      private TableColumnModel tcm;
47      private ColumnModel model;
48  
49      //--- Constructor(s) ---
50  
51      /***
52       *
53       */
54      public TablePreferencesHandler(TablePreferencesProvider prefs, String table, 
55  								   ColumnModel model, TableColumnModel tcm)
56      {
57  		this.prefs = prefs;
58  		this.table = table;
59  		this.model = model;
60  		this.tcm = tcm;
61  
62  		tcm.addColumnModelListener(new ColumnListener());
63  
64  		if (model instanceof SortableModel) {
65  			((SortableModel)model).setMaintainSortOrder
66  				(prefs.getTableMaintainSortOrder(table));
67  		}
68  		prefs.addTableListener(table, this);
69  
70  		restore();
71      }
72  
73      //--- Method(s) ---
74  
75      public TablePreferencesProvider getPreferencesSupport()
76      {
77  		return prefs;
78      }
79  
80  	public Column getColumnByKey(String key)
81  	{
82  		for (int i = 0; i < model.getColumnCount(); i++) {
83  			if (model.getColumnAt(i).getKey().equals(key)) {
84  				return model.getColumnAt(i);
85  			}
86  		}
87  		return null;
88  	}
89  
90      /***
91       * Returns the preferences key.
92       */
93      public String getTable()
94      {
95  		return table;
96      }
97  
98      public void propertyChange(PropertyChangeEvent e)
99      {
100 		setVisible(prefs.getTableColumns(table));
101 		if (model instanceof SortableModel) {
102 			((SortableModel)model).setMaintainSortOrder
103 				(prefs.getTableMaintainSortOrder(table));
104 		}
105     }
106 
107     /***
108      * Restores the table width and sort order.
109      */
110     public void restore()
111     {
112 		// add columns and restore order of columns
113 		String[] visibleKeysArray = prefs.getTableColumns(table);
114 		for (int i = 0; i < visibleKeysArray.length; i++) {
115 			Column c = getColumnByKey(visibleKeysArray[i]);
116 			if (c != null) {
117 				tcm.addColumn(c);
118 				c.setVisible(true);
119 			}
120 		}
121 		
122 		// make sure at least one column is visible
123 		setVisible(visibleKeysArray);
124 
125 		// restore table widths
126 		int[] widths = prefs.getTableColumnWidths(table);
127 		for (int i = 0; i < widths.length && i < model.getColumnCount(); i++) {
128 			model.getColumnAt(i).setPreferredWidth(widths[i]);
129 			model.getColumnAt(i).setWidth(widths[i]);
130 		}
131 	    
132 		// restore sort order
133 		int c = prefs.getTableSortedColumn(table);
134 		if (c != 0) {
135 			int column = Math.abs(c) - 1;
136 			if (model instanceof SortableModel 
137 				&& column >= 0 && column < model.getColumnCount()) {
138 
139 				((SortableModel)model).sortByColumn(column, c > 0, false);
140 			}
141 		}
142     }
143 
144     public void setVisible(String[] visibleKeysArray)
145     {
146 		HashSet visibleKeys = new HashSet(Arrays.asList(visibleKeysArray));
147 
148 		boolean visible = false;
149 		for (int i = 0; i < model.getColumnCount(); i++) {
150 			boolean newStatus 
151 				= visibleKeys.contains(model.getColumnAt(i).getKey());
152 			visible |= newStatus;
153 			Column c = model.getColumnAt(i);
154 			if (c.isVisible() != newStatus) {
155 				if (newStatus) {
156 					tcm.addColumn(c);
157 				}
158 				else {
159 					tcm.removeColumn(c);
160 				}
161 				c.setVisible(newStatus);
162 			}
163 		}
164 
165 		if (!visible && model.getColumnCount() > 0) {
166 			// make sure at least one column is visible
167 			prefs.setTableColumns
168 				(table, new String[] { model.getColumnAt(0).getKey() });
169 		}
170     }
171 
172     /***
173      * Saves the sorted column.
174      *
175      * <p>Writes 0, if no column was ever sorted; index + 1, if the
176      * column was sorted ascending; -index - 1, if the column was
177      * sorted descending ;).
178      */
179     public void sortedColumnChanged()
180     {
181 		if (model instanceof SortableModel) {
182 			int column = ((SortableModel)model).getSortedColumn();
183 			column = (column == -1)
184 				? 0
185 				: (((SortableModel)model).isSortedAscending()) 
186 				? +(column + 1) 
187 				: -(column + 1);
188 
189 			prefs.setTableSortedColumn(table, column);
190 		}
191     }
192 
193     /***
194      * Saves the width of all columns.
195      */
196     public void columnWidthChanged()
197     {
198 		int[] widths = new int[model.getColumnCount()];
199 		for (int i = 0; i < widths.length; i++) {
200 			widths[i] = model.getColumnAt(i).getWidth();
201 		}
202 		prefs.setTableColumnWidths(table, widths);
203     }
204 
205     protected class ColumnListener implements TableColumnModelListener 
206     {
207 
208 		public void columnAdded(TableColumnModelEvent event) 
209 		{
210 		}
211 
212 		public void columnMarginChanged(ChangeEvent event)
213 		{
214 		}
215 
216 		public void columnMoved(TableColumnModelEvent event)
217 		{
218 			String[] colKeys = new String[tcm.getColumnCount()];
219 			for (int i = 0; i < colKeys.length; i++) {
220 				colKeys[i] = ((Column)tcm.getColumn(i)).getKey();
221 			}
222 
223 			try {
224 				prefs.setTableColumns(table, colKeys);
225 			}
226 			catch (IllegalArgumentException e) {
227 				// FIX: we should restore the correct order here
228 			}
229 		}
230 
231 		public void columnRemoved(TableColumnModelEvent event)
232 		{
233 		}
234 
235 		public void columnSelectionChanged(ListSelectionEvent event) 
236 		{
237 		}
238 
239     }
240 
241 }