/*
* Copyright 2009 Peter Karich, peat_hal ‘at’ users ‘dot’ sourceforge ‘dot’ net.
*
* 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.
* under the License.
*/
package de.timefinder.core.springrc;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.SortedList;
import ca.odell.glazedlists.matchers.Matcher;
import ca.odell.glazedlists.matchers.MatcherEditor;
import ca.odell.glazedlists.swing.TableComparatorChooser;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.TableModel;
import org.springframework.beans.support.PropertyComparator;
import org.springframework.binding.form.HierarchicalFormModel;
import org.springframework.richclient.form.AbstractMasterForm;
import org.springframework.richclient.form.builder.TableFormBuilder;
import org.springframework.richclient.table.support.GlazedTableModel;
import org.springframework.richclient.util.PopupMenuMouseListener;
/**
* Layout construction more generic, so that we can use BorderLayout instead
* JSplitPane. Made eventList protected so that we can add listeners etc
*
* @author Larry Streepy (and Peter Karich)
* @see org.springframework.richclient.form.AbstractTableMasterForm
* @see de.timefinder.core.ui.form.CollectionMasterDetailForm - at the moment
* the only subtype
*/
public abstract class MyAbstractTableMasterForm extends AbstractMasterForm {
/**
* Is this the sorted; filtered; but not observable rootEventList !?
* masterEventList is sorted; filtered and observable after installEventList
*
* WARNING: List<Event> is an eventList too but has nothing to do with
* glazedLists observable list which reacts on events of the EDT
*/
protected EventList eventList;
private JTable masterTable;
private Matcher matcher;
private MatcherEditor matcherEditor;
/**
* Construct a new AbstractTableMasterForm using the given parent form model and
* property path. The form model for this class will be constructed by getting the
* value model of the specified property from the parent form model and constructing a
* DeepCopyBufferedCollectionValueModel on top of it. Unless
* {@link AbstractMasterForm#getListListModel()} has been overriden, the table will
* contain all the elements in the domain object referenced by <code>property</code>.
*
* @param parentFormModel Parent form model to access for this form's data
* @param property Property containing this forms data (must be a collection or an
* array)
* @param formId Id of this form
* @param detailType Type of detail object managed by this master form
*/
public MyAbstractTableMasterForm(HierarchicalFormModel parentFormModel,
String property, String formId, Class detailType) {
super(parentFormModel, property, formId, detailType);
}
@SuppressWarnings("unchecked")
@Override
protected JComponent createFormControl() {
// Configure all our sub-components
configure();
eventList = getRootEventList();
// Install the matcher if configured (this will filter the list)
if (matcher != null)
eventList = new FilterList(eventList, matcher);
else if (matcherEditor != null)
eventList = new FilterList(eventList, matcherEditor);
String sortProperty = getColumnPropertyNames()[0];
SortedList sortedList = new SortedList(eventList,
new PropertyComparator(sortProperty, true, true));
eventList = sortedList;
// Install this new event list configuration (sorting and filtering)
installEventList(eventList);
masterTable = createTable(createTableModel());
// Finish the sorting installation
new TableComparatorChooser(masterTable, sortedList, true);
// If we have either a sort or a filter, we need a special selection model
// if (matcher != null) {
// EventSelectionModel selectionModel = new EventSelectionModel(eventList);
// masterTable.setSelectionModel(selectionModel);
// }
masterTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
// Setup our selection listener so that it controls the detail form
installSelectionHandler();
// Enable a popup menu
masterTable.addMouseListener(new PopupMenuMouseListener(getPopupMenu()));
// Avoid the default viewport size of 450,400
Dimension ps = masterTable.getPreferredSize();
masterTable.setPreferredScrollableViewportSize(ps);
TableFormBuilder formBuilder = new TableFormBuilder(getBindingFactory());
formBuilder.getLayoutBuilder().cell(createMainPanel(),
"align=default,default rowSpec=fill:default:g");
updateControlsForState();
return formBuilder.getForm();
}
public Matcher getMatcher() {
return matcher;
}
public void setMatcher(Matcher matcher) {
this.matcher = matcher;
}
public MatcherEditor getMatcherEditor() {
return matcherEditor;
}
public void setMatcherEditor(MatcherEditor matcherEditor) {
this.matcherEditor = matcherEditor;
}
protected JComponent createMainPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(createNorthPanel(), BorderLayout.NORTH);
panel.add(createMasterComponent(), BorderLayout.CENTER);
JSplitPane split = new JSplitPane();
split.setTopComponent(getDetailForm().getControl());
split.setBottomComponent(panel);
split.setOrientation(JSplitPane.VERTICAL_SPLIT);
split.setDividerSize(8);
split.setOneTouchExpandable(true);
split.setResizeWeight(.5d);
// split.setDividerLocation(0.3d);
return split;
}
protected JComponent createMainPanelNoneSplit() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(createNorthPanel(), BorderLayout.NORTH);
panel.add(createMasterComponent(), BorderLayout.CENTER);
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(getDetailForm().getControl(), BorderLayout.NORTH);
mainPanel.add(panel, BorderLayout.CENTER);
return mainPanel;
}
public JComponent createNorthPanel() {
return super.createButtonBar();
}
public JComponent createMasterComponent() {
return new JScrollPane(getMasterTable());
}
public JTable getMasterTable() {
return masterTable;
}
/**
* Create the master table.
* @param tableModel to use in the table
* @return table, default implementation uses the component factory to create the table
*/
protected JTable createTable(TableModel tableModel) {
return getComponentFactory().createTable(tableModel);
}
/**
* Create the table model for the master table.
* @return table model to install
*/
protected TableModel createTableModel() {
// Make this table model read-only
return new GlazedTableModel(eventList, getColumnPropertyNames(), getId()) {
@Override
protected boolean isEditable(Object row, int column) {
return false;
}
};
}
protected abstract String[] getColumnPropertyNames();
/**
* Get the selection model for the master list representation.
*
* @return selection model or null if master table has not been constructed yet
*/
@Override
protected ListSelectionModel getSelectionModel() {
return masterTable != null ? masterTable.getSelectionModel() : null;
}
}