/** * 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; }
/** * 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; }