source: AE/installer2/src/net/oni2/aeinstaller/gui/modtable/ModTable.java@ 658

Last change on this file since 658 was 658, checked in by alloc, 12 years ago

AEI2 0.99i:

  • Lots of refactorings for the GUI:
    • Global type for the mod info box (Main, Tools, Core)
    • Same table for Main, Tools, Core
File size: 10.4 KB
Line 
1package net.oni2.aeinstaller.gui.modtable;
2
3import java.awt.Desktop;
4import java.awt.Rectangle;
5import java.awt.event.ActionEvent;
6import java.awt.event.ActionListener;
7import java.awt.event.KeyAdapter;
8import java.awt.event.KeyEvent;
9import java.awt.event.MouseAdapter;
10import java.awt.event.MouseEvent;
11import java.io.File;
12import java.io.IOException;
13import java.util.ArrayList;
14import java.util.HashSet;
15import java.util.List;
16import java.util.ResourceBundle;
17import java.util.TreeSet;
18
19import javax.swing.JComponent;
20import javax.swing.JMenuItem;
21import javax.swing.JOptionPane;
22import javax.swing.JPopupMenu;
23import javax.swing.JTable;
24import javax.swing.JViewport;
25import javax.swing.ListSelectionModel;
26import javax.swing.RowSorter;
27import javax.swing.SortOrder;
28import javax.swing.event.ListSelectionEvent;
29import javax.swing.event.RowSorterEvent;
30import javax.swing.table.TableRowSorter;
31
32import net.oni2.aeinstaller.backend.Settings;
33import net.oni2.aeinstaller.backend.packages.Package;
34import net.oni2.aeinstaller.backend.packages.Type;
35
36/**
37 * @author Christian Illy
38 */
39public class ModTable extends JTable {
40 private static final long serialVersionUID = 1L;
41
42 private ResourceBundle bundle = ResourceBundle
43 .getBundle("net.oni2.aeinstaller.localization.ModTable");
44
45 /**
46 * @author Christian Illy
47 */
48 public enum ETableContentType {
49 /**
50 * Table showing mods
51 */
52 MODS,
53 /**
54 * Table showing tools
55 */
56 TOOLS,
57 /**
58 * Table showing core packages
59 */
60 CORE
61 };
62
63 private HashSet<ModSelectionListener> modSelListeners = new HashSet<ModSelectionListener>();
64
65 private ModTableModel model;
66 private TableRowSorter<ModTableModel> sorter;
67
68 private ETableContentType contentType = ETableContentType.MODS;
69
70 /**
71 * Create a new ModTable
72 *
73 * @param contentType
74 * Content to show
75 */
76 public ModTable(ETableContentType contentType) {
77 super();
78
79 this.contentType = contentType;
80
81 setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
82 getSelectionModel().addListSelectionListener(this);
83 addMouseListener(new MouseEventHandler());
84 addKeyListener(new KeyEventHandler());
85 // To get checkbox-cells with background of row
86 ((JComponent) getDefaultRenderer(Boolean.class)).setOpaque(true);
87
88 model = new ModTableModel(contentType);
89
90 setModel(model);
91
92 sorter = new TableRowSorter<ModTableModel>(model);
93 setRowSorter(sorter);
94
95 setFilter(null, 0);
96
97 List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
98
99 int sortCol = Settings.getInstance().get("modSortColumn", 1);
100 SortOrder sortOrder = SortOrder.valueOf(Settings.getInstance().get(
101 "modSortOrder", "ASCENDING"));
102
103 sortKeys.add(new RowSorter.SortKey(sortCol, sortOrder));
104 sorter.setSortKeys(sortKeys);
105
106 for (int i = 0; i < model.getColumnCount(); i++) {
107 model.setColumnConstraints(i, getColumnModel().getColumn(i));
108 }
109
110 if (contentType != ETableContentType.MODS) {
111 getColumnModel().removeColumn(getColumnModel().getColumn(0));
112 }
113 }
114
115 @Override
116 public String getToolTipText(MouseEvent e) {
117 int r = rowAtPoint(e.getPoint());
118 int c = columnAtPoint(e.getPoint());
119 if (r >= 0 && r < getRowCount()) {
120 int modelCol = convertColumnIndexToModel(c);
121 if (modelCol == 4) {
122 final Package mod = (Package) getValueAt(r, -1);
123
124 String tt = "<html>";
125 tt += String.format("%s: %s<br>",
126 bundle.getString("state.installed"),
127 bundle.getString((mod.isInstalled() ? "yes" : "no")));
128 tt += String.format(
129 "%s: %s<br>",
130 bundle.getString("state.updatable"),
131 bundle.getString((mod.isLocalAvailable()
132 && mod.isNewerAvailable() ? "yes" : "no")));
133 tt += String.format("%s: %s</html>", bundle
134 .getString("state.downloaded"), bundle.getString((mod
135 .isLocalAvailable() ? "yes" : "no")));
136 return tt;
137 }
138 }
139 return super.getToolTipText(e);
140 }
141
142 /**
143 * @param listener
144 * Listener to add
145 */
146 public void addModSelectionListener(ModSelectionListener listener) {
147 modSelListeners.add(listener);
148 }
149
150 /**
151 * @param listener
152 * Listener to remove
153 */
154 public void removeModSelectionListener(ModSelectionListener listener) {
155 modSelListeners.remove(listener);
156 }
157
158 private void notifyModSelectionListeners(Package m) {
159 for (ModSelectionListener l : modSelListeners) {
160 l.modSelectionChanged(this, m);
161 }
162 }
163
164 /**
165 * @param listener
166 * Listener to add
167 */
168 public void addDownloadSizeListener(DownloadSizeListener listener) {
169 model.addDownloadSizeListener(listener);
170 }
171
172 /**
173 * @param listener
174 * Listener to remove
175 */
176 public void removeDownloadSizeListener(DownloadSizeListener listener) {
177 model.removeDownloadSizeListener(listener);
178 }
179
180 /**
181 * Reload the nodes data after an update to the cache
182 */
183 public void reloadData() {
184 model.reloadData();
185 }
186
187 /**
188 * Revert the selection to the mods that are currently installed
189 */
190 public void revertSelection() {
191 model.revertSelection();
192 }
193
194 /**
195 * Reload the selection after a config was loaded
196 *
197 * @param config
198 * Config to load
199 */
200 public void reloadSelection(File config) {
201 model.reloadSelection(config);
202 }
203
204 /**
205 * @return Mods selected for installation
206 */
207 public TreeSet<Package> getSelectedMods() {
208 return model.getSelectedMods();
209 }
210
211 /**
212 * @param type
213 * Type of mods to show (null for all)
214 * @param downloadState
215 * Show only: 0 = all, 1 = online, 2 = downloaded
216 */
217 public void setFilter(Type type, int downloadState) {
218 sorter.setRowFilter(new ModTableFilter(type, downloadState,
219 contentType == ETableContentType.CORE, false));
220 }
221
222 @Override
223 public void sorterChanged(RowSorterEvent evt) {
224 super.sorterChanged(evt);
225 if (evt.getType() == RowSorterEvent.Type.SORT_ORDER_CHANGED) {
226 @SuppressWarnings("unchecked")
227 RowSorter<ModTableModel> rs = (RowSorter<ModTableModel>) getRowSorter();
228 List<? extends RowSorter.SortKey> keys = rs.getSortKeys();
229 if (keys.size() > 0) {
230 int col = keys.get(0).getColumn();
231 SortOrder so = keys.get(0).getSortOrder();
232 Settings.getInstance().put("modSortColumn", col);
233 Settings.getInstance().put("modSortOrder", so.toString());
234 }
235 }
236 }
237
238 /**
239 * Select/Unselect all currently visible items depending on the current
240 * state of selection
241 */
242 public void unSelectAll() {
243 boolean isAll = true;
244 for (int i = 0; i < getRowCount(); i++) {
245 int modRow = convertRowIndexToModel(i);
246 boolean inst = (Boolean) model.getValueAt(modRow, 0);
247 if (!inst) {
248 isAll = false;
249 break;
250 }
251 }
252
253 for (int i = 0; i < getRowCount(); i++) {
254 int modRow = convertRowIndexToModel(i);
255 model.setValueAt(!isAll, modRow, 0);
256 }
257 invalidate();
258 repaint();
259 }
260
261 @Override
262 public void valueChanged(ListSelectionEvent e) {
263 super.valueChanged(e);
264 int viewRow = getSelectedRow();
265 if (viewRow < 0) {
266 notifyModSelectionListeners(null);
267 } else {
268 Package mod = (Package) getValueAt(viewRow, -1);
269 notifyModSelectionListeners(mod);
270 }
271 }
272
273 private class MouseEventHandler extends MouseAdapter {
274 private void mouseEventProcessing(MouseEvent e) {
275 int r = rowAtPoint(e.getPoint());
276 if (r >= 0 && r < getRowCount())
277 setRowSelectionInterval(r, r);
278 else
279 clearSelection();
280
281 int rowindex = getSelectedRow();
282 if (rowindex >= 0) {
283 if (e.isPopupTrigger() && e.getComponent() instanceof JTable) {
284 final Package mod = (Package) getValueAt(rowindex, -1);
285
286 JPopupMenu popup = new JPopupMenu();
287
288 if (mod.isLocalAvailable()) {
289 // Open package folder item
290 JMenuItem openModFolder = new JMenuItem(
291 bundle.getString("openModFolder.text"));
292 openModFolder.addActionListener(new ActionListener() {
293 @Override
294 public void actionPerformed(ActionEvent arg0) {
295 try {
296 Desktop.getDesktop().open(
297 mod.getLocalPath());
298 } catch (IOException e) {
299 e.printStackTrace();
300 }
301 }
302 });
303 popup.add(openModFolder);
304 }
305
306 if (mod.getUrl() != null) {
307 // Open Depot page item
308 JMenuItem openDepotPage = new JMenuItem(
309 bundle.getString("openDepotPage.text"));
310 openDepotPage.addActionListener(new ActionListener() {
311 @Override
312 public void actionPerformed(ActionEvent arg0) {
313 try {
314 Desktop.getDesktop().browse(mod.getUrl());
315 } catch (IOException e) {
316 e.printStackTrace();
317 }
318 }
319 });
320 popup.add(openDepotPage);
321 }
322
323 if (mod.isLocalAvailable()
324 && contentType != ETableContentType.CORE) {
325 // Delete package folder item
326 JMenuItem deleteModFolder = new JMenuItem(
327 bundle.getString("deletePackage.text"));
328 deleteModFolder.addActionListener(new ActionListener() {
329 @Override
330 public void actionPerformed(ActionEvent arg0) {
331 if (mod.getNode() == null) {
332 JOptionPane.showMessageDialog(
333 null,
334 bundle.getString("deletePackageLocalOnly.text"),
335 bundle.getString("deletePackageLocalOnly.title"),
336 JOptionPane.INFORMATION_MESSAGE);
337 } else {
338 int res = JOptionPane.showConfirmDialog(
339 null,
340 bundle.getString("deletePackageConfirm.text"),
341 bundle.getString("deletePackageConfirm.title"),
342 JOptionPane.YES_NO_OPTION,
343 JOptionPane.WARNING_MESSAGE);
344 if (res == JOptionPane.YES_OPTION) {
345 mod.deleteLocalPackage();
346 invalidate();
347 repaint();
348 }
349 }
350 }
351 });
352 popup.add(deleteModFolder);
353 }
354
355 if (popup.getSubElements().length > 0)
356 popup.show(e.getComponent(), e.getX(), e.getY());
357 }
358 }
359 }
360
361 @Override
362 public void mousePressed(MouseEvent e) {
363 mouseEventProcessing(e);
364 }
365
366 @Override
367 public void mouseReleased(MouseEvent e) {
368 mouseEventProcessing(e);
369 }
370 }
371
372 private class KeyEventHandler extends KeyAdapter {
373 @Override
374 public void keyTyped(KeyEvent e) {
375 super.keyTyped(e);
376
377 if (e.getModifiers() == 0) {
378 String key = String.valueOf(e.getKeyChar()).toLowerCase();
379 for (int i = 0; i < getRowCount(); i++) {
380 Package m = (Package) getValueAt(i, -1);
381 if (m.getName().toLowerCase().startsWith(key)) {
382 setRowSelectionInterval(i, i);
383 JViewport viewport = (JViewport) getParent();
384 Rectangle rect = getCellRect(i, 0, true);
385 Rectangle r2 = viewport.getVisibleRect();
386 scrollRectToVisible(new Rectangle(rect.x, rect.y,
387 (int) r2.getWidth(), (int) r2.getHeight()));
388 break;
389 }
390 }
391 }
392 }
393 }
394}
Note: See TracBrowser for help on using the repository browser.