Removed depcrecated Bebop Table component

pull/28/head
Jens Pelzetter 2022-03-22 19:51:44 +01:00
parent 0e3ae4e99f
commit abe48a650d
17 changed files with 0 additions and 2939 deletions

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.bebop;
import com.arsdigita.globalization.GlobalizedMessage;
// Renders strings as labels
public class GlobalizedLabelCellRenderer extends StringLabelCellRenderer {
public GlobalizedLabelCellRenderer(final String weight) {
super(weight);
}
public GlobalizedLabelCellRenderer(final boolean outputEscape) {
super(outputEscape);
}
@Override
protected Label getLabel(final Object value) {
return new Label((GlobalizedMessage) value);
}
}

View File

@ -1,132 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop;
import com.arsdigita.bebop.list.ListModel;
import com.arsdigita.bebop.list.ListModelBuilder;
import com.arsdigita.bebop.table.DefaultTableCellRenderer;
import com.arsdigita.bebop.table.DefaultTableColumnModel;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableColumnModel;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.util.LockableImpl;
/**
* Displays a {@link ListModel} as a grid (that is, a {@link Table})
* of given width.
*
* @version $Id: Grid.java 287 2005-02-22 00:29:02Z sskracic $
*/
public class Grid extends Table {
private int m_cols;
/**
* Constructs a new <code>Grid</code>.
* <p>
*
* @param builder the {@link ListModelBuilder} that provides
* the grid with data
*
* @param numCols the number of columns in the grid
*/
public Grid(ListModelBuilder builder, int numCols) {
super(new GridModelBuilder(builder, numCols), new DefaultTableColumnModel());
m_cols = numCols;
setHeader(null);
TableColumnModel cols = getColumnModel();
for(int i=0; i<numCols; i++) {
cols.add(new TableColumn(i));
}
setClassAttr("grid");
setWidth("100%");
// Ignore null values
setDefaultCellRenderer(new DefaultTableCellRenderer(true) {
@Override
public Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key,
int row, int column) {
if(value == null)
return new Label("&nbsp;", false);
else
return super.getComponent(table, state, value, isSelected, key, row, column);
}
});
}
/**
* @param builder the {@link ListModelBuilder} that provides
* the grid with data
*/
public void setModelBuilder(ListModelBuilder builder) {
super.setModelBuilder(new GridModelBuilder(builder, getColumnCount()));
}
/**
* @return the number of columns in the grid.
*/
public int getColumnCount() {
return m_cols;
}
/**
* Converts a ListModel to a TableModel
*/
private static class GridModelBuilder extends LockableImpl
implements TableModelBuilder {
private ListModelBuilder m_builder;
private int m_cols;
public GridModelBuilder(ListModelBuilder builder, int cols) {
super();
m_builder = builder;
m_cols = cols;
}
public TableModel makeModel(Table t, PageState s) {
//XXX FIXME: The creation of a new List() below is a
//Hack to compile all...remove and fix.
//This is because makeModel requires a List arg.
//Should add a List setter function to Grid class, and
//initialize to null, then pass in null below if necessary...
//Christian: I will let your review team ponder this
//proposed change, and if approved, please assign the
//ticket to me! -jbp
List l = new List();
ListModel m = m_builder.makeModel(l,s);
return new GridTableModel(m, m_cols);
}
@Override
public void lock() {
m_builder.lock();
super.lock();
}
}
}

View File

@ -1,104 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.list.ListModel;
import java.util.ArrayList;
/**
* Converts a linear ListModel to a grid of items.
* For example, <code>A B C D E F G</code> becomes:
*
* <code><pre>
* A D G
* B E .
* C F .
* </pre></code>
*
* The extraneous cells in the table are filled
* with <code>GridTableModel.PLACEHOLDER</code>.
*
* @version $Id: GridTableModel.java 287 2005-02-22 00:29:02Z sskracic $
*/
public class GridTableModel implements TableModel {
private ListModel m_items;
private int m_colHeight, m_cols, m_size, m_index;
private Object[] m_elements;
private Object[] m_keys;
/**
* Constructs a new <code>GridTableModel</code>.
* @param items a {@link ListModel} that represents the
* items
* @param cols the number of columns in the grid
*/
public GridTableModel(ListModel items, int cols) {
m_items = items;
m_cols = cols;
// Load the items into memory
ArrayList elements = new ArrayList(), keys = new ArrayList();
for(m_size=0; m_items.next(); m_size++) {
elements.add(m_items.getElement());
keys.add(m_items.getKey());
}
m_elements = elements.toArray();
m_keys = keys.toArray();
// Round up
m_colHeight = m_size / m_cols;
if(m_colHeight * m_cols < m_size) ++m_colHeight;
m_index = -1;
}
public int getColumnCount() {
return m_cols;
}
public boolean nextRow() {
if(m_index >= m_colHeight - 1)
return false;
++m_index;
return true;
}
private Object safeGet(Object[] a, int columnIndex) {
int i = m_index + m_colHeight*columnIndex;
if(i >= a.length)
return null;
else
return a[i];
}
public Object getElementAt(int columnIndex) {
return safeGet(m_elements, columnIndex);
}
public Object getKeyAt(int columnIndex) {
return safeGet(m_keys, columnIndex);
}
}

View File

@ -1,151 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.bebop.util.GlobalizationUtil;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.LockableImpl;
/**
* Displays a list of label-value pairs that represent the properties of some
* object. For example, a typical <code>PropertySheet</code> may look like this:
* <p>
* <table cellpadding=4 cellspacing=0 border=0>
* <tr><th>First Name:</th><td>Stanislav</td></tr>
* <tr><th>Last Name:</th><td>Freidin</td></tr>
* <tr><th>Mission:</th><td>Sleep</td></tr>
* </table>
* <p>
* This class relies on the {@link PropertySheetModelBuilder} to supply it with
* the right {@link PropertySheetModel} during each request. It is up to the
* user to provide the right builder.
* <p>
*
* @author Stanislav Freidin
*
*/
public class PropertySheet extends Table {
/**
* Constructs a new <code>PropertySheet</code>.
*
* @param modelBuilder the property sheet model builder that is responsible
* for building the property sheet model
*
*/
public PropertySheet(final PropertySheetModelBuilder modelBuilder) {
this(modelBuilder, false);
}
/**
* Constructs a new <code>PropertySheet</code> and sets the output escape
* value.
*
* @param modelBuilder the property sheet model builder that is
* responsible for building the property sheet
* model
* @param valueOutputEscape the value of the label-value pair's
* output-escaping
*
*/
public PropertySheet(final PropertySheetModelBuilder modelBuilder,
final boolean valueOutputEscape) {
super(new PSTMBAdapter(modelBuilder), new Object[]{"Label", "Value"});
super.setHeader(null);
super
.getColumn(0)
.setCellRenderer(new GlobalizedLabelCellRenderer(Label.BOLD));
super.getColumn(1).setCellRenderer(new StringLabelCellRenderer(
valueOutputEscape));
}
// Convert a PropertySheetModelBuilder to a TableModelBuilder
private static class PSTMBAdapter
extends LockableImpl implements TableModelBuilder {
private PropertySheetModelBuilder modelBuilder;
public PSTMBAdapter(final PropertySheetModelBuilder modelBuilder) {
this.modelBuilder = modelBuilder;
}
@Override
public TableModel makeModel(final Table table, final PageState state) {
return new TableModelAdapter(
modelBuilder.makeModel((PropertySheet) table, state)
);
}
@Override
public void lock() {
modelBuilder.lock();
super.lock();
}
}
// Wraps a PropertySheetModel
private static class TableModelAdapter implements TableModel {
private final PropertySheetModel propertySheetModel;
private int currentRow;
public TableModelAdapter(final PropertySheetModel propertySheetModel) {
this.propertySheetModel = propertySheetModel;
currentRow = -1;
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public boolean nextRow() {
currentRow++;
return propertySheetModel.nextRow();
}
@Override
public Object getElementAt(final int columnIndex) {
if (columnIndex == 0) {
return propertySheetModel.getGlobalizedLabel();
} else {
return propertySheetModel.getValue();
}
}
@Override
public Object getKeyAt(final int columnIndex) {
return currentRow;
}
public PropertySheetModel getPSModel() {
return propertySheetModel;
}
};
}

View File

@ -1,45 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop;
import com.arsdigita.bebop.PageState;
import com.arsdigita.util.Lockable;
/**
* Constructs a new {@link PropertySheetModel} for the {@link PropertySheet}.
* The model will be used to get a list of properties at runtime.
*
* @author Stanislav Freidin
* @version $Id: PropertySheetModelBuilder.java 287 2005-02-22 00:29:02Z sskracic $
* @see PropertySheetModel
*/
public interface PropertySheetModelBuilder extends Lockable {
/**
* Constructs a new {@link PropertySheetModel}.
*
* @param sheet the {@link PropertySheet}
* @param state the page state
* @return a {@link PropertySheetModel}.
*/
PropertySheetModel makeModel(PropertySheet sheet, PageState state);
}

View File

@ -1,57 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.bebop;
import com.arsdigita.bebop.table.TableCellRenderer;
// Renders strings as labels
public class StringLabelCellRenderer implements TableCellRenderer {
private String weight;
private boolean outputEscape = false;
public StringLabelCellRenderer(final String weight) {
this.weight = weight;
}
public StringLabelCellRenderer(boolean outputEscape) {
this.outputEscape = outputEscape;
}
@Override
public Component getComponent(final Table table,
final PageState state, Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
final Label target = getLabel(value);
target.setOutputEscaping(outputEscape);
if (weight != null) {
target.setFontWeight(weight);
}
return target;
}
protected Label getLabel(Object value) {
return new Label((String) value);
}
}

View File

@ -1,896 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop;
import static com.arsdigita.bebop.Component.*;
import com.arsdigita.bebop.event.EventListenerList;
import com.arsdigita.bebop.event.TableActionAdapter;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.bebop.parameters.ParameterModel;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.bebop.table.AbstractTableModelBuilder;
import com.arsdigita.bebop.table.DefaultTableCellRenderer;
import com.arsdigita.bebop.table.DefaultTableColumnModel;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableColumnModel;
import com.arsdigita.bebop.table.TableHeader;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import static com.arsdigita.bebop.util.BebopConstants.*;
import com.arsdigita.util.Assert;
import com.arsdigita.xml.Element;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Iterator;
import javax.servlet.ServletException;
/**
* Displays statically or dynamically generated data in tabular form.
* The data is retrieved from a <code>TableModel</code>.
*
* <p>
* This class is similar to the {@link List} class, but it has two dimensions.
* The table consists of a {@link TableModelBuilder}, a {@link TableColumnModel},
* a {@link TableHeader} and a {@link TableCellRenderer} for each column.
* <p>
*
* A table that represents a static matrix can be created fairly quickly:
* <blockquote><pre><code> String[][] data = {
* {"Stas", "Freidin"},
* {"David", "Lutterkort"}
* };
*
* String[] headers = {"First Name", "Last Name"};
*
* Table myTable = new Table(data, headers);</code></pre></blockquote>
* <p>
*
* However, tables are most often used to represent database queries, not static
* data. For these tables, the {@link TableModelBuilder} class should be used
* to supply the <code>Table</code> class with data.
* The {@link TableModelBuilder} class will execute the database query and
* return a {@link TableModel}, which wraps the query.
* <p>
*
* The content in the cells is rendered by the {@link TableCellRenderer} that
* is set for the {@link TableColumn} to which the cell belongs.
*
* If the <code>TableCellRenderer</code> has not been set, the
* <code>TableCellRenderer</code> for the <code>Table</code> is used.
* By default, the <code>Table</code> class uses an inactive instance of the
* {@link DefaultTableCellRenderer} (cell content is displayed as {@link Label}s).
* However, if an active <code>DefaultTableCellRenderer</code> is used, the
* cells in the table appear as links. When the user clicks a link, the
* <code>Table</code>'s action listeners will be fired.
*
* <P>
* The currently selected cell is represented by two {@link SingleSelectionModel}s -
* one model for the row and one model for the column. Typically, the selected
* row is identified by a string key and the selected column is identified by
* an integer.
*
* @see TableModel
* @see TableColumnModel
*
* @author David Lutterkort
*/
public class Table extends SimpleComponent {
private static final Logger LOGGER = LogManager.getLogger(Table.class);
// Names for HTML Attributes
private static final String WIDTH = "width";
private static final String CELL_SPACING = "cellspacing";
private static final String CELL_PADDING = "cellpadding";
private static final String BORDER = "border";
private static final String SELECTED_ROW = "row";
/**
* The control event when the user selects one table cell.
* This control event will only be used when
*/
protected static final String CELL_EVENT = "cell";
protected static final char SEP = ' ';
private TableModelBuilder m_modelBuilder;
private TableColumnModel m_columnModel;
private TableHeader m_header;
private RequestLocal m_tableModel;
private SingleSelectionModel m_rowSelectionModel;
/**
* A listener to forward headSelected events originating from the
* TableHeader. This will be null until somebody actually registers a
* TableActionListener from the outside.
*/
private TableActionListener m_headerForward;
private EventListenerList m_listeners;
private TableCellRenderer m_defaultCellRenderer;
private Component m_emptyView;
private boolean m_striped = false;
/**
* Constructs a new, empty table.
*/
public Table() {
this(new Object[0][0], new Object[0]);
}
/**
* Constructs a static table with the specified column headers,
* and pre-fills it with data.
*
* @param data a matrix of objects that will serve as static data
* for the table cells
*
* @param headers an array of string labels for the table headers
*/
public Table(Object[][] data, Object[] headers) {
this(new MatrixTableModelBuilder(data), headers);
}
/**
* Constructs a table using a {@link TableModelBuilder}. The table
* data will be generated dynamically during each request.
*
* @param b the {@link TableModelBuilder} that is responsible for
* instantiating a {@link TableModel} during each request
*
* @param headers an array of string labels for the table headers
*/
public Table(TableModelBuilder b, Object[] headers) {
this(b, new DefaultTableColumnModel(headers));
}
/**
* Constructs a table using a {@link TableModelBuilder}. The table
* data will be generated dynamically during each request. The
* table's columns and headers will be provided by a
* {@link TableColumnModel}.
*
* @param b the {@link TableModelBuilder} that is responsible for
* instantiating a {@link TableModel} during each request
*
* @param c the {@link TableColumnModel} that will maintain the
* columns and headers for this table
*/
public Table(TableModelBuilder b, TableColumnModel c) {
super();
m_modelBuilder = b;
m_columnModel = c;
setHeader(new TableHeader(m_columnModel));
m_rowSelectionModel =
new ParameterSingleSelectionModel(new StringParameter(SELECTED_ROW));
m_listeners = new EventListenerList();
m_defaultCellRenderer = new DefaultTableCellRenderer();
initTableModel();
}
// Events and listeners
/**
* Adds a {@link TableActionListener} to the table. The listener is
* fired whenever a table cell is clicked.
*
* @param l the {@link TableActionListener} to be added
*/
public void addTableActionListener(TableActionListener l) {
Assert.isUnlocked(this);
if (m_headerForward == null) {
m_headerForward = createTableActionListener();
if (m_header != null) {
m_header.addTableActionListener(m_headerForward);
}
}
m_listeners.add(TableActionListener.class, l);
}
/**
* Removes a {@link TableActionListener} from the table.
*
* @param l the {@link TableActionListener} to be removed
*/
public void removeTableActionListener(TableActionListener l) {
Assert.isUnlocked(this);
m_listeners.remove(TableActionListener.class, l);
}
/**
* Fires event listeners to indicate that a new cell has been
* selected in the table.
*
* @param state the page state
* @param rowKey the key that identifies the selected row
* @param column the integer index of the selected column
*/
protected void fireCellSelected(PageState state,
Object rowKey, Integer column) throws FormProcessException {
Iterator i = m_listeners.getListenerIterator(TableActionListener.class);
TableActionEvent e = null;
while (i.hasNext()) {
if (e == null) {
e = new TableActionEvent(this, state, rowKey, column);
}
((TableActionListener) i.next()).cellSelected(e);
}
}
/**
* Fires event listeners to indicate that a new header cell has been
* selected in the table.
*
* @param state the page state
* @param rowKey the key that identifies the selected row
* @param column the integer index of the selected column
*/
protected void fireHeadSelected(PageState state,
Object rowKey, Integer column) {
Iterator i = m_listeners.getListenerIterator(TableActionListener.class);
TableActionEvent e = null;
while (i.hasNext()) {
if (e == null) {
e = new TableActionEvent(this, state, rowKey, column);
}
((TableActionListener) i.next()).headSelected(e);
}
}
/**
* Instantiates a new {@link TableActionListener} for this table.
*
* @return a new {@link TableActionListener} that should be used
* only for this table.
*
*/
protected TableActionListener createTableActionListener() {
return new TableActionAdapter() {
@Override
public void headSelected(TableActionEvent e) {
fireHeadSelected(e.getPageState(), e.getRowKey(), e.getColumn());
}
};
}
/**
* @return the {@link TableColumnModel} for this table.
*/
public final TableColumnModel getColumnModel() {
return m_columnModel;
}
/**
* Sets a new {@link TableColumnModel} for the table.
*
* @param v the new {@link TableColumnModel}
*/
public void setColumnModel(TableColumnModel v) {
Assert.isUnlocked(this);
m_columnModel = v;
}
/**
* @return the {@link TableModelBuilder} for this table.
*/
public final TableModelBuilder getModelBuilder() {
return m_modelBuilder;
}
/**
* Sets a new {@link TableModelBuilder} for the table.
*
* @param v the new {@link TableModelBuilder}
*/
public void setModelBuilder(TableModelBuilder v) {
Assert.isUnlocked(this);
m_modelBuilder = v;
}
/**
* @return the {@link TableHeader} for this table. Could return null
* if the header is hidden.
*/
public final TableHeader getHeader() {
return m_header;
}
/**
* Sets a new header for this table.
*
* @param v the new header for this table. If null, the header will be
* hidden.
*/
public void setHeader(TableHeader v) {
Assert.isUnlocked(this);
if (m_headerForward != null) {
if (m_header != null) {
m_header.removeTableActionListener(m_headerForward);
}
if (v != null) {
v.addTableActionListener(m_headerForward);
}
}
m_header = v;
if (m_header != null) {
m_header.setTable(this);
}
}
/**
* @param i the numerical index of the column
* @return the {@link TableColumn} whose index is i.
*/
public TableColumn getColumn(int i) {
return getColumnModel().get(i);
}
/**
* Maps the colulumn at a new numerical index. This method
* is normally used to rearrange the order of the columns in the
* table.
*
* @param i the numerical index of the column
* @param v the column that is to be mapped at i
*/
public void setColumn(int i, TableColumn v) {
getColumnModel().set(i, v);
}
/**
* @return the {@link SingleSelectionModel} that is responsible
* for selecting the current row.
*/
public final SingleSelectionModel getRowSelectionModel() {
return m_rowSelectionModel;
}
/**
* Specifies the {@link SingleSelectionModel} that will be responsible
* for selecting the current row.
*
* @param v a {@link SingleSelectionModel}
*/
public void setRowSelectionModel(SingleSelectionModel v) {
Assert.isUnlocked(this);
m_rowSelectionModel = v;
}
/**
* @return the {@link SingleSelectionModel} that is responsible
* for selecting the current column.
*/
public SingleSelectionModel getColumnSelectionModel() {
return (getColumnModel() == null) ? null : getColumnModel().
getSelectionModel();
}
/**
* Specifies the {@link SingleSelectionModel} that will be responsible
* for selecting the current column.
*
* @param v a {@link SingleSelectionModel}
*/
public void setColumnSelectionModel(SingleSelectionModel v) {
Assert.isUnlocked(this);
// TODO: make sure table gets notified of changes
getColumnModel().setSelectionModel(v);
}
/**
* Clears the row and column selection models that the table holds.
*
* @param s represents the state of the current request
* @post ! getRowSelectionModel().isSelected(s)
* @post ! getColumnSelectionModel().isSelected(s)
*/
public void clearSelection(PageState s) {
getRowSelectionModel().clearSelection(s);
getColumnSelectionModel().clearSelection(s);
}
/**
* @return the default {@link TableCellRenderer}.
*/
public final TableCellRenderer getDefaultCellRenderer() {
return m_defaultCellRenderer;
}
/**
* Specifies the default cell renderer. This renderer will
* be used to render columns that do not specify their own
* {@link TableCellRenderer}.
*
* @param v the default {@link TableCellRenderer}
*/
public final void setDefaultCellRenderer(TableCellRenderer v) {
m_defaultCellRenderer = v;
}
/**
* @return the component that will be shown if the table is
* empty.
*/
public final Component getEmptyView() {
return m_emptyView;
}
/**
* Sets the empty view. The empty view is the component that
* is shown if the table is empty. Usually, the component
* will be a simple label, such as <code>new Label("The table is empty")</code>.
*
* @param v a Bebop component
*/
public final void setEmptyView(Component v) {
m_emptyView = v;
}
// Set HTML table attributes
/**
*
* @return the HTML width of the table.
*/
public String getWidth() {
return getAttribute(WIDTH);
}
/**
*
* @param v the HTML width of the table
*/
public void setWidth(String v) {
setAttribute(WIDTH, v);
}
/**
*
* @return the HTML border of the table.
*/
public String getBorder() {
return getAttribute(BORDER);
}
/**
*
* @param v the HTML border of the table
*/
public void setBorder(String v) {
setAttribute(BORDER, v);
}
public String getCellSpacing() {
return getAttribute(CELL_SPACING);
}
/**
*
* @param v the HTML width of the table
*/
public void setCellSpacing(String v) {
setAttribute(CELL_SPACING, v);
}
/**
*
* @return the HTML cell spacing of the table.
*/
public String getCellPadding() {
return getAttribute(CELL_PADDING);
}
/**
*
* @param v the HTML cell padding of the table
*/
public void setCellPadding(String v) {
setAttribute(CELL_PADDING, v);
}
/**
* Processes the events for this table. This method will automatically
* handle all user input to the table.
*
* @param s the page state
* @throws javax.servlet.ServletException
*/
@Override
public void respond(PageState s) throws ServletException {
String event = s.getControlEventName();
String rowKey = null;
Integer column = null;
if (CELL_EVENT.equals(event)) {
String value = s.getControlEventValue();
SingleSelectionModel rowSel = getRowSelectionModel();
SingleSelectionModel colSel = getColumnSelectionModel();
int split = value.indexOf(SEP);
rowKey = value.substring(0, split);
column = new Integer(value.substring(split + 1));
colSel.setSelectedKey(s, column);
rowSel.setSelectedKey(s, rowKey);
fireCellSelected(s, rowKey, column);
} else {
throw new ServletException("Unknown event '" + event + "'");
}
}
/**
* Registers the table with the containing page. The table will add the
* state parameters of the row and column selection models, if they use
* them, thus making the selection persist between requests.
*
* @param p the page that contains this table
*/
@Override
public void register(Page p) {
ParameterModel m = getRowSelectionModel() == null ? null
: getRowSelectionModel().getStateParameter();
if (m != null) {
p.addComponentStateParam(this, m);
}
m = getColumnSelectionModel() == null ? null : getColumnSelectionModel().
getStateParameter();
if (m != null) {
p.addComponentStateParam(this, m);
}
}
/**
* Returns an iterator over the header and all the columns. If the table
* has no header, the iterator lists only the columns.
*
* @return an iterator over Bebop components.
*/
@Override
public Iterator children() {
return new Iterator() {
int pos = (getHeader() == null) ? -1 : -2;
@Override
public boolean hasNext() {
return pos < getColumnModel().size() - 1;
}
@Override
public Object next() {
pos += 1;
if (pos == -1) {
return getHeader();
} else {
return getColumn(pos);
}
}
@Override
public void remove() {
throw new UnsupportedOperationException("Read-only iterator.");
}
};
}
/**
* Determines whether a row is seleted.
*
* @param s the page state
* @param rowKey the key that identifies the row
* @return <code>true</code> if the row is currently selected;
* <code>false</code> otherwise.
*/
public boolean isSelectedRow(PageState s, Object rowKey) {
if (rowKey == null || getRowSelectionModel() == null) {
return false;
}
return getRowSelectionModel().isSelected(s)
&& rowKey.toString().equals(
getRowSelectionModel().getSelectedKey(s).toString());
}
/**
* Determines whether a column is selected.
*
* @param s the page state
* @param column a key that identifes the column. Should be consistent
* with the type used by the column selection model.
* @return <code>true</code> if the column is selected;
* <code>false</code> otherwise.
*/
public boolean isSelectedColumn(PageState s, Object column) {
if (column == null || getColumnSelectionModel() == null) {
return false;
}
return getColumnSelectionModel().isSelected(s)
&& column.toString().equals(
getColumnSelectionModel().getSelectedKey(s).toString());
}
/**
* Determines whether the cell addressed by the specified row key and
* column number is selected in the request represented by the page
* state.
*
* @param s represents the state of the page in the current request
* @param rowKey the row key of the cell. The concrete type should agree
* with the type used by the row selection model.
* @param column the column of the cell. The concrete type should agree
* with the type used by the column selection model.
* @return <code>true</code> if the cell is selected;
* <code>false</code> otherwise.
*/
public boolean isSelectedCell(PageState s, Object rowKey, Object column) {
return isSelectedRow(s, rowKey) && isSelectedColumn(s, column);
}
public void setStriped(boolean striped) {
m_striped = striped;
}
public boolean getStriped() {
return m_striped;
}
/**
* Adds type-specific XML attributes to the XML element representing
* this link. Subclasses should override this method if they introduce
* more attributes than the ones {@link #generateXML generateXML}
* produces by default.
*
* @param state represents the current request
* @param element the XML element representing this table
*/
protected void generateExtraXMLAttributes(PageState state,
Element element) {
}
/**
* Generates the XML representing the table. Gets a new {@link TableModel}
* from the {@link TableModelBuilder} and iterates over the model's
* rows. The value in each table cell is rendered with the help of the
* column's table cell renderer.
*
* <p> Generates an XML fragment:
* <pre>
* &lt;bebop:table&gt;
* &lt;bebop:thead&gt;
* &lt;bebpp:cell&gt;...&lt;/cell&gt; ...
* &lt;/bebop:thead&gt;
* &lt;bebop:tbody&gt;
* &lt;bebop:trow&gt;
* &lt;bebpp:cell&gt;...&lt;/cell&gt; ...
* &lt;/bebop:trow&gt;
* ...
* &lt;/bebop:tbody&gt;
* &lt;/bebop:table&gt;
*
* @param s the page state
* @param p the parent {@link Element}
*/
@Override
public void generateXML(PageState s, Element p) {
TableModel model = getTableModel(s);
final boolean tableIsRegisteredWithPage =
s.getPage().stateContains(getControler());
if (model.nextRow()) {
Element table = p.newChildElement(BEBOP_TABLE, BEBOP_XML_NS);
exportAttributes(table);
generateExtraXMLAttributes(s, table);
if (getHeader() != null) {
getHeader().generateXML(s, table);
}
Element tbody = table.newChildElement(BEBOP_TABLEBODY, BEBOP_XML_NS);
if (m_striped) {
tbody.addAttribute("striped", "true");
}
final int modelSize = getColumnModel().size();
int row = 0;
LOGGER.debug("Creating table rows...");
long start = System.currentTimeMillis();
do {
long rowStart = System.currentTimeMillis();
Element trow = tbody.newChildElement(BEBOP_TABLEROW,
BEBOP_XML_NS);
for (int i = 0; i < modelSize; i++) {
TableColumn tc = getColumn(i);
if (tc.isVisible(s)) {
TableCellRenderer r = tc.getCellRenderer();
if (r == null) {
r = m_defaultCellRenderer;
}
final int modelIndex = tc.getModelIndex();
Object key = model.getKeyAt(modelIndex);
Object value = model.getElementAt(modelIndex);
boolean selected =
isSelectedCell(s, key, new Integer(i));
if (tableIsRegisteredWithPage) {
/*StringBuffer coords = new StringBuffer(40);
coords.append(model.getKeyAt(modelIndex)).append(SEP).
append(i);
s.setControlEvent(getControler(), CELL_EVENT,
coords.toString());*/
s.setControlEvent(getControler(),
CELL_EVENT,
String.format("%s%s%d",
model.getKeyAt(
modelIndex),
SEP,
i));
}
Element cell = trow.newChildElement(BEBOP_CELL,
BEBOP_XML_NS);
tc.exportCellAttributes(cell);
long begin = System.currentTimeMillis();
r.getComponent(this, s, value, selected, key, row, i).
generateXML(s, cell);
LOGGER.debug(String.format("until here i needed %d ms",
System.currentTimeMillis()
- begin));
}
}
row += 1;
LOGGER.debug(
String.format("Created row in %d ms",
System.currentTimeMillis() - rowStart));
} while (model.nextRow());
LOGGER.debug(String.format("Build table rows in %d ms",
System.currentTimeMillis() - start));
} else if (m_emptyView != null) {
m_emptyView.generateXML(s, p);
}
if (tableIsRegisteredWithPage) {
s.clearControlEvent();
}
}
protected Component getControler() {
return this;
}
/**
* Returns the table model in effect for the request represented by the
* page state.
*
* @param s represents the state of the page in the current request
* @return the table model used for outputting the table.
*/
public TableModel getTableModel(PageState s) {
return (TableModel) m_tableModel.get(s);
}
/**
* Initialize the request local <code>m_tableModel</code> field so that
* it is initialized with whatever model the table model builder returns
* for the request.
*/
private void initTableModel() {
m_tableModel = new RequestLocal() {
@Override
protected Object initialValue(PageState s) {
return m_modelBuilder.makeModel(Table.this, s);
}
};
}
/**
* Locks the table against further modifications. This also locks all
* the associated objects: the model builder, the column model, and the
* header components.
* @see com.arsdigita.util.Lockable#lock
*/
@Override
public void lock() {
getModelBuilder().lock();
getColumnModel().lock();
if (getHeader() != null) {
getHeader().lock();
}
super.lock();
}
/**
* An internal class that creates a table model around a set of data given
* as a <code>Object[][]</code>. The table models produced by this builder
* use row numbers, converted to strings, as the key for each column of a
* row.
*/
public static class MatrixTableModelBuilder
extends AbstractTableModelBuilder {
private final Object[][] m_data;
/**
* Constructor.
*
* @param data
*/
public MatrixTableModelBuilder(Object[][] data) {
m_data = data;
}
@Override
public TableModel makeModel(Table t, PageState s) {
return new TableModel() {
private int row = -1;
@Override
public int getColumnCount() {
return m_data[0].length;
}
@Override
public boolean nextRow() {
return (++row < m_data.length);
}
@Override
public Object getElementAt(int j) {
return m_data[row][j];
}
@Override
public Object getKeyAt(int j) {
return String.valueOf(row);
}
};
}
}
/**
* A {@link TableModel} that has no rows.
*/
public static final TableModel EMPTY_MODEL = new TableModel() {
@Override
public int getColumnCount() {
return 0;
}
@Override
public boolean nextRow() {
return false;
}
@Override
public Object getKeyAt(int column) {
throw new IllegalStateException("TableModel is empty");
}
@Override
public Object getElementAt(int column) {
throw new IllegalStateException("TableModel is empty");
}
};
}

View File

@ -1,53 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop.table;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Table;
import com.arsdigita.util.LockableImpl;
/**
* A convenience for implementing <code>TableModelBuilder</code>s. This
* class provides a default implementation of the methods demanded by
* <code>Lockable</code>, so that implementors of
* <code>TableModelBuilder</code> only need to override the
* <code>makeModel</code> method.
*
* @author David Lutterkort
* @see TableModelBuilder
* @see com.arsdigita.util.Lockable
*
* @version $Id$
*/
public abstract class AbstractTableModelBuilder extends LockableImpl
implements TableModelBuilder {
/**
* Return a table model for the request represented by
* <code>s</code>. The table model contains all the data that is to be
* displayed in a table. The returned table model is used only during
* the duration of that request.
*
* @param t the table which will use this table model
* @param s represents the current request
* @return the data to be displayed in the table
*/
public abstract TableModel makeModel(Table t, PageState s);
}

View File

@ -1,159 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop.table;
import com.arsdigita.bebop.util.GlobalizationUtil ;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ControlLink;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Table;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.Assert;
import com.arsdigita.util.LockableImpl;
/**
* The default renderer for table cells. This renderer is used by the
* {@link com.arsdigita.bebop.Table} component for rendering the table
* headers and cells if no other renderer is specified.
*
* <p> This renderer can operate in two different modes: <em>active</em>
* and <em>inactive</em> mode. In inactive mode, all objects are rendered
* by converting them to a string and enclosing that string in a {@link
* com.arsdigita.bebop.Label}. If the renderer is in active mode, this
* label is further enclosed in a control link. When the user clicks on
* this link, the table will fire an <code>TableActionEvent</code> whose
* <code>getKey()</code> and <code>getColumn()</code> method return the
* values of the <code>key</code> and <code>column</code> parameters that
* were passed into {@link #getComponent getComponent}.
*
* <p> In a nutshell, an active renderer will let the user click a link
* that causes a <code>TableActionEvent</code> for the corresponding cell,
* while an inactive renderer will display the values just as strings, thus
* making it impossible for the user to cause such an event.
*
* @author David Lutterkort
* @see com.arsdigita.bebop.Table
* @see com.arsdigita.bebop.event.TableActionEvent
*
* @version $Id$ */
public class DefaultTableCellRenderer extends LockableImpl
implements TableCellRenderer {
private boolean m_active;
private ThreadLocal m_label;
private ThreadLocal m_controlLink;
/**
* Creates a new table cell renderer. The table cell renderer is in
* inactive mode.
*/
public DefaultTableCellRenderer() {
this(false);
}
/**
* Creates a new table cell renderer. The <code>active</code> argument
* specifies whether the renderer should be active or not.
*
* @param active <code>true</code> if the renderer should generate links
* instead of just static labels.
*/
public DefaultTableCellRenderer(boolean active) {
m_active = active;
m_label = new ThreadLocal() {
protected Object initialValue() {
return new Label("");
}
};
m_controlLink = new ThreadLocal() {
protected Object initialValue() {
return new ControlLink((Label) m_label.get());
}
};
}
/**
* Return <code>true</code> if the renderer is in active mode. A
* rendererin active mode will enclose the objects it renders in links
* that, when clicked, will cause the containing table to fire a
* <code>TableActionEvent</code>.
*
* @return <code>true</code> if the renderer is in active mode.
*/
public final boolean isActive() {
return m_active;
}
/**
* Set the renderer to active or inactive mode.
*
* @param v <code>true</code> if the renderer should operate in active
* mode.
* @pre ! isLocked()
*/
public void setActive(boolean v) {
Assert.isUnlocked(this);
m_active = v;
}
/**
* Return the component that should be used to render the given
* <code>value</code>. Returns a {@link com.arsdigita.bebop.Label} if the
* renderer is active, and a {@link com.arsdigita.bebop.ControlLink} if
* the renderer is inactive.
*
* @pre table == null || table != null
*/
public Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key,
int row, int column)
{
if ( ! isLocked() && table != null && table.isLocked() ) {
lock();
}
Label l;
if ( value instanceof com.arsdigita.bebop.Component ) {
return (com.arsdigita.bebop.Component) value;
} else if(value instanceof GlobalizedMessage) {
l = (Label) m_label.get();
l.setLabel((GlobalizedMessage) value);
} else {
l = (Label) m_label.get();
if ( value == null ) {
l.setLabel( (String) GlobalizationUtil.globalize("bebop.table.").localize());
l.setOutputEscaping(false);
} else {
l.setLabel(value.toString());
l.setOutputEscaping(true);
}
}
l.setFontWeight( (isSelected && m_active) ? Label.BOLD : null );
if (m_active && ! isSelected) {
return (ControlLink) m_controlLink.get();
} else {
return l;
}
}
}

View File

@ -1,127 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop.table;
import java.util.ArrayList;
import java.util.Iterator;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.parameters.IntegerParameter;
import com.arsdigita.util.Assert;
/**
* Describe interface <code>TableColumnModel</code> here.
*
* @author David Lutterkort
* @version $Id$
*/
public class DefaultTableColumnModel implements TableColumnModel {
private static final String SELECTED_COLUMN="col";
private boolean m_locked;
private ArrayList m_columns;
private SingleSelectionModel m_selection;
public DefaultTableColumnModel() {
this(new Object[0]);
}
public DefaultTableColumnModel(SingleSelectionModel sel) {
this(new Object[0], sel);
}
public DefaultTableColumnModel(Object[] headers) {
this(headers,
new ParameterSingleSelectionModel(new IntegerParameter(SELECTED_COLUMN)) );
}
public DefaultTableColumnModel(Object[] headers, SingleSelectionModel sel) {
m_columns = new ArrayList();
m_selection = sel;
for (int i=0; i < headers.length; i++) {
add(new TableColumn(i, headers[i], new Integer(i)));
}
}
public void add(TableColumn column) {
Assert.isUnlocked(this);
m_columns.add(column);
}
public void add(int columnIndex, TableColumn column) {
Assert.isUnlocked(this);
m_columns.add(columnIndex, column);
}
public TableColumn get(int columnIndex) {
return (TableColumn) m_columns.get(columnIndex);
}
public void set(int columnIndex, TableColumn v) {
m_columns.set(columnIndex, v);
}
public int size() {
return m_columns.size();
}
public int getIndex(Object key) {
if ( key == null ) {
return -1;
}
for (int i=0; i<size(); i++) {
TableColumn t = get(i);
if ( key.equals(t.getHeaderKey()) ) {
return i;
}
}
return -1;
}
public Iterator columns() {
return m_columns.iterator();
}
public void remove(TableColumn column) {
Assert.isUnlocked(this);
m_columns.remove(column);
}
public final SingleSelectionModel getSelectionModel() {
return m_selection;
}
public void setSelectionModel(SingleSelectionModel model) {
Assert.isUnlocked(this);
m_selection = model;
}
public final void lock() {
m_locked = true;
}
public final boolean isLocked() {
return m_locked;
}
}

View File

@ -1,62 +0,0 @@
/*
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.bebop.table;
import org.libreccm.cdi.utils.CdiUtil;
import java.util.ArrayList;
import java.util.List;
/**
* This class is used as an bridge between a CDI based Controller class and
* a Bebop {@link TableModel}. The Controller provides a (transactional) method
* for retrieving the data to show in the table. The table model simply retrieves
* the Controller bean using the {@link CdiUtil} and uses the returned list of
* objects of this class for creating the table rows.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @param <K> Type of the row key.
*/
public class RowData<K> {
private K rowKey;
private final String[] cols;
public RowData(final int numCols) {
cols = new String[numCols];
}
public K getRowKey() {
return rowKey;
}
public void setRowKey(final K rowKey) {
this.rowKey = rowKey;
}
public String getColData(final int colIndex) {
return cols[colIndex];
}
public void setColData(final int colIndex, final String data) {
cols[colIndex] = data;
}
}

View File

@ -1,126 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop.table;
import com.arsdigita.bebop.util.GlobalizationUtil ;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Table;
/**
* Render one cell in a table. The renderer returns a component whose
* {@link com.arsdigita.bebop.Component#generateXML generateXML} method
* will be called by the table to include the data for the cell in the
* table's output.
*
* <p> The table uses the returned component only until it calls the cell
* renderer again, so that cell renderers may reuse the same object in
* subsequent calls to {@link #getComponent getComponent}.
*
* <p> As an example, consider the following implementation of a table cell
* renderer, which simply converts the passed in <code>value</code> to a
* string and encloses it in a label. The cell renderer converts the passed
* in value to a string and uses that to set the text to display for a
* label. If the value is selected, the label is bolded. As an added twist,
* the table cell renderer uses only one label for each thread from which
* it is accessed (rather than creating a new <code>Label</code> for each
* call) by storing the label in a <code>ThreadLocal</code> variable.
*
* <pre>
* public class MyTableCellRenderer implements TableCellRenderer {
*
* private ThreadLocal m_label;
*
* public MyTableCellRenderer() {
* m_label = new ThreadLocal() {
* protected Object initialValue() {
* return new Label("");
* }
* };
* }
*
* public Component getComponent(Table table, PageState state, Object value,
* boolean isSelected, Object key,
* int row, int column) {
* Label l = (Label) m_label.get();
* l.setLabel(value.toString());
* l.setFontWeight( isSelected ? Label.BOLD : null );
* return l;
* }
* }
* </pre>
*
* @author David Lutterkort
* @see com.arsdigita.bebop.Table Table
* @version $Id$
*/
public interface TableCellRenderer {
/**
* Return a component with the visual representation for the passed in
* <code>key</code> and <code>value</code>.
*
* <p> The table sets the control event prior to calling this method, so
* that any control link returned as the component will, when clicked,
* cause the table to fire a <code>TableActionEvent</code> whose
* <code>getRowKey()</code> and <code>getColumn()</code> return the
* values of <code>key</code> and <code>column</code>. A simple cell
* renderer that achieves this would implement this method in the
* following way:
* <pre>
* public Component getComponent(Table table, PageState state, Object value,
* boolean isSelected, Object key,
* int row, int column) {
* return new ControlLink(value.toString());
* }
* </pre>
*
* <p> The <code>column</code> refers to a column in the table's {@link
* TableColumnModel}, i.e. the visual column on the screen, and not the
* table's representation of the underlying data in the {@link
* TableModel}.
*
* @param table the table requesting the rendering.
* @param state represents the state of the current request.
* @param value the data element to render as returned by the table
* model's {@link TableModel#getElementAt getElementAt(column)}.
* @param isSelected true if this item is selected.
* @param key the key identifying this row (and possibly column) as
* returned by the table model's {@link TableModel#getKeyAt
* getKeyAt(column)}
* @param row the number of the row in the table, the first row has
* number <code>0</code>.
* @param column the number of the table column.
* @return the component that should be used to render the
* <code>value</code>.
* @pre table != null
* @pre state != null
* @pre value != null
* @pre key != null
* @pre row >= 0
* @pre column >= 0 && column < table.getColumnModel().size()
* @post return != null
* @see TableColumnModel
*/
Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key,
int row, int column);
}

View File

@ -1,458 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop.table;
import static com.arsdigita.bebop.Component.*;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleComponent;
import com.arsdigita.util.Assert;
import com.arsdigita.bebop.util.Attributes;
import com.arsdigita.util.Lockable;
import com.arsdigita.xml.Element;
/**
* One column in a table. The <code>TableColumn</code> stores important
* display-related information about a table column, such as the column
* header, the renderers for the column header and ordinary cells in this
* column and from which column in the table model values should be taken
* when rendering table cells. The set of table columns for a table is
* maintained by a {@link TableColumnModel}.
*
* <p> <code>TableColumn</code> allows the column ordering to be different
* between the underlying {@link TableModel} and the view presented by the
* <code>Table</code>: each column contains a <code>modelIndex</code>
* property. This is the column that is retrieved from the
* <code>TableModel</code> when the values are displayed, regardless of the
* position of the <code>TableColumn</code> in the
* <code>TableColumnModel</code>. This makes it possible to display the
* same table model in several tables with reordered or omitted columns.
*
* <p> The <code>TableColumn</code> stores also the value and key used for
* the header of the column. These objects are passed to the header cell
* renderer when the header of the table is rendered. The value is usually
* used to generate the visible information for the table header, and is
* often a string. The key is usually used to identify the underlying
* object, or to just identify the column, and can be any object whose
* <code>toString()</code> method returns a representation that can be
* included in a URL. In the simplest case, this may just be an
* <code>Integer</code> containing the index of the column in the column
* model.
*
* @author David Lutterkort
* @see com.arsdigita.bebop.Table
* @see TableColumnModel
*
* @version $Id$ */
public class TableColumn extends SimpleComponent
implements Lockable {
/**
* The name of the width attribute used in the XML.
*/
private static final String WIDTH_ATTR = "width";
/**
* The name of the align attribute used in the XML.
*/
private static final String ALIGN_ATTR = "align";
/**
* The name of the valign attribute used in the XML.
*/
private static final String VALIGN_ATTR = "valign";
/**
* The number of the column in the table model from which to get values.
*/
private int m_modelIndex;
/**
* The renderer used for ordinary cells in this column. Null by default,
* which instructs the <code>Table</code> to use its default renderer.
*/
private TableCellRenderer m_cellRenderer;
/**
* The renderer used for the header of the column. Null by default, which
* instructs the <code>TableHeader</code> to use its default renderer.
*/
private TableCellRenderer m_headerRenderer;
/**
* The key for identifying the header. Will be passed to the header cell
* renderer.
*/
private Object m_headerKey;
/**
* The display value for identifying the header. Will be passed to the
* header cell renderer.
* Usually this will be a {@link Label} passed in by a pattern like
* {@code new Label(GlobalizedMessage)}. But it could be any object,
* e.g.an image as well. The use of a string is possible but strongly
* discouraged because it results in non-localizable UI.
*/
private Object m_headerValue;
/**
* The display attributes for each cell in this column
*/
private Attributes m_cellAttrs;
/**
* Creates a new table column with <code>modelIndex</code> 0 and header
* value and key equal to <code>null</code>.
*/
public TableColumn() {
this(0);
}
/**
* Creates a new table column with the given <code>modelIndex</code> and
* header value and key equal to <code>null</code>.
*
* @param modelIndex the index of the column in the table model from
* which to retrieve values
* @pre modelIndex >= 0
*/
public TableColumn(int modelIndex) {
this(modelIndex, null);
}
/**
* Creates a new table column with the given <code>modelIndex</code> and
* header value. The header key is equal to <code>null</code>.
*
* @param modelIndex the index of the column in the table model from
* which to retrieve values.
* @param value the value for the column header.
* @pre modelIndex >= 0
*/
public TableColumn(int modelIndex, Object value) {
this(modelIndex, value, null);
}
/**
* Creates a new table column with the given <code>modelIndex</code> and
* header value and key.
*
* @param modelIndex the index of the column in the table model from
* which to retrieve values.
* @param value the value for the column header.
* @param key the key for the column header.
* @pre modelIndex >= 0
*/
public TableColumn(int modelIndex, Object value, Object key) {
super();
m_modelIndex = modelIndex;
m_headerValue = value;
m_headerKey = key;
m_cellAttrs = new Attributes();
}
/**
* Return the renderer used for the column header. This is
* <code>null</code> by default, in which case the default renderer for
* the {@link TableHeader} of the table to which this column belongs is
* used.
*
* @return the renderer used for the column header.
*/
public final TableCellRenderer getHeaderRenderer() {
return m_headerRenderer;
}
/**
* Set the renderer used for the column header. The header key and value
* objects are passed to the renderer when the column header will be
* rendererd.
*
* @param v the new renderer for the column header.
* @see #getHeaderRenderer
* @see #getCellRenderer
*/
public void setHeaderRenderer(TableCellRenderer v) {
Assert.isUnlocked(this);
m_headerRenderer = v;
}
/**
* Return the renderer used for the cells in this column. This is
* <code>null</code> by default, in which case the default renderer of
* the {@link com.arsdigita.bebop.Table#getDefaultCellRenderer() table} to which this column
* belongs is used.
*
* @return the renderer used for the cells in this column.
*/
public final TableCellRenderer getCellRenderer() {
return m_cellRenderer;
}
/**
* Set the renderer used for cells in this column.
*
* @param v the new renderer for the cells in this column.
* @see #getCellRenderer
* @see #getHeaderRenderer
*/
public void setCellRenderer(TableCellRenderer v) {
Assert.isUnlocked(this);
m_cellRenderer = v;
}
/**
* Get the display value used for the header. This is the object that is
* passed to the renderer. Usually this will be a {@link Label} previously
* passed in by a pattern like {@code new Label(GlobalizedMessage)}.
* The use of a string is possible but strongly discouraged.
*
* @return the display value for the header.
*/
public final Object getHeaderValue() {
return m_headerValue;
}
/**
* Set the display value for the header. This object is passed through to
* the header renderer without any modifications.
* Usually this will be a {@link Label} passed in by a pattern like
* {@code new Label(GlobalizedMessage)}. The use of a string is possible
* but strongly discouraged because it results in non-localizable UI.
*
* @param value the new display value for the header.
* @see #getHeaderValue
*/
public void setHeaderValue(Object value) {
Assert.isUnlocked(this);
m_headerValue = value;
}
/**
* Get the key used to identify the header of this column. In the
* simplest case, this is an <code>Integer</code> containing the index of
* the column.
*
* @return the key used to identify the header of this column.
*/
public final Object getHeaderKey() {
return m_headerKey;
}
/**
* Set the key used to identify the header of this column.
*
* @param key the new key for identifying the header of this column.
* @see #getHeaderKey
*/
public void setHeaderKey(Object key) {
Assert.isUnlocked(this);
m_headerKey = key;
}
/**
* Get the index of the column from which values are taken in the {@link
* TableModel}.
*
* @return the index of the column in the table model from which values
* are taken.
* @see #setModelIndex setModelIndex
*/
public final int getModelIndex() {
return m_modelIndex;
}
/**
* Set the index of the column in the {@link TableModel} from which the
* values are taken when this column is rendered.
*
* @param v the new index of the column in the table model from which to
* take values.
*/
public void setModelIndex(int v) {
Assert.isUnlocked(this);
m_modelIndex = v;
}
/**
* Get the width for this column.
*
* @return the width of this column.
* @see #setWidth setWidth
*/
public String getWidth() {
return getAttribute(WIDTH_ATTR);
}
/**
* Set the width of this column. The string <code>v</code> is added as an
* attribute to the XML element for this column in the table header.
*
* @param v the width of this column
*/
public void setWidth(String v) {
Assert.isUnlocked(this);
setAttribute(WIDTH_ATTR, v);
}
/**
* Set the horizontal alignment this column. The string <code>v</code>
* is added as an attribute to the XML element for each cell in this column
*
* @param v the width of this column
*/
public void setAlign(String v) {
Assert.isUnlocked(this);
m_cellAttrs.setAttribute(ALIGN_ATTR, v);
}
/**
* Set the horizontal alignment this column's header. The string
* <code>v</code> is added as an attribute to the XML element for
* the column's header cell.
*
* @param v the width of this column */
public void setHeadAlign(String v) {
Assert.isUnlocked(this);
setAttribute(ALIGN_ATTR, v);
}
/**
* Set the vertical alignment this column. The string <code>v</code>
* is added as an attribute to the XML element for each cell in this column
*
* @param v the width of this column
*/
public void setVAlign(String v) {
Assert.isUnlocked(this);
m_cellAttrs.setAttribute(VALIGN_ATTR, v);
}
/**
* Set the vertical alignment this column's header. The string
* <code>v</code> is added as an attribute to the XML element for
* this column's header cell.
*
* @param v the width of this column */
public void setHeadVAlign(String v) {
Assert.isUnlocked(this);
setAttribute(VALIGN_ATTR, v);
}
/**
* Sets the style attribute for the column's
* cells. <code>style</code> should be a valid CSS style, since
* its value will be copied verbatim to the output and appear as a
* <tt>style</tt> attribute in the top level XML or HTML output
* element.
*
* @param style a valid CSS style description for use in the
* <tt>style</tt> attribute of an HTML tag
* @see <a href="#standard">Standard Attributes</a> */
public void setStyleAttr(String style) {
Assert.isUnlocked(this);
m_cellAttrs.setAttribute(STYLE, style);
}
/**
* Sets the style attribute for the column's header
* cell. <code>style</code> should be a valid CSS style, since its
* value will be copied verbatim to the output and appear as a
* <tt>style</tt> attribute in the top level XML or HTML output
* element.
*
* @param style a valid CSS style description for use in the
* <tt>style</tt> attribute of an HTML tag
* @see <a href="#standard">Standard Attributes</a> */
public void setHeadStyleAttr(String style) {
Assert.isUnlocked(this);
setAttribute(STYLE, style);
}
/**
* Sets the class attribute for the column's
* cells. <code>style</code> should be the name of a defined CSS
* class, since its value will be copied verbatim to the output
* and appear as a <tt>class</tt> attribute in the top level XML
* or HTML output element.
*
* @param style a valid CSS style description for use in the
* <tt>style</tt> attribute of an HTML tag
* @see <a href="#standard">Standard Attributes</a> */
public void setClassAttr(String c) {
Assert.isUnlocked(this);
m_cellAttrs.setAttribute(CLASS, c);
}
/**
* Sets the class attribute for the column's header
* cell. <code>style</code> should be the name of a defined CSS
* class, since its value will be copied verbatim to the output
* and appear as a <tt>class</tt> attribute in the top level XML
* or HTML output element.
*
* @param style a valid CSS style description for use in the
* <tt>style</tt> attribute of an HTML tag
* @see <a href="#standard">Standard Attributes</a> */
public void setHeadClassAttr(String c) {
Assert.isUnlocked(this);
setAttribute(CLASS, c);
}
/**
* Add all the XML attributes for this column.
*
* @param e the XML element to which attributes will be added.
*/
public void exportCellAttributes(Element e) {
m_cellAttrs.exportAttributes(e);
}
/**
* Add all the XML attributes for this column to this
* element. Package-friendly since it is only used by {@link
* TableHeader}.
*
* @param e the XML element to which attributes will be added.
*/
final void exportHeadAttributes(Element e) {
super.exportAttributes(e);
}
/**
* Throw an <code>UnsupportedOperationException</code>. This method can
* only be called if the table column is not properly contained in a
* table.
*
* @param s represents the current request
* @param e the parent element
*/
public void generateXML(PageState s, Element e) {
throw new UnsupportedOperationException("TableColumn used outside of a Table");
}
}

View File

@ -1,62 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop.table;
import java.util.Iterator;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.util.Lockable;
/**
* Describe interface <code>TableColumnModel</code> here.
*
* @author David Lutterkort
* @version $Id$
*/
public interface TableColumnModel extends Lockable {
void add(TableColumn column);
TableColumn get(int columnIndex);
/**
* Insert a column at the given index. The columns from
* <code>columnIndex</code> on are shifted one up.
*
* @param columnIndex the index for the new column.
* @param column the table column to add to the model.
* @pre 0 <= columnIndex && columnIndex <= size()
*/
void add(int columnIndex, TableColumn column);
void set(int columnIndex, TableColumn v);
int size();
int getIndex(Object columnIdentifier);
Iterator columns();
void remove(TableColumn column);
SingleSelectionModel getSelectionModel();
void setSelectionModel(SingleSelectionModel model);
}

View File

@ -1,298 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop.table;
import static com.arsdigita.bebop.Component.*;
import java.util.Iterator;
import javax.servlet.ServletException;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleComponent;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.event.EventListenerList;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.util.Assert;
import com.arsdigita.xml.Element;
/**
* This class is used by {@link Table} in order to maintain its headers.
*
* <code>TableHeader</code> is responsible for setting the control event
* in order to notify the {@link Table} when one of the column headers
* is clicked.
*
* @author David Lutterkort
* @version $Id$
*/
public class TableHeader extends SimpleComponent {
/**
* The control event when the user clicks on a column header.
*/
public static final String HEAD_EVENT = "head";
private TableCellRenderer m_defaultRenderer;
private TableColumnModel m_columnModel;
private Table m_table;
private EventListenerList m_listeners;
/**
* Create a new <code>TableHeader</code>
*/
public TableHeader() {
this(new DefaultTableColumnModel());
}
/**
* Create a new <code>TableHeader</code>
*
* @param model the {@link TableColumnModel} that the header
* will use in order to generate and maintain the
* column headers.
*/
public TableHeader(TableColumnModel model) {
m_columnModel = model;
m_defaultRenderer = new DefaultTableCellRenderer();
m_listeners = new EventListenerList();
}
/**
* Add an {@link TableActionListener} to the header.
* The listener will be fired whenever this header is
* selected by the user.
*
* @param l the {@link TableActionListener} to add
*/
public void addTableActionListener(TableActionListener l) {
Assert.isUnlocked(this);
m_listeners.add(TableActionListener.class, l);
}
/**
* Remove a {@link TableActionListener} from the header
*
*@param l the {@link TableActionListener} to remove
*/
public void removeTableActionListener(TableActionListener l) {
Assert.isUnlocked(this);
m_listeners.remove(TableActionListener.class, l);
}
/**
* Notify all listeners that the header was selected
*
* @param state the page state
* @param rowKey the key of the selected row, as returned by
* <code>Table.getRowSelectionModel().getSelectedKey(state)</code>.
* this key may be null.
* @param column The index of the selected column
*
*/
protected void fireHeadSelected(PageState state,
Object rowKey, Integer column) {
Iterator
i=m_listeners.getListenerIterator(TableActionListener.class);
TableActionEvent e = null;
while (i.hasNext()) {
if ( e == null ) {
e = new TableActionEvent(this, state, rowKey, column);
}
((TableActionListener) i.next()).headSelected(e);
}
}
/**
* Respond to the current event by selecting the current
* column
*
* @param s the page state
*/
public void respond(PageState s) throws ServletException {
String event = s.getControlEventName();
if ( HEAD_EVENT.equals(event) ) {
String value = s.getControlEventValue();
// FIXME: ParameterData allows its value to be set to anything, even
// if it isn't compatible with the ParameterModel
// We need to change ParameterModel/Data to fail earlier on bad data
Integer col = new Integer(value);
getColumnModel().getSelectionModel().setSelectedKey(s, col);
fireHeadSelected(s, null, col);
} else {
throw new ServletException("Unknown event '" + event + "'");
}
}
/**
* @return the parent {@link Table}
*/
public final Table getTable() {
return m_table;
}
/**
* Set the parent {@link Table}
*
* @param v the parent table
*/
public void setTable(Table v) {
Assert.isUnlocked(this);
m_table = v;
}
/**
* @return the {@link TableColumnModel} which maintains the headers
*/
public final TableColumnModel getColumnModel() {
return m_columnModel;
}
/**
* Set the {@link TableColumnModel} which will maintain the headers
*
* @param v the new {@link TableColumnModel}
*/
public void setColumnModel(TableColumnModel v) {
Assert.isUnlocked(this);
m_columnModel = v;
}
/**
* @return the default {@link TableCellRenderer} for this header
*/
public final TableCellRenderer getDefaultRenderer() {
return m_defaultRenderer;
}
/**
* Set the default {@link TableCellRenderer} for this header.
* Header cells will be rendered with this renderer unless
* the column model specifies an alternative renderer.
*
* @param v the new default renderer
*/
public void setDefaultRenderer(TableCellRenderer v) {
Assert.isUnlocked(this);
m_defaultRenderer = v;
}
/**
* Generate the XML for this header. The XML will be of the form
* <blockquote><pre><code>
* &lt;bebop:thead&gt;
* &lt;bebop:cell&gt;...&lt;/bebop:cell&gt;
* ...
* &lt;/bebop:thead&gt;
* </code><pre></blockquote>
*
* @param s the page state
* @param p the parent element
*/
public void generateXML(PageState s, Element p) {
if ( isVisible(s) ) {
Element thead = p.newChildElement("bebop:thead", BEBOP_XML_NS);
exportAttributes(thead);
for (int i=0; i < m_columnModel.size(); i++) {
TableColumn t = m_columnModel.get(i);
if ( t.isVisible(s) ) {
TableCellRenderer r = t.getHeaderRenderer();
if ( r == null ) {
r = getDefaultRenderer();
}
boolean isSel = isSelected(s, t.getHeaderKey(), i);
Component c = r.getComponent(getTable(), s, t.getHeaderValue(), isSel,
t.getHeaderKey(), -1, i);
if (c != null) {
// supports having a table header disappear
// completely, mainly useful for the odd special case
// where a second-row element is being displayed.
Element cell = thead.newChildElement("bebop:cell", BEBOP_XML_NS);
t.exportHeadAttributes(cell);
// Mark the cell as selected if it is selected
if(isSel) {
cell.addAttribute("selected", "1");
}
// I added this check so that a table which is not
// added to the Page can still be used to render
// table XML.
boolean tableIsRegisteredWithPage =
s.getPage().stateContains(getControler());
if (tableIsRegisteredWithPage) {
s.setControlEvent(getControler(), HEAD_EVENT,
String.valueOf(i));
}
c.generateXML(s, cell);
if (tableIsRegisteredWithPage) {
s.clearControlEvent();
}
}
}
}
}
}
protected Component getControler() {
return this;
}
/**
* Determine whether the given column is selected. This information
* will be passed to the {@link TableCellRenderer} for this header.
*
* @param s the page state
* @param key the header key for the column as returned by
* <code>TableColumn.getHeaderKey()</code>
* @param column the index of the column to test
*/
protected boolean isSelected(PageState s, Object key, int column) {
if (getTable().getColumnSelectionModel() == null) {
return false;
}
Object sel = getTable()
.getColumnSelectionModel().getSelectedKey(s);
if(sel == null) {
return false;
}
return (column == ((Integer)sel).intValue());
}
}

View File

@ -1,104 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop.table;
/**
* The <code>TableModel</code> is the abstraction a {@link
* com.arsdigita.bebop.Table Table} uses to access the data it
* displays. The table will ask its {@link TableModelBuilder} to
* instantiate a new table model once for each request it processes.
*
* <p> The table will request each element in the model at most once per
* request, moving through the rows with successive calls to {@link
* #nextRow}. For each row, the table retrieves the values and keys in each
* column with calls to {@link #getElementAt} and {@link #getKeyAt}.
*
* <p> The table data is accessed by the table by moving through the rows
* of the table model with calls to {@link #nextRow}. The data for each
* column in a row is represented by two objects: the data element which
* usually contains display information for that column and can be as
* simple as a string, and the key, which is used to identify the
* column. The key is usually a suitable representation of the primary key
* of the underlying object in the database. The key needs to be unique
* amongst all <em>rows</em> in the table model, but doesn't need to
* uniquely identify the row <em>and</em> column for that data item -
* all calls to {@link #getKeyAt} can return the same value for one row in
* the table model.
*
* @see com.arsdigita.bebop.Table Table
* @see TableModelBuilder
*
* @author David Lutterkort
* @version $Id$ */
public interface TableModel {
/**
* Return the number of columns this table model has.
*
* @return the number of columns in the table model
* @post return >= 0
*/
int getColumnCount();
/**
* Move to the next row and return true if the model is now positioned on
* a valid row. Initially, the table model is positioned before the first
* row. The table will call this method before it retrieves the data for
* the row with calls to {@link #getElementAt getElementAt} and {@link
* #getKeyAt getKeyAt}.
*
* <p> If this method returns <code>true</code>, subsequent calls to
* {@link #getElementAt getElementAt} and {@link #getKeyAt getKeyAt} have
* to succeed and return non-null objects. If this method returns
* <code>false</code>, the table assumes that it has traversed all the
* data contained in this model.
*
* @return <code>true</code> if the model is positioned on a valid row
*/
boolean nextRow();
/**
* Return the data element for the given column and the current row. The
* returned object will be passed to the table cell renderer as the
* <code>value</code> argument without modifications.
*
* @param columnIndex the number of the column for which to get data
* @return the object to pass to the table cell renderer for display
* @pre columnIndex >= 0 && columnIndex < getColumnCount()
* @post return != null
* @see TableCellRenderer
*/
Object getElementAt(int columnIndex);
/**
* Return the key for the given column and the current row. The key has
* to be unique for each <em>row</em> in the table model, but does not
* need to be unique for each row <em>and</em> column, though it may.
* The key is passed to the table cell renderer as the <code>key</code>
* argument.
*
* @param columnIndex the number of the column for which to get data
* @return the key for the given column and the current row.
* @pre columnIndex >= 0 && columnIndex < getColumnCount()
* @post return != null
* @see TableCellRenderer
*/
Object getKeyAt(int columnIndex);
}

View File

@ -1,65 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.bebop.table;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Table;
import com.arsdigita.util.Lockable;
/**
* Builds the request-specific table models. A table retrieves the data it
* displays by asking the table model builder for a table model. This is
* done for each request; the table does not cahce table models across
* requests. If such caching is desired, it has to be performed by the
* table model builder.
*
* <p> Typically, the table model builder will run a database query based
* on the information contained in the page state and return the result of
* the database query by wrapping it in a table model. The table will then
* traverse the table model during rendering.
*
* <p> The table model builder is automatically locked by the table to
* which it was added either through one of the {@link
* com.arsdigita.bebop.Table Table} constructors or with a call to {@link
* com.arsdigita.bebop.Table#setModelBuilder}.
*
* @see com.arsdigita.bebop.Table Table
* @see TableModel
*
* @author David Lutterkort
* @version $Id$
*/
public interface TableModelBuilder extends Lockable {
/**
* Return a table model for the request represented by
* <code>s</code>. The table model contains all the data that is to be
* displayed in a table. The returned table model is used only during
* the duration of that request.
*
* @param t the table which will use this table model
* @param s represents the current request
* @return the data to be displayed in the table
* @pre t != null
* @pre s != null
* @post return != null
*/
TableModel makeModel(Table t, PageState s);
}