/**
* Copyright (C) 2015 Valkyrie RCP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.valkyriercp.widget.table.glazedlists;
import ca.odell.glazedlists.*;
import ca.odell.glazedlists.event.ListEvent;
import ca.odell.glazedlists.event.ListEventListener;
import ca.odell.glazedlists.gui.TableFormat;
import ca.odell.glazedlists.gui.WritableTableFormat;
import ca.odell.glazedlists.swing.*;
import com.google.common.collect.Lists;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.Size;
import com.jgoodies.forms.layout.Sizes;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.decorator.*;
import org.jdesktop.swingx.table.TableColumnExt;
import org.valkyriercp.command.support.AbstractCommand;
import org.valkyriercp.command.support.ActionCommand;
import org.valkyriercp.command.support.CommandGroup;
import org.valkyriercp.util.ValueMonitor;
import org.valkyriercp.widget.AbstractWidget;
import org.valkyriercp.widget.table.TableCellRenderers;
import org.valkyriercp.widget.table.TableDescription;
import org.valkyriercp.widget.table.TableWidget;
import javax.annotation.PostConstruct;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.*;
import java.util.List;
public final class GlazedListTableWidget extends AbstractWidget implements
TableWidget {
private JXTable theTable = new JXTable();
private JScrollPane tableScroller;
private ValueMonitor selectionMonitor = new ValueMonitor();
private EventTableModel<Object> tableModel;
private EventSelectionModel<Object> selectionModel;
private EventList<Object> dataList;
private EventList<Object> shownList;
private SortedList<Object> sortedList;
private JTextField textFilterField;
private List<AbstractCommand> navigationCommands;
private CommandGroup navigationCommandGroup;
private CommandGroup selectColumnCommandGroup;
private JLabel countLabel;
// static
// {
// UIManager.put("JXTable.column.horizontalScroll",
// RcpSupport.getMessage("JXTable.horizontalScroll.label"));
// UIManager.put("JXTable.column.packAll",
// RcpSupport.getMessage("JXTable.packAll.label"));
// UIManager.put("JXTable.column.packSelected",
// RcpSupport.getMessage("JXTable.packSelected.label"));
// }
/**
* CellEditorListener op de selectiekolom om de selectieListeners gezamelijk
* te triggeren .
*/
private CellEditorListener userSelectionCellEditorListener = new CellEditorListener() {
public void editingStopped(ChangeEvent e) {
fireUserSelectionChangedEvent();
}
public void editingCanceled(ChangeEvent e) {
}
};
private Set dirtyRows = new HashSet();
private CellEditorListener dirtyRowCellEditorListener = new CellEditorListener() {
public void editingCanceled(ChangeEvent e) {
}
public void editingStopped(ChangeEvent e) {
dirtyRows.add(getSelectedRows()[0]);
}
};
/**
* De listeners geregistreerd op de selectiekolom, getriggerd door
* {@link #userSelectionCellEditorListener}.
*/
private List<PropertyChangeListener> userSelectionListeners;
private Class mDataType;
private List<? extends Object> mRows;
private TableFormat mFormat;
private String[] mFilterProperties;
private Comparator mComparator;
private boolean mAddHighlightSelectColumn;
private TableDescription mTableDesc;
public GlazedListTableWidget(List<? extends Object> rows,
TableDescription tableDesc) {
this(rows, tableDesc, tableDesc.getDefaultComparator());
}
public GlazedListTableWidget(List<? extends Object> rows,
TableDescription tableDesc, boolean enableFiltering) {
this(rows, tableDesc, tableDesc.getDefaultComparator(), enableFiltering);
}
public GlazedListTableWidget(List<? extends Object> rows,
TableDescription tableDesc, Comparator comparator) {
this(rows, tableDesc, comparator, true);
// Als de tablewidget met ons eigen TableDescription class is gemaakt
// kunnen we additionele dingen als width/resizable/renderer en editor
// zetten
// bedenking: zouden we tabledesc van een iterator voorzien om over de
// kolommen te lopen?
}
public GlazedListTableWidget(List<? extends Object> rows,
TableDescription tableDesc, Comparator comparator,
boolean enableFiltering) {
this(tableDesc.getDataType(), rows, GlazedListsSupport
.makeTableFormat(tableDesc),
enableFiltering ? GlazedListsSupport
.makeFilterProperties(tableDesc) : null, comparator,
tableDesc.hasSelectColumn());
mTableDesc = tableDesc;
// Als de tablewidget met ons eigen TableDescription class is gemaakt
// kunnen we additionele dingen als width/resizable/renderer en editor
// zetten
// bedenking: zouden we tabledesc van een iterator voorzien om over de
// kolommen te lopen?
}
private TableCellRenderer wrapInSortArrowHeaderRenderer(
TableCellRenderer renderer) {
if (tableComparatorChooser != null) {
return tableComparatorChooser
.createSortArrowHeaderRenderer(renderer);
} else {
return renderer;
}
}
protected GlazedListTableWidget(Class dataType,
List<? extends Object> rows, TableFormat format,
String[] filterProperties) {
this(dataType, rows, format, filterProperties, null, false);
}
protected GlazedListTableWidget(Class dataType,
List<? extends Object> rows, TableFormat format,
String[] filterProperties, Comparator comparator,
boolean addHighlightSelectColumn) {
mDataType = dataType;
mRows = rows;
mFormat = format;
mFilterProperties = filterProperties;
mComparator = comparator;
mAddHighlightSelectColumn = addHighlightSelectColumn;
postConstruct();
}
private void postConstruct() {
theTable.setColumnControlVisible(true);
dataList = mRows == null ? new BasicEventList<Object>() : GlazedLists
.eventList(mRows);
sortedList = new SortedList<Object>(dataList, mComparator);
this.shownList = sortedList;
if (mFilterProperties != null) {
textFilterField = new JTextField(getApplicationConfig()
.messageResolver().getMessage(
"glazedListTableWidget.textFilterField.prompt"));
textFilterField.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
textFilterField.selectAll();
}
});
shownList = new FilterList<Object>(shownList,
new TextComponentMatcherEditor(textFilterField,
GlazedLists.textFilterator(mDataType,
mFilterProperties)));
}
selectionModel = new EventSelectionModel<Object>(shownList);
selectionModel
.addListSelectionListener(new SelectionNavigationListener());
theTable.setSelectionModel(selectionModel);
tableModel = new EventJXTableModel<Object>(shownList, mFormat);
theTable.setModel(tableModel);
if (mAddHighlightSelectColumn) {
Highlighter selectHighlighter = new ColorHighlighter(
HIGHLIGHTSELECTCOLUMN, new Color(0xF0, 0xF0, 0xE0),
Color.BLACK);
setHighlighters(HighlighterFactory.createSimpleStriping(),
selectHighlighter);
initializeSelectColumnCommands();
} else {
setHighlighters(HighlighterFactory.createSimpleStriping());
}
if (sortedList != null) {
theTable.setSortable(false);
theTable.getTableHeader().setDefaultRenderer(
TableCellRenderers.LEFT_ALIGNED_HEADER_RENDERER);
tableComparatorChooser = TableComparatorChooser.install(theTable,
sortedList,
TableComparatorChooser.MULTIPLE_COLUMN_MOUSE_WITH_UNDO);
// the following is a fix for the selection sort and navigation
// problem
tableComparatorChooser.addSortActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
EventList<Object> selected = selectionModel.getSelected();
int[] indexes = new int[selected.size()];
int i = 0;
for (Object o : selected) {
indexes[i++] = shownList.indexOf(o);
}
selectionModel.clearSelection();
for (int index : indexes) {
selectionModel.addSelectionInterval(index, index);
}
}
});
}
theTable.setPreferredScrollableViewportSize(new Dimension(50, 50));
tableScroller = new JScrollPane(theTable);
theTable.setHorizontalScrollEnabled(true);
initializeNavigationCommands();
if (mTableDesc != null) {
TableCellEditor columnEditor = null;
for (int i = 0; i < mTableDesc.getColumnCount(); ++i) {
TableColumnExt column = (TableColumnExt) theTable.getColumns(
true).get(i);
int columnWidth = mTableDesc.getMaxColumnWidth(i);
if (columnWidth > 0) {
column.setMaxWidth(columnWidth);
}
columnWidth = mTableDesc.getMinColumnWidth(i);
if (columnWidth > 0) {
column.setMinWidth(columnWidth);
}
column.setResizable(mTableDesc.isResizable(i));
column.setVisible(mTableDesc.isVisible(i));
columnEditor = mTableDesc.getColumnEditor(i);
if (columnEditor != null) {
if (mTableDesc.isSelectColumn(i)) {
columnEditor
.addCellEditorListener(userSelectionCellEditorListener);
} else {
columnEditor
.addCellEditorListener(dirtyRowCellEditorListener);
}
column.setCellEditor(columnEditor);
}
if (mTableDesc.getColumnRenderer(i) != null) {
TableCellRenderer renderer = mTableDesc
.getColumnRenderer(i);
column.setCellRenderer(renderer);
if (renderer instanceof DefaultTableCellRenderer) {
int align = ((DefaultTableCellRenderer) renderer)
.getHorizontalAlignment();
switch (align) {
case SwingConstants.CENTER:
column.setHeaderRenderer(wrapInSortArrowHeaderRenderer(TableCellRenderers.CENTER_ALIGNED_HEADER_RENDERER));
break;
case SwingConstants.RIGHT:
column.setHeaderRenderer(wrapInSortArrowHeaderRenderer(TableCellRenderers.RIGHT_ALIGNED_HEADER_RENDERER));
break;
default:
break;
}
}
}
}
}
}
/**
* Enable the row height to diverge from the default height.
* <p/>
* NOTE: this is experimental as there is a problem with glazedlists and
* jxtable. (see note on ExtendedJXTable above)
*/
// public void setRowHeightEnabled(boolean rowHeightEnabled) {
// theTable.setRowHeightEnabled(true);
// }
private class SelectionNavigationListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent e) {
// enkel op einde van reeks selection veranderingen reageren.
if (!e.getValueIsAdjusting()) {
if (selectionModel.getSelected().size() == 1) {
selectionMonitor.setValue(selectionModel.getSelected().get(
0));
} else {
Object[] selectedRows = selectionModel.getSelected()
.toArray();
selectionMonitor
.setValue(selectedRows.length > 0 ? selectedRows
: null);
}
int selectedIndex = selectionModel.getAnchorSelectionIndex();
int lastIndex = shownList.size() - 1;
boolean emptyList = (lastIndex == -1);
boolean onFirst = (selectedIndex == 0);
boolean onLast = (selectedIndex == lastIndex);
navigationCommands.get(0).setEnabled(!emptyList && !onFirst);
navigationCommands.get(1).setEnabled(!emptyList && !onFirst);
navigationCommands.get(2).setEnabled(!emptyList && !onLast);
navigationCommands.get(3).setEnabled(!emptyList && !onLast);
}
}
}
public static final HighlightPredicate HIGHLIGHTSELECTCOLUMN = new HighlightSelectColumn();
private TableComparatorChooser tableComparatorChooser;
static class HighlightSelectColumn implements HighlightPredicate {
public boolean isHighlighted(Component renderer,
ComponentAdapter adapter) {
Object selectedValue = adapter.getValueAt(adapter.row, 0);
return Boolean.TRUE.equals(selectedValue);
}
}
public void setHighlighters(Highlighter... highlighters) {
this.theTable.setHighlighters(highlighters);
}
/**
* {@inheritDoc}
*/
public boolean isEmpty() {
return this.dataList.isEmpty();
}
/**
* {@inheritDoc}
*/
public int nrOfRows() {
return this.tableModel.getRowCount();
}
private void initializeNavigationCommands() {
this.navigationCommands = Lists.newArrayList();
navigationCommands.add(new ActionCommand(NAVIGATE_FIRSTROW_CMDID) {
@Override
protected void doExecuteCommand() {
selectionModel.setSelectionInterval(0, 0);
scrollToSelectedRow();
}
});
navigationCommands.add(new ActionCommand(NAVIGATE_PREVIOUSROW_CMDID) {
@Override
protected void doExecuteCommand() {
int newIndex = selectionModel.getAnchorSelectionIndex() - 1;
newIndex = (newIndex < 0) ? 0 : newIndex;
selectionModel.setSelectionInterval(newIndex, newIndex);
scrollToSelectedRow();
}
});
navigationCommands.add(new ActionCommand(NAVIGATE_NEXTROW_CMDID) {
@Override
protected void doExecuteCommand() {
int newIndex = selectionModel.getAnchorSelectionIndex() + 1;
int lastIndex = shownList.size() - 1;
newIndex = (newIndex > lastIndex) ? lastIndex : newIndex;
selectionModel.setSelectionInterval(newIndex, newIndex);
scrollToSelectedRow();
}
});
navigationCommands.add(new ActionCommand(NAVIGATE_LASTROW_CMDID) {
@Override
protected void doExecuteCommand() {
int lastIndex = shownList.size() - 1;
selectionModel.setSelectionInterval(lastIndex, lastIndex);
scrollToSelectedRow();
}
});
for (AbstractCommand navigationCommand : navigationCommands) {
this.getApplicationConfig().commandConfigurer().configure(
navigationCommand);
navigationCommand.setEnabled(false);
}
this.navigationCommandGroup = getApplicationConfig().commandManager()
.createCommandGroup(this.navigationCommands);
}
private void fireUserSelectionChangedEvent() {
if (userSelectionListeners != null) {
for (Iterator listeners = userSelectionListeners.iterator(); listeners
.hasNext();) {
PropertyChangeListener listener = (PropertyChangeListener) listeners
.next();
listener.propertyChange(new PropertyChangeEvent(this,
"selection", null, null));
}
}
}
public void addUserSelectionListener(PropertyChangeListener listener) {
if (userSelectionListeners == null) {
userSelectionListeners = new ArrayList<PropertyChangeListener>();
}
userSelectionListeners.add(listener);
}
private void initializeSelectColumnCommands() {
final WritableTableFormat writableTableFormat = (WritableTableFormat) this.tableModel
.getTableFormat();
AbstractCommand selectAll = new ActionCommand(SELECT_ALL_ID) {
@Override
protected void doExecuteCommand() {
shownList.getReadWriteLock().writeLock().lock();
Iterator i = shownList.iterator();
while (i.hasNext()) {
writableTableFormat.setColumnValue(i.next(), Boolean.TRUE,
0);
}
shownList.getReadWriteLock().writeLock().unlock();
theTable.repaint();
fireUserSelectionChangedEvent();
}
};
this.getApplicationConfig().commandConfigurer().configure(selectAll);
AbstractCommand selectNone = new ActionCommand(SELECT_NONE_ID) {
@Override
protected void doExecuteCommand() {
shownList.getReadWriteLock().writeLock().lock();
Iterator i = shownList.iterator();
while (i.hasNext()) {
writableTableFormat.setColumnValue(i.next(), Boolean.FALSE,
0);
}
shownList.getReadWriteLock().writeLock().unlock();
theTable.repaint();
fireUserSelectionChangedEvent();
}
};
this.getApplicationConfig().commandConfigurer().configure(selectNone);
AbstractCommand selectInverse = new ActionCommand(SELECT_INVERSE_ID) {
@Override
protected void doExecuteCommand() {
shownList.getReadWriteLock().writeLock().lock();
Iterator i = shownList.iterator();
while (i.hasNext()) {
Object rowObject = i.next();
Object columnValue = writableTableFormat.getColumnValue(
rowObject, 0);
writableTableFormat.setColumnValue(rowObject,
Boolean.TRUE.equals(columnValue) ? Boolean.FALSE
: Boolean.TRUE, 0);
}
shownList.getReadWriteLock().writeLock().unlock();
theTable.repaint();
fireUserSelectionChangedEvent();
}
};
this.getApplicationConfig().commandConfigurer().configure(selectInverse);
this.selectColumnCommandGroup = getApplicationConfig()
.commandManager()
.createCommandGroup(
Lists.newArrayList(selectAll, selectNone, selectInverse));
}
public final void setRows(Collection newRows) {
this.dataList.getReadWriteLock().writeLock().lock();
try {
this.dirtyRows.clear();
theTable.clearSelection();
this.dataList.clear();
this.dataList.addAll(newRows);
scrollToSelectedRow(); // new rows, scroll back to top
} finally {
this.dataList.getReadWriteLock().writeLock().unlock();
}
}
public final List getRows() {
return new ArrayList<Object>(this.dataList);
}
public final List getVisibleRows() {
return new ArrayList<Object>(this.shownList);
}
public void addRowObject(Object newObject) {
this.dataList.getReadWriteLock().writeLock().lock();
try {
this.dataList.add(newObject);
} finally {
this.dataList.getReadWriteLock().writeLock().unlock();
}
}
public void addRows(Collection rows) {
this.dataList.getReadWriteLock().writeLock().lock();
try {
this.dataList.addAll(rows);
} finally {
this.dataList.getReadWriteLock().writeLock().unlock();
}
}
public void removeRowObject(Object objectToRemove) {
this.dataList.getReadWriteLock().writeLock().lock();
try {
dirtyRows.remove(objectToRemove);
this.dataList.remove(objectToRemove);
} finally {
this.dataList.getReadWriteLock().writeLock().unlock();
}
}
public int selectRowObject(Object toPointTo, Observer originatingObserver) {
int index = this.shownList.indexOf(toPointTo);
selectRowObject(index, originatingObserver);
return index;
}
public void selectRowObject(final int index,
final Observer originatingObserver) {
Runnable doSelectRowObject = new Runnable() {
public void run() {
if (originatingObserver != null) {
selectionMonitor.deleteObserver(originatingObserver);
}
if ((index > -1) && (shownList.size() > index)) {
selectionModel.setSelectionInterval(index, index);
} else {
selectionModel.clearSelection();
}
scrollToSelectedRow();
if (originatingObserver != null) {
selectionMonitor.addObserver(originatingObserver);
}
}
};
if (SwingUtilities.isEventDispatchThread()) {
doSelectRowObject.run();
} else {
SwingUtilities.invokeLater(doSelectRowObject);
}
}
public void addSelection(final Object[] rows,
final Observer originatingObserver) {
Runnable doAddSelection = new Runnable() {
public void run() {
if (originatingObserver != null) {
selectionMonitor.deleteObserver(originatingObserver);
}
for (int i = 0; i < rows.length; i++) {
int index = shownList.indexOf(rows[i]);
selectionModel.addSelectionInterval(index, index);
}
if (originatingObserver != null) {
selectionMonitor.addObserver(originatingObserver);
}
}
};
if (SwingUtilities.isEventDispatchThread()) {
doAddSelection.run();
} else {
SwingUtilities.invokeLater(doAddSelection);
}
}
public boolean hasSelection() {
return !this.selectionModel.isSelectionEmpty();
}
public synchronized void scrollToSelectedRow() {
Runnable doScrollToSelectedRow = new Runnable() {
public void run() {
if (theTable.isVisible()) {
int selectedRow = theTable.getSelectedRow();
if (selectedRow != -1) {
Rectangle cellRect = theTable.getCellRect(selectedRow,
0, true);
Rectangle viewRect = tableScroller.getViewport()
.getViewRect();
if (!viewRect.contains(cellRect)) {
if (cellRect.y < viewRect.y) // cell is above view
// (or cut above)
{
tableScroller.getViewport().setViewPosition(
cellRect.getLocation());
} else // cell is below view (or cut below)
{
tableScroller.getViewport()
.scrollRectToVisible(cellRect);
}
}
} else {
tableScroller.getViewport().setViewPosition(
new Point(0, 0));
}
}
}
};
if (SwingUtilities.isEventDispatchThread()) {
doScrollToSelectedRow.run();
} else {
SwingUtilities.invokeLater(doScrollToSelectedRow);
}
}
public void replaceRowObject(Object oldObject, Object newObject,
Observer originatingObserver) {
this.dataList.getReadWriteLock().writeLock().lock();
try {
dirtyRows.remove(oldObject);
int index = this.dataList.indexOf(oldObject);
if (index != -1) {
boolean wasSelected = this.selectionModel
.isSelectedIndex(this.shownList.indexOf(oldObject));
if (wasSelected && (originatingObserver != null)) {
this.selectionMonitor.deleteObserver(originatingObserver);
}
this.dataList.set(index, newObject);
if (wasSelected) {
int indexToSelect = this.shownList.indexOf(newObject);
this.selectionModel.addSelectionInterval(indexToSelect,
indexToSelect);
if (originatingObserver != null) {
this.selectionMonitor.addObserver(originatingObserver);
}
}
}
} finally {
this.dataList.getReadWriteLock().writeLock().unlock();
}
}
public void replaceRows(final Collection oldObject,
final Collection newObject) {
Runnable doReplaceRows = new Runnable() {
public void run() {
dataList.getReadWriteLock().writeLock().lock();
try {
dirtyRows.clear();
dataList.removeAll(oldObject);
dataList.addAll(newObject);
} finally {
dataList.getReadWriteLock().writeLock().unlock();
}
}
};
if (SwingUtilities.isEventDispatchThread()) {
doReplaceRows.run();
} else {
SwingUtilities.invokeLater(doReplaceRows);
}
}
public void unSelectAll() {
Runnable doUnselectAll = new Runnable() {
public void run() {
selectionModel.clearSelection();
}
};
if (SwingUtilities.isEventDispatchThread()) {
doUnselectAll.run();
} else {
SwingUtilities.invokeLater(doUnselectAll);
}
}
public Object[] getSelectedRows() {
return this.selectionModel.getSelected().toArray();
}
public JComponent getComponent() {
return this.tableScroller;
}
public JTable getTable() {
return this.theTable;
}
public void addSelectionObserver(Observer observer) {
this.selectionMonitor.addObserver(observer);
}
public void removeSelectionObserver(Observer observer) {
this.selectionMonitor.deleteObserver(observer);
}
public void addTableModelListener(TableModelListener listener) {
this.tableModel.addTableModelListener(listener);
}
public void removeTableModelListener(TableModelListener listener) {
this.tableModel.removeTableModelListener(listener);
}
public void updateTable() {
this.tableModel.fireTableDataChanged();
}
public JTextField getTextFilterField() {
return textFilterField;
}
public List<AbstractCommand> getNavigationCommands() {
return navigationCommands;
}
public JComponent getNavigationButtonBar() {
return getNavigationButtonBar(Sizes.PREFERRED,
BorderFactory.createEmptyBorder());
}
public JComponent getNavigationButtonBar(Size size, Border border) {
return this.navigationCommandGroup.createButtonBar(size, border);
}
public CommandGroup getNavigationCommandGroup() {
return this.navigationCommandGroup;
}
public CommandGroup getSelectColumnCommandGroup() {
return this.selectColumnCommandGroup;
}
public JComponent getSelectButtonBar() {
return this.selectColumnCommandGroup.createButtonBar(Sizes.PREFERRED,
BorderFactory.createEmptyBorder());
}
public JComponent getButtonBar() {
if (this.selectColumnCommandGroup != null) {
JPanel buttons = new JPanel(new FormLayout(
"fill:pref, 3dlu, fill:pref, 3dlu, fill:pref",
"fill:pref:grow"));
CellConstraints cc = new CellConstraints();
buttons.add(getSelectButtonBar(), cc.xy(1, 1));
buttons.add(new JSeparator(SwingConstants.VERTICAL), cc.xy(3, 1));
buttons.add(getNavigationButtonBar(), cc.xy(5, 1));
return buttons;
}
return getNavigationButtonBar();
}
public JLabel getListSummaryLabel() {
if (countLabel == null) {
countLabel = createCountLabel();
}
return countLabel;
}
private JLabel createCountLabel() {
final JLabel label = new JLabel("");
setTextForListSummaryLabel(label);
shownList.addListEventListener(new ListEventListener<Object>() {
public void listChanged(ListEvent<Object> evt) {
if (!evt.isReordering()) {
setTextForListSummaryLabel(label);
}
}
});
theTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
setTextForListSummaryLabel(label);
}
}
});
return label;
}
private void setTextForListSummaryLabel(final JLabel label) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Integer index = 0;
Integer selectedCount = 0;
Integer totalCount = shownList.size();
if (getSelectedRows() != null && getSelectedRows().length > 0) {
index = shownList.indexOf(getSelectedRows()[0]);
index++;
selectedCount = getSelectedRows().length;
}
label.setText(getApplicationConfig().messageResolver().getMessage(
"glazedListTableWidget", "listSummary", "label",
new Object[] { index, selectedCount, totalCount }));
}
});
}
@Override
public void onAboutToShow() {
super.onAboutToShow();
this.theTable.requestFocusInWindow();
}
@Override
public String getId() {
return "glazedListTableWidget";
}
public Set getDirtyRows() {
return dirtyRows;
}
}