Source Code Cross Referenced for SortableTableModel.java in  » IDE » tIDE » snow » sortabletable » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » tIDE » snow.sortabletable 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package snow.sortabletable;
002:
003:        import javax.swing.table.*;
004:        import java.util.*;
005:        import javax.swing.event.*;
006:        import javax.swing.*;
007:        import java.awt.event.*;
008:        import java.awt.*;
009:        import java.util.regex.*;
010:
011:        /** Wraps a basic model and allow sorting of his columns
012:         the basic model remains unchanged. Only this model is sorted !
013:         Features :
014:         + The selection is maintained after table updates.
015:         + Can installGUI() without corrupting model/view separation
016:
017:         usage:
018:         1) make a FineGrain table model (like AbstractTableModel...)
019:         2) make this class, pass 1)
020:         3) make a table with this model 2)
021:         4) call installGUI() with the table 3) to allow sorting
022:         */
023:        public class SortableTableModel extends AbstractTableModel {
024:            // these are the indices in the unsirted model corresponding to the position in this
025:            // sorted model. element i is for position i in this table
026:            // WITHOUT SEARCH HITS
027:            final Vector<Integer> sortedRowIndices = new Vector<Integer>();
028:
029:            // i-th element is the index in the basic model of the ith found element
030:            final Vector<Integer> foundBasicIndices = new Vector<Integer>();
031:
032:            // this is the unsorted model
033:            private FineGrainTableModel basicTableModel;
034:
035:            public final static Icon SORT_ASC = new SortDirectionSelfDrawingIcon(
036:                    SortDirectionSelfDrawingIcon.Ascending);
037:            public final static Icon SORT_DESC = new SortDirectionSelfDrawingIcon(
038:                    SortDirectionSelfDrawingIcon.Descending);
039:
040:            // used to remember selection when table change
041:            JTable tableReference;
042:            JTable tableRowHeadersReference;
043:            int numberOfColumnAsRowHeaders = 0;
044:
045:            // contain the basic model column indices to show (selected = visible)
046:            // 0, 1, 3, 4    for example if column2 is not visible
047:            final private Set<Integer> selectedColumns = new TreeSet<Integer>();
048:
049:            private boolean columnVisibilitiesChangeEnable = true;
050:
051:            private boolean multiSearch = false;
052:            private Query[] queries = null;
053:
054:            /** wraps a sortable feature around your basic table model
055:
056:              Easy usage:
057:                1) just create your model, pass it here
058:                2) use this model as tablemodel for your jtable.
059:                3) After that, call installGUI and pass your JTable as argument.
060:             */
061:            public SortableTableModel(FineGrainTableModel basicTableModel) {
062:                this (basicTableModel, 0, true);
063:            }
064:
065:            public FineGrainTableModel getBasicTableModel() {
066:                return basicTableModel;
067:            }
068:
069:            TableModelListener tableModelListener = null;
070:            TableModelChangeListener tableModelChangeListener = null;
071:
072:            /** wraps a sortable feature around your basic table model
073:
074:              Easy usage:
075:                1) just create your model, pass it here
076:                2) use this model as tablemodel for your jtable.
077:                3) After that, call installGUI and pass your JTable as argument.
078:             */
079:            public SortableTableModel(FineGrainTableModel basicTableModel,
080:                    int sortedColumn, boolean ascending) {
081:                setBasicTableModel(basicTableModel, sortedColumn, ascending);
082:            }
083:
084:            public void setBasicTableModel(FineGrainTableModel basicTableModel,
085:                    int sortedColumn, boolean ascending) {
086:                removeOldListeners();
087:
088:                this .basicTableModel = basicTableModel;
089:                this .sortedColumnInBasicModel = sortedColumn;
090:                this .ascending = ascending;
091:
092:                tableModelListener = new TableModelListener() {
093:                    // called after the table has changed
094:                    public void tableChanged(TableModelEvent e) {
095:                        //System.out.println("received tableChanged event from unsortedModel");
096:                        createRangeForSorting(); // range 0,...,n-1
097:                        internalSort();
098:                        internal_multisearch();
099:
100:                        // pass the event in same EDT for this listener
101:                        fireTableDataChanged();
102:                        //tableChanged(e);  // index mismatch... should convert them... ###
103:                    }
104:                };
105:                basicTableModel.addTableModelListener(tableModelListener);
106:
107:                tableModelChangeListener = new TableModelChangeListener() {
108:                    public void tableModelWillChange(ChangeEvent e) {
109:                        storeTableSelection();
110:                    }
111:
112:                    public void tableModelHasChanged(ChangeEvent e) {
113:                        restoreTableSelections();
114:                    }
115:                };
116:                basicTableModel
117:                        .addModelChangeListener(tableModelChangeListener);
118:
119:                // all columns are selected
120:                for (int i = 0; i < basicTableModel.getColumnCount(); i++) {
121:                    selectedColumns.add(i);
122:                }
123:
124:                // initial sort
125:                createRangeForSorting();
126:                sort(sortedColumn, ascending);
127:                internal_multisearch();
128:
129:                restoreTableSelections(); // ??? not now, but when table installed !!
130:
131:            } // Constructor
132:
133:            public void removeOldListeners() {
134:                if (basicTableModel != null) {
135:                    basicTableModel
136:                            .removeTableModelListener(tableModelListener);
137:                    basicTableModel
138:                            .removeModelChangeListener(tableModelChangeListener);
139:                }
140:
141:                if (tableHeadClickMouseAdapter != null) {
142:                    tableRowHeadersReference
143:                            .removeMouseListener(tableHeadClickMouseAdapter);
144:                }
145:                if (tableRefClickMouseAdapter != null) {
146:                    tableReference
147:                            .removeMouseListener(tableRefClickMouseAdapter);
148:                }
149:            }
150:
151:            /** free resource, listeners and so on...
152:             */
153:            public synchronized void terminate() {
154:                removeOldListeners();
155:
156:                if (basicTableModel != null) {
157:                    this .basicTableModel.terminate();
158:                    basicTableModel = null;
159:                }
160:            }
161:
162:            /** only call this when you terminate the table,
163:                to keep selection stored in model (if implemented)
164:             */
165:            public synchronized void storeTableSelection() {
166:                //System.out.println("Store sel");
167:                if (!SwingUtilities.isEventDispatchThread()) {
168:                    new Throwable("Must be called from EDT !")
169:                            .printStackTrace();
170:                }
171:
172:                if (tableReference == null)
173:                    return;
174:
175:                // store the selection (store indices of the basic model
176:                int[] sel = tableReference.getSelectedRows();
177:                basicTableModel.clearRowSelection();
178:                for (int i = 0; i < sel.length; i++) {
179:                    int indexThis = sel[i];
180:                    int indexBase = getIndexInUnsortedFromTablePos(indexThis);
181:                    basicTableModel.setRowSelection(indexBase, true);
182:                }
183:            }
184:
185:            private synchronized void restoreTableSelections() {
186:                if (tableReference == null)
187:                    return;
188:                if (this .getRowCount() == 0)
189:                    return;
190:                if (!SwingUtilities.isEventDispatchThread()) {
191:                    new Throwable("Must be called from EDT !")
192:                            .printStackTrace();
193:                }
194:
195:                // restore selection
196:                tableReference.getSelectionModel().clearSelection();
197:                int[] sel = basicTableModel.getSelectedRows();
198:                for (int i = 0; i < sel.length; i++) {
199:                    int indexBase = sel[i];
200:                    int pos = getIndexInFoundFromBasicIndex(indexBase);
201:
202:                    if (pos >= 0 && pos < tableReference.getRowCount()) {
203:                        if (tableReference.getSelectionModel()
204:                                .getSelectionMode() == ListSelectionModel.SINGLE_SELECTION) {
205:                            tableReference.setRowSelectionInterval(pos, pos);
206:                        } else {
207:                            tableReference.addRowSelectionInterval(pos, pos);
208:                        }
209:                    }
210:                }
211:
212:                // ### needed to display correctly !!!
213:                if (tableReference != null)
214:                    tableReference.revalidate(); // .repaint();
215:                if (tableRowHeadersReference != null)
216:                    tableRowHeadersReference.revalidate();
217:            }
218:
219:            /** This just creates a range 0.. size-1 used to sort.
220:             */
221:            private synchronized void createRangeForSorting() {
222:                // nothing to do if the size is ok
223:                if (sortedRowIndices.size() == basicTableModel.getRowCount())
224:                    return;
225:
226:                synchronized (this ) {
227:                    sortedRowIndices.removeAllElements();
228:                    for (int i = 0; i < basicTableModel.getRowCount(); i++) {
229:                        sortedRowIndices.addElement(i);
230:                    }
231:                }
232:            }
233:
234:            /** @return true if the search is active.
235:             *
236:            public synchronized boolean isSearchActive()
237:            {
238:               if(search1.length()>0) return true;
239:               if(search2!=null) return true;
240:               return false;
241:            }
242:            /*
243:            String search1 = "";
244:            String search2 = null;
245:            boolean useRegEx = false;
246:            Pattern p1 = null;
247:            Pattern p2 = null;
248:            int searchColumn = -1;  // -1 => all
249:            boolean andSearch = true;
250:             */
251:            public synchronized void search(String str1, String str2,
252:                    boolean useRegEx) {
253:                if (!SwingUtilities.isEventDispatchThread()) {
254:                    new Throwable("Must be called from EDT !")
255:                            .printStackTrace();
256:                }
257:
258:                Query q1 = new Query(-1, str1, Query.Combine.And,
259:                        (useRegEx ? Query.Comparison.RegEx
260:                                : Query.Comparison.Contains));
261:                Query q2 = new Query(-1, str2, Query.Combine.And,
262:                        (useRegEx ? Query.Comparison.RegEx
263:                                : Query.Comparison.Contains));
264:
265:                this .multiSearch(new Query[] { q1, q2 });
266:            }
267:
268:            public synchronized void advancedSearch(String str1, String str2,
269:                    boolean andSearch, boolean useRegEx, int column) {
270:                Query q1 = new Query(column, str1, Query.Combine.And,
271:                        (useRegEx ? Query.Comparison.RegEx
272:                                : Query.Comparison.Contains));
273:                Query q2 = new Query(column, str2,
274:                        (andSearch ? Query.Combine.And : Query.Combine.Or),
275:                        (useRegEx ? Query.Comparison.RegEx
276:                                : Query.Comparison.Contains));
277:
278:                this .multiSearch(new Query[] { q1, q2 });
279:            }
280:
281:            /** SPECIAL CASE: Table with row index.
282:                the two tables have the same selection model.
283:             */
284:            public void installGUI(JTable tHead, JTable table) {
285:                // synchronize the selections => simply use the same models !!
286:                tHead.setSelectionModel(table.getSelectionModel());
287:
288:                this .tableReference = table;
289:                this .tableRowHeadersReference = tHead;
290:
291:                numberOfColumnAsRowHeaders = tHead.getColumnCount();
292:
293:                // we just install header renderers
294:                setHeaders();
295:                installHeaderClickListeners();
296:
297:            }
298:
299:            /** used to render headers...
300:             */
301:            public void installGUI(JTable _tableReference) {
302:                this .tableReference = _tableReference;
303:                setHeaders(); // calls setHeadersForIndexTable()
304:
305:                installHeaderClickListeners();
306:
307:                // this is the first sel, from model, when the three methods
308:                // are implemented
309:                EventQueue.invokeLater(new Runnable() {
310:                    public void run() {
311:                        restoreTableSelections();
312:
313:                        int fontSize = UIManager.getFont("Label.font")
314:                                .getSize();
315:                        for (int i = 0; i < tableReference.getColumnCount(); i++) {
316:                            int w = basicTableModel.getPreferredColumnWidth(i);
317:                            if (w > 0) {
318:                                tableReference.getColumnModel().getColumn(i)
319:                                        .setPreferredWidth(w * fontSize);
320:                            }
321:                        }
322:
323:                    }
324:                });
325:            }
326:
327:            public void setColumnVisibilityToggle(boolean enable) {
328:                columnVisibilitiesChangeEnable = enable;
329:            }
330:
331:            /** actually only for tables without header
332:              Must be caled after installGUI !
333:             */
334:            public void setPreferredColumnSizesFromModel() {
335:                if (tableReference == null)
336:                    return;
337:
338:                int fontSize = UIManager.getFont("Label.font").getSize();
339:                for (int i = 0; i < tableReference.getColumnCount(); i++) {
340:                    int pos = this .getColumnForViewIndex(i);
341:                    int w = this .basicTableModel.getPreferredColumnWidth(pos);
342:                    if (w > 0) {
343:                        tableReference.getColumnModel().getColumn(i)
344:                                .setPreferredWidth(w * fontSize);
345:                    }
346:                }
347:
348:            }
349:
350:            MouseAdapter tableRefClickMouseAdapter = null;
351:            MouseAdapter tableHeadClickMouseAdapter = null;
352:
353:            /** Listen to click on the table headers used to toggle sorting.
354:             */
355:            private void installHeaderClickListeners() {
356:                if (tableRefClickMouseAdapter != null) {
357:                    tableReference
358:                            .removeMouseListener(tableRefClickMouseAdapter);
359:                }
360:
361:                // listen to click on the table headers used to toggle sorting
362:                tableRefClickMouseAdapter = new MouseAdapter() {
363:                    @Override
364:                    public void mouseReleased(MouseEvent e) {
365:                        if (e.isPopupTrigger()
366:                                && columnVisibilitiesChangeEnable) {
367:                            // on windows
368:                            showColumnSelectionPopup(e);
369:                            //e.consume();
370:                        }
371:                    }
372:
373:                    @Override
374:                    public void mousePressed(MouseEvent e) {
375:                        if (e.isPopupTrigger()
376:                                && columnVisibilitiesChangeEnable) {
377:                            // on linux
378:                            showColumnSelectionPopup(e);
379:                            //e.consume();
380:                        }
381:                    }
382:
383:                    @Override
384:                    public void mouseClicked(MouseEvent e) {
385:                        // [EDT]
386:
387:                        int columnView = tableReference.getColumnModel()
388:                                .getColumnIndexAtX(e.getX());
389:                        int columnModel = tableReference
390:                                .convertColumnIndexToModel(columnView);
391:
392:                        if (columnModel >= 0) {
393:                            //TableColumn tc = tableReference.getColumnModel().getColumn(columnModel);
394:
395:                            // convert to model taking in account the columns that are not visible
396:                            int columnIndexInModel = getModelIndexForClickedColumn(columnModel);
397:
398:                            // if this is the column already selected, invert the order
399:                            if (sortedColumnInBasicModel == columnIndexInModel
400:                                    + numberOfColumnAsRowHeaders) {
401:                                ascending = !ascending;
402:                            } else {
403:                                ascending = true;
404:                            }
405:                            sortedColumnInBasicModel = columnIndexInModel
406:                                    + numberOfColumnAsRowHeaders;
407:                            //System.out.println("Sorted column in basic model = " + sortedColumnInBasicModel);
408:
409:                            storeTableSelection();
410:
411:                            internalSort();
412:                            internal_multisearch();
413:
414:                            fireTableDataChanged();
415:
416:                            restoreTableSelections();
417:
418:                            setHeaders(); // calls setHeadersForIndexTable()
419:                            // strange... when not invoked, is sometimes not repainted
420:                            if (tableReference != null) {
421:                                tableReference.getTableHeader().repaint(); // we're in the EDT... ok
422:                            }
423:                            if (tableRowHeadersReference != null) {
424:                                tableRowHeadersReference.getTableHeader()
425:                                        .repaint(); // we're in the EDT... ok
426:                            }
427:                            //tableHeader.invalidate();
428:                        }
429:                    }
430:                };
431:                tableReference.getTableHeader().addMouseListener(
432:                        tableRefClickMouseAdapter);
433:
434:                // index table
435:                //
436:                if (tableRowHeadersReference == null)
437:                    return;
438:
439:                if (tableHeadClickMouseAdapter != null) {
440:                    tableRowHeadersReference
441:                            .removeMouseListener(tableHeadClickMouseAdapter);
442:                }
443:
444:                tableRowHeadersReference.getTableHeader().addMouseListener(
445:                        tableHeadClickMouseAdapter = new MouseAdapter() {
446:                            @Override
447:                            public void mouseClicked(MouseEvent e) {
448:                                //final int column = tableReference.columnAtPoint(new Point(e.getX(), e.getY()));
449:                                int columnView = tableRowHeadersReference
450:                                        .getColumnModel().getColumnIndexAtX(
451:                                                e.getX());
452:                                int columnModel = tableRowHeadersReference
453:                                        .convertColumnIndexToModel(columnView);
454:
455:                                //System.out.println("Click column "+columnModel);
456:
457:                                if (columnModel >= 0) {
458:                                    //TableColumn tc = tableRowHeadersReference.getColumnModel().getColumn(columnModel);
459:                                    if (sortedColumnInBasicModel == columnModel) {
460:                                        ascending = !ascending;
461:                                    } else {
462:                                        ascending = true;
463:                                    }
464:                                    sortedColumnInBasicModel = columnModel;
465:                                    //System.out.println("Sort column "+sortedColumn);
466:
467:                                    //setHeadersForMainTable();
468:                                    //tableHeader.repaint();
469:
470:                                    storeTableSelection();
471:
472:                                    internalSort();
473:                                    internal_multisearch();
474:
475:                                    fireTableDataChanged();
476:
477:                                    restoreTableSelections();
478:
479:                                    setHeaders();
480:                                    // strange... when not invoked, is sometimes not repainted
481:                                    if (tableReference != null)
482:                                        tableReference.getTableHeader()
483:                                                .repaint(); // we're in the EDT... ok
484:                                    if (tableRowHeadersReference != null)
485:                                        tableRowHeadersReference
486:                                                .getTableHeader().repaint(); // we're in the EDT... ok
487:                                    //tableHeader.invalidate();
488:                                }
489:                            }
490:                        });
491:            }
492:
493:            /** @return {0,1,3} for example if column 2 is not visible
494:             */
495:            public int[] getVisibleColumnsIndex() {
496:                synchronized (this ) {
497:                    int[] rep = new int[selectedColumns.size()];
498:                    Integer[] sc = selectedColumns
499:                            .toArray(new Integer[selectedColumns.size()]);
500:                    for (int i = 0; i < selectedColumns.size(); i++) {
501:                        rep[i] = sc[i].intValue();
502:                    }
503:                    return rep;
504:                }
505:            }
506:
507:            private int getModelIndexForClickedColumn(int col) {
508:                int[] visibleIndex = getVisibleColumnsIndex();
509:                return getVisibleColumnsIndex()[col];
510:            }
511:
512:            public void setVisibleColumns(int[] cols) {
513:                synchronized (this ) {
514:                    selectedColumns.clear();
515:                    for (int i = 0; i < cols.length; i++) {
516:                        if (cols[i] < this .basicTableModel.getColumnCount()) {
517:                            selectedColumns.add(new Integer(cols[i]));
518:                        }
519:                    }
520:                }
521:                storeTableSelection();
522:                fireTableStructureChanged(); // structure has changed, give a TableModelEvent with ROW_HEADERS row as argument
523:                restoreTableSelections();
524:                setHeaders();
525:
526:            }
527:
528:            public boolean isColumnVisible(int column) {
529:                return selectedColumns.contains(new Integer(column));
530:            }
531:
532:            /** @param column in the base model
533:             */
534:            public void setColumnVisible(int column, boolean visible) {
535:                if (visible) {
536:                    selectedColumns.add(column);
537:                } else {
538:                    // avoid zero columns !!!
539:                    if (selectedColumns.size() > 1) {
540:                        selectedColumns.remove(column);
541:                    }
542:                }
543:
544:                storeTableSelection();
545:                fireTableStructureChanged(); // structure has changed, give a TableModelEvent with ROW_HEADERS row as argument
546:                restoreTableSelections();
547:                setHeaders();
548:
549:                // [Feb2007]
550:                this .setPreferredColumnSizesFromModel();
551:            }
552:
553:            /** Must be called in the edt ! */
554:            public void setAllColumnsVisible() {
555:                for (int i = 0; i < this .getBasicTableModel().getColumnCount(); i++) {
556:                    selectedColumns.add(i);
557:                }
558:                storeTableSelection();
559:                fireTableStructureChanged(); // structure has changed, give a TableModelEvent with ROW_HEADERS row as argument
560:                restoreTableSelections();
561:                setHeaders();
562:            }
563:
564:            private void showColumnSelectionPopup(MouseEvent e) {
565:                JPopupMenu popup = new JPopupMenu("View Columns");
566:                popup.add(new JLabel("  View"));
567:                popup.addSeparator();
568:
569:                // numberOfColumnAsRowHeaders first col are always visible
570:                for (int i = numberOfColumnAsRowHeaders; i < this .basicTableModel
571:                        .getColumnCount(); i++) {
572:                    String name = basicTableModel.getColumnName(i);
573:                    final Integer index = i;
574:                    final JCheckBoxMenuItem cb = new JCheckBoxMenuItem(name,
575:                            selectedColumns.contains(index));
576:                    popup.add(cb);
577:                    cb.addActionListener(new ActionListener() {
578:                        public void actionPerformed(ActionEvent ae) {
579:                            setColumnVisible(index, cb.isSelected());
580:                        }
581:                    });
582:                }
583:
584:                popup.show(tableReference.getTableHeader(), e.getX(), e.getY());
585:            }
586:
587:            /** set the headers with sort icons.
588:              [Called from EDT]
589:             */
590:            protected void setHeaders() {
591:                if (tableReference == null)
592:                    return;
593:
594:                setHeadersForIndexTable();
595:
596:                //System.out.println("SC="+sortedColumn);
597:
598:                // for the index table
599:                if (tableRowHeadersReference != null) {
600:                    for (int i = 0; i < numberOfColumnAsRowHeaders; i++) {
601:                        int indexModel = i;
602:                        int indexView = tableRowHeadersReference
603:                                .convertColumnIndexToView(i);
604:                        //TableColumn column = tableRowHeadersReference.getColumnModel().getColumn(indexView);
605:                        DefaultTableCellRenderer headerRenderer = new DefaultTableCellRenderer();
606:                        headerRenderer.setBackground(UIManager
607:                                .getColor("TableHeader.background"));
608:                        if (indexModel == sortedColumnInBasicModel) {
609:                            if (ascending)
610:                                headerRenderer.setIcon(getAscIcon(indexModel));
611:                            else
612:                                headerRenderer.setIcon(getDescIcon(indexModel));
613:                        } else {
614:                            headerRenderer.setIcon(getNoSortIcon(indexModel));
615:                        }
616:
617:                        tableRowHeadersReference.getColumnModel().getColumn(
618:                                indexView).setHeaderRenderer(headerRenderer);
619:
620:                        // ??? needed, otherwise, does not correctly display.
621:                        tableRowHeadersReference.getTableHeader().repaint();
622:                    }
623:                }
624:
625:                // table
626:
627:                for (int i = 0; i < tableReference.getColumnCount(); i++) {
628:                    //int indexModel = i;
629:                    int indexView = tableReference.convertColumnIndexToView(i);
630:                    //TableColumn column = tableReference.getColumnModel().getColumn(indexView);
631:
632:                    DefaultTableCellRenderer headerRenderer = new DefaultTableCellRenderer();
633:                    headerRenderer.setBackground(UIManager
634:                            .getColor("TableHeader.background"));
635:
636:                    int sortedColViewIndex = getColumnForViewIndex(i);
637:
638:                    if (sortedColViewIndex + numberOfColumnAsRowHeaders == sortedColumnInBasicModel) {
639:                        if (ascending) {
640:                            headerRenderer
641:                                    .setIcon(getAscIcon(sortedColViewIndex));
642:                        } else {
643:                            headerRenderer
644:                                    .setIcon(getDescIcon(sortedColViewIndex));
645:                        }
646:                    } else {
647:                        headerRenderer
648:                                .setIcon(getNoSortIcon(sortedColViewIndex));
649:                    }
650:
651:                    tableReference.getColumnModel().getColumn(indexView)
652:                            .setHeaderRenderer(headerRenderer);
653:                    // ??? needed, otherwise, does not correctly display.
654:                    tableReference.getTableHeader().repaint();
655:                }
656:            }
657:
658:            private void setHeadersForIndexTable() {
659:                if (tableRowHeadersReference == null)
660:                    return;
661:
662:                //JTableHeader tableHeader = tableRowHeadersReference.getTableHeader();
663:                for (int i = 0; i < tableRowHeadersReference.getColumnCount(); i++) {
664:                    int indexModel = i;
665:                    int indexView = tableRowHeadersReference
666:                            .convertColumnIndexToView(i);
667:
668:                    //TableColumn column = tableRowHeadersReference.getColumnModel().getColumn(indexView);
669:                    DefaultTableCellRenderer headerRenderer = new DefaultTableCellRenderer();
670:                    headerRenderer.setBackground(UIManager
671:                            .getColor("TableHeader.background"));
672:
673:                    if (indexModel == sortedColumnInBasicModel) {
674:                        if (ascending) {
675:                            headerRenderer.setIcon(getAscIcon(indexModel));
676:                        } else {
677:                            headerRenderer.setIcon(getDescIcon(indexModel));
678:                        }
679:                    } else {
680:                        headerRenderer.setIcon(getNoSortIcon(indexModel));
681:                    }
682:
683:                    tableRowHeadersReference.getColumnModel().getColumn(
684:                            indexView).setHeaderRenderer(headerRenderer);
685:                    //tableReference.repaint();
686:                }
687:            }
688:
689:            // keep in mind what sorting is wanted, because each update must re-sort
690:            int sortedColumnInBasicModel = 0;
691:            boolean ascending = true;
692:
693:            public void sort(int column, boolean ascending) {
694:                synchronized (this ) {
695:                    this .sortedColumnInBasicModel = column;
696:                    this .ascending = ascending;
697:                    internalSort();
698:
699:                    // pass the event in same EDT for this listener
700:                    fireTableDataChanged();
701:                }
702:            }
703:
704:            /** @return true if the actual sorting order is ascending (default).
705:             */
706:            public boolean getSortOrderIsAscending() {
707:                return ascending;
708:            }
709:
710:            /** @return index in the basic tabel model.
711:             */
712:            public int getSortedColumn() {
713:                return sortedColumnInBasicModel;
714:            }
715:
716:            public void setSortedColumnAndOrder(int col, boolean ascending) {
717:                this .sortedColumnInBasicModel = col;
718:                this .ascending = ascending;
719:            }
720:
721:            private void internalSort() {
722:                Comparator<Integer> comp = new Comparator<Integer>() {
723:                    public int compare(Integer ind1, Integer ind2) {
724:                        //int ind1 = ((Integer) i1).intValue();
725:                        //int ind2 = ((Integer) i2).intValue();
726:
727:                        if (ascending) {
728:                            return basicTableModel.compareForColumnSort(ind1,
729:                                    ind2, sortedColumnInBasicModel);
730:                        } else {
731:                            return basicTableModel.compareForColumnSort(ind2,
732:                                    ind1, sortedColumnInBasicModel);
733:                        }
734:                    }
735:                };
736:                //System.out.println("Sort start");
737:                Collections.sort(sortedRowIndices, comp);
738:                //System.out.println("Sort end");
739:            }
740:
741:            //
742:            // TableModel
743:            //
744:
745:            /** @param pos id the index in this table,
746:                @return the position of the element in the unsorted model
747:             */
748:            private int getIndexInUnsortedModel(int pos) {
749:                if (pos == -1)
750:                    return -1;
751:                if (pos >= sortedRowIndices.size())
752:                    return -1;
753:
754:                return sortedRowIndices.get(pos);
755:            }
756:
757:            /** positions in unsorted
758:             */
759:            public int getIndexInUnsortedFromTablePos(int tablePos) {
760:                if (tablePos == -1)
761:                    return -1;
762:                if (tablePos >= foundBasicIndices.size()) {
763:                    //       System.out.println("tp="+tablePos+", fi="+foundBasicIndices.size());
764:                    return -1;
765:                }
766:
767:                return foundBasicIndices.get(tablePos);
768:            }
769:
770:            /** get the view index corresponding to the one in the basicIndex
771:             */
772:            public int getIndexInFoundFromBasicIndex(int basicIndex) {
773:                if (basicIndex == -1)
774:                    return -1;
775:                if (basicIndex >= 0
776:                        && basicIndex < basicTableModel.getRowCount()) {
777:                    int pos = foundBasicIndices.indexOf(Integer
778:                            .valueOf(basicIndex));
779:                    return pos;
780:                } else {
781:                    return -1;
782:                }
783:            }
784:
785:            @Override
786:            public Object getValueAt(int row, int col) {
787:                int pos = getIndexInUnsortedFromTablePos(row);
788:                return basicTableModel.getValueAt(pos,
789:                        getColumnForViewIndex(col));
790:            }
791:
792:            public int getRowCount() {
793:                //System.out.println("grc="+foundBasicIndices.size());
794:                return foundBasicIndices.size();
795:                //#  return unsortedTableModel.getRowCount();
796:            }
797:
798:            public int getColumnCount() {
799:                return selectedColumns.size();
800:                //[Old] return basicTableModel.getColumnCount();
801:            }
802:
803:            /** if visible columns are {0,1,3}, view=2, return 3
804:                BE CAREFUL: used in getColumName and getColumnClass !
805:             */
806:            public int getColumnForViewIndex(int viewCol) {
807:                synchronized (this ) {
808:                    int pos = -1;
809:                    // iterate over all visible columns
810:                    Iterator it = selectedColumns.iterator();
811:                    while (it.hasNext()) {
812:                        Integer ind = (Integer) it.next();
813:                        pos++;
814:                        if (pos == viewCol) {
815:                            return ind.intValue();
816:                        }
817:                    }
818:                    return -1;
819:                }
820:            }
821:
822:            @Override
823:            public boolean isCellEditable(int row, int col) {
824:                int pos = getIndexInUnsortedFromTablePos(row);
825:                return basicTableModel.isCellEditable(pos,
826:                        getColumnForViewIndex(col));
827:            }
828:
829:            @Override
830:            public void setValueAt(Object val, int row, int col) {
831:                int pos = getIndexInUnsortedFromTablePos(row);
832:                basicTableModel
833:                        .setValueAt(val, pos, getColumnForViewIndex(col));
834:            }
835:
836:            @Override
837:            public Class getColumnClass(int column) {
838:                return basicTableModel
839:                        .getColumnClass(getColumnForViewIndex(column));
840:            }
841:
842:            @Override
843:            public String getColumnName(int column) {
844:                return basicTableModel
845:                        .getColumnName(getColumnForViewIndex(column));
846:            }
847:
848:            /** can be used for completion...
849:             */
850:            public Set<String> getDifferentColumnValues(int col) {
851:                Set<String> set = new HashSet<String>();
852:                int colMod = this .getModelIndexForClickedColumn(col);
853:                for (int i = 0; i < this .getBasicTableModel().getRowCount(); i++) {
854:                    set.add(""
855:                            + this .getBasicTableModel().getValueAt(i, colMod));
856:                }
857:
858:                return set;
859:            }
860:
861:            /** {value, count}
862:             */
863:            public Map<String, Integer> getDifferentColumnValuesStat(int col) {
864:                Map<String, Integer> set = new HashMap<String, Integer>();
865:                int colMod = this .getModelIndexForClickedColumn(col);
866:                for (int i = 0; i < this .getBasicTableModel().getRowCount(); i++) {
867:                    String val = ""
868:                            + this .getBasicTableModel().getValueAt(i, colMod);
869:                    if (!set.containsKey(val)) {
870:                        set.put(val, 1);
871:                    } else {
872:                        set.put(val, set.get(val) + 1);
873:                    }
874:                }
875:                return set;
876:            }
877:
878:            public void multiSearch(final Query[] _queries) {
879:                multiSearch = true;
880:                queries = _queries;
881:                storeTableSelection();
882:
883:                internal_multisearch();
884:                fireTableDataChanged();
885:
886:                restoreTableSelections();
887:            }
888:
889:            private void internal_multisearch() {
890:                synchronized (this ) {
891:                    foundBasicIndices.clear();
892:                    for (int i = 0; i < basicTableModel.getRowCount(); i++) {
893:                        int basicIndex = getIndexInUnsortedModel(i);
894:
895:                        if (basicTableModel.hitForTextSearch(basicIndex,
896:                                queries)) {
897:                            foundBasicIndices.add(basicIndex);
898:                        }
899:                    }
900:                }
901:            }
902:
903:            /**
904:             * returns the ascending/descending sort icons.
905:             * this method may be overwritten by subclasses
906:             * in order to provide their own icons
907:             */
908:            protected Icon getAscIcon(final int column) {
909:                return (SORT_ASC);
910:            }
911:
912:            protected Icon getDescIcon(final int column) {
913:                return (SORT_DESC);
914:            }
915:
916:            protected Icon getNoSortIcon(final int column) {
917:                return (null);
918:            }
919:
920:            /** important: this returns a list of indices in the basic model in ascending order
921:             *   suitable for reverse iterating, for example when removing elements.
922:             *   silently ignore bad positions (-1).
923:             *   @param table uses the passed table to fetch the view selected rows.
924:             */
925:            public Vector<Integer> getSelectedRows_sortedBasicIndices(
926:                    JTable table) {
927:                int[] sel = table.getSelectedRows();
928:                Vector<Integer> ind = new Vector<Integer>();
929:                for (int i = 0; i < sel.length; i++) {
930:                    int pos = getIndexInUnsortedFromTablePos(sel[i]);
931:                    if (pos >= 0)
932:                        ind.add(pos);
933:                }
934:                Collections.sort(ind);
935:                return ind;
936:            }
937:
938:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.