/** * Gets the current selection. * * <p>Ensures entities are returned in the same order as are viewed. * * @param <Q> the type of the rows. * @param table the table. * @param tableModel the table model. * @return the selected entities. * @see #getSelection(JTable, GlazedTableModel, List) */ public static <Q> List<Q> getSelection(JTable table, GlazedTableModel tableModel) { Assert.notNull(table, TableUtils.TABLE); Assert.notNull(tableModel, TableUtils.TABLE_MODEL); final List<Integer> modelIndexes = TableUtils.getSelectedModelIndexes(table); return TableUtils.getSelection(table, tableModel, modelIndexes); }
/** * Gets the selected rows model indexes. * * @param table the table. * @return the model indexes. */ public static List<Integer> getSelectedModelIndexes(JTable table) { Assert.notNull(table, TableUtils.TABLE); final List<Integer> viewIndexes = TableUtils.getSelectedViewIndexes(table); final List<Integer> modelIndexes = TableUtils.getModelIndexes(table, viewIndexes); return modelIndexes; }
/** * Refresh current selection. * * <p>This method ensures listeners are invoked just once. * * @param <Q> the type of the rows. * @param table the table. * @see #changeSelection(JTable, List, Boolean) */ public static <Q> void refreshSelection(final JTable table) { Assert.notNull(table, "table"); final List<Integer> selectedViewIndexes = TableUtils.getSelectedViewIndexes(table); // (JAF), 20110116, clear selection before turning on valueIsAdjusting, otherwise listeners may // not be notified table.clearSelection(); TableUtils.changeSelection(table, selectedViewIndexes, Boolean.TRUE); }
/** * Changes selection. * * <p>This method ensures listeners are invoked just once. * * @param <Q> the type of the rows. * @param table the table. * @param tableModel the table model. * @param newSelection the entities to be selected. If any entity does not belong to entities * currently being shown then it is ignored. * @see #changeSelection(JTable, List) */ public static <Q> void changeSelection( final JTable table, final GlazedTableModel tableModel, final List<Q> newSelection) { Assert.notNull(table, TableUtils.TABLE); Assert.notNull(tableModel, TableUtils.TABLE_MODEL); Assert.notNull(newSelection, "entities"); // Calculate view indexes and call overloaded method final List<Integer> modelIndexes = TableUtils.getModelIndexes(tableModel, newSelection); final List<Integer> viewIndexes = TableUtils.getViewIndexes(table, modelIndexes); TableUtils.changeSelection(table, viewIndexes); }
/** * Gets the model indexes for the given row indexes. * * @param table the table. * @param viewIndexes the view indexes. * @return the model indexes. * @see #getModelIndex(JTable, Integer) * @see #getViewIndexes(JTable, List) */ public static List<Integer> getModelIndexes(JTable table, List<Integer> viewIndexes) { Assert.notNull(table, TableUtils.TABLE); Assert.notNull(viewIndexes, "viewIndexes"); final List<Integer> modelIndexes = new ArrayList<Integer>(viewIndexes.size()); for (int i = 0; i < viewIndexes.size(); ++i) { modelIndexes.add(TableUtils.getModelIndex(table, viewIndexes.get(i))); } return modelIndexes; }
/** * Gets the model indexes for the given rows. * * @param <Q> the type of the rows. * @param tableModel the table model. * @param entities the entities to be queried. * @return the model indexes. */ public static <Q> List<Integer> getModelIndexes(GlazedTableModel tableModel, List<Q> entities) { Assert.notNull(tableModel, TableUtils.TABLE_MODEL); Assert.notNull(entities, "entities"); final EventList<Q> eventList = TableUtils.getSource(tableModel); final List<Integer> modelIndexes = new ArrayList<Integer>(entities.size()); for (int i = 0; i < entities.size(); ++i) { modelIndexes.add(eventList.indexOf(entities.get(i))); } return modelIndexes; }
/** * Gets the current selection. * * <p>Ensures entities are returned in the same order as <code>modelIndexes</code>. * * <p><em>This method exists for performance reasons when <code>modelIndexes</code> are already * known</em>. * * @param <Q> the type of the rows. * @param table the table. * @param tableModel the table model. * @param modelIndexes the model indexes. * @return the selected entities. */ public static <Q> List<Q> getSelection( JTable table, GlazedTableModel tableModel, List<Integer> modelIndexes) { Assert.notNull(table, TableUtils.TABLE); Assert.notNull(tableModel, TableUtils.TABLE_MODEL); final EventList<Q> eventList = TableUtils.getSource(tableModel); final List<Q> selectedEntities = new ArrayList<Q>(modelIndexes.size()); for (Integer modelIndex : modelIndexes) { selectedEntities.add(eventList.get(modelIndex)); } return selectedEntities; }
/** * Gets the entities currently being shown. * * @param <Q> the type of the rows. * @param table the table. * @return the visible entities. */ @SuppressWarnings("unchecked") public static <Q> List<Q> getVisibleEntities(JTable table) { Assert.notNull(table, TableUtils.TABLE); Assert.notNull(table.getModel(), "table.getModel()"); Assert.isTrue( table.getModel() instanceof GlazedTableModel, "table.getModel() instanceof GlazedTableModel"); final GlazedTableModel tableModel = (GlazedTableModel) table.getModel(); final List<Q> rows = new ArrayList<Q>(table.getRowCount()); for (int i = 0; i < table.getRowCount(); ++i) { // JAF, 20100411, fixed a BIG bug retrieving elements: rows.add((Q) // tableModel.getElementAt(i)); rows.add((Q) tableModel.getElementAt(TableUtils.getModelIndex(table, i))); } return rows; }
/** * Changes current selection if newer is different. * * <p>This method ensures listeners are invoked just once. * * @param <Q> the type of the rows. * @param table the table. * @param viewIndexes the indexes to select. <code>-1</code> indexes are ignored. * @see #changeSelection(JTable, List, Boolean) */ public static <Q> void changeSelection(final JTable table, final List<Integer> viewIndexes) { TableUtils.changeSelection(table, viewIndexes, Boolean.FALSE); }
/** * Show the given entities in a table. * * <p>When dealing with <code>EventList</code> performance is important. This method ensures table * model events are launched just once at the end. * * @param <Q> the type of the rows. * @param tableModel the table model. * @param entities the entities to be shown. * @param attach whether to attach new entities to currents. If <code>false</code> currents are * replaced. * @return <code>true</code> if success and <code>false</code> in other case (i.e.:user rejected * change). */ @SuppressWarnings("unchecked") public static <Q> Boolean showEntities( GlazedTableModel tableModel, final List<Q> entities, final Boolean attach) { Assert.notNull(tableModel, TableUtils.TABLE_MODEL); Assert.notNull(entities, "entities"); Assert.notNull(attach, "attach"); final EventList<Q> eventList = TableUtils.getSource(tableModel); // Proceed only if ... final Boolean proceed; if (attach) { // ... must attach and entities are not contained in eventList or... proceed = !CollectionUtils.isSubCollection(entities, eventList); } else { // ... must replace and entities are not equals to eventList proceed = !CollectionUtils.isEqualCollection(entities, eventList); } if (proceed) { if (TableUtils.LOGGER.isDebugEnabled()) { TableUtils.LOGGER.debug("About to show entities " + entities); } // Avoid notifying in every single change, instead do it at the end final TableModelListener[] listeners = tableModel.getTableModelListeners(); for (final TableModelListener listener : listeners) { tableModel.removeTableModelListener(listener); } SwingUtils.runInEventDispatcherThread( new Runnable() { @Override public void run() { // Update the contents of the event list eventList.getReadWriteLock().writeLock().lock(); try { if (!attach) { eventList.clear(); } eventList.addAll(eventList.size(), CollectionUtils.subtract(entities, eventList)); } finally { // Since Swing is multithread we need to lock before and unlock later // http://sites.google.com/site/glazedlists/documentation/faq eventList.getReadWriteLock().writeLock().unlock(); } } }); // Enable notifying: install listeners again for (final TableModelListener listener : listeners) { tableModel.addTableModelListener(listener); } // Since listeners were uninstalled notification should be explicit tableModel.fireTableDataChanged(); } return proceed; }