package org.javabuilders.swing.handler.type;
import java.util.Map;
import java.util.Set;
import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import org.javabuilders.BuildException;
import org.javabuilders.BuildProcess;
import org.javabuilders.Builder;
import org.javabuilders.BuilderConfig;
import org.javabuilders.Node;
import org.javabuilders.handler.AbstractTypeHandler;
import org.javabuilders.handler.ITypeHandlerFinishProcessor;
import org.javabuilders.util.JBStringUtils;
/**
* TableColumn handler
* @author Jacek Furmankiewicz
*
*/
public class TableColumnTypeHandler extends AbstractTypeHandler implements ITypeHandlerFinishProcessor {
/**
* Defines custom property name that controls if a cell renderer should be for the cell (default) or for the header
*/
public static final String FOR_HEADER = "forHeader";
public static final String IDENTIFIER = "identifier";
public static final String HEADER_VALUE = "headerValue";
public static final String FILTER = "filter"; //handled by table model handlers
public static final String EDITABLE = "editable"; //handled by table model handlers
public static final String INTERNAL_MODEL_INDEX = Builder.INTERNAL_FIELD_PREFIX + "modelIndex";
private static final TableColumnTypeHandler singleton = new TableColumnTypeHandler();
/**
* @return Singleton
*/
public static TableColumnTypeHandler getInstance() {
return singleton;
}
//constructor
private TableColumnTypeHandler() {
super(FOR_HEADER,FILTER,EDITABLE);
}
/* (non-Javadoc)
* @see org.javabuilders.handler.ITypeHandler#createNewInstance(org.javabuilders.BuilderConfig, org.javabuilders.BuildProcess, org.javabuilders.Node, java.lang.String, java.util.Map)
*/
public Node createNewInstance(BuilderConfig config, BuildProcess process, Node parent, String key,
Map<String, Object> typeDefinition) throws BuildException {
TableColumn instance = null;
JTable table = (JTable) parent.getParentObject(JTable.class);
if (table != null) {
//try to see if a column with this identifier or name already exists
//If it was already processed by a separate model or binding it should have the
//INTERNAL_MODEL_INDEX field in it.
Integer index = (Integer) typeDefinition.get(INTERNAL_MODEL_INDEX);
if (index != null) {
int count = table.getColumnModel().getColumnCount();
for(int i = 0; i < count; i++) {
TableColumn col = table.getColumnModel().getColumn(i);
//attempt to find the column by model index
if (col.getModelIndex() == index) {
instance = col;
break;
}
}
}
}
if (instance == null) {
instance = new TableColumn();
}
return useExistingInstance(config, process, parent, key, typeDefinition, instance);
}
/* (non-Javadoc)
* @see org.javabuilders.handler.ITypeHandler#useExistingInstance(org.javabuilders.BuilderConfig, org.javabuilders.BuildProcess, org.javabuilders.Node, java.lang.String, java.util.Map, java.lang.Object)
*/
public Node useExistingInstance(BuilderConfig config, BuildProcess process, Node parent, String key,
Map<String, Object> typeDefinition, Object instance) throws BuildException {
Node node = new Node(parent,key, typeDefinition,instance);
return node;
}
/* (non-Javadoc)
* @see org.javabuilders.handler.ITypeHandlerFinishProcessor#finish(org.javabuilders.BuilderConfig, org.javabuilders.BuildProcess, org.javabuilders.Node, java.lang.String, java.util.Map)
*/
public void finish(BuilderConfig config, BuildProcess process, Node current, String key, Map<String, Object> typeDefinition)
throws BuildException {
TableColumn col = (TableColumn) current.getMainObject();
//Cell renderers
Set<Node> renderers = current.getContentNodes(TableCellRenderer.class);
for(Node renderer : renderers) {
TableCellRenderer r = (TableCellRenderer) renderer.getMainObject();
if (Boolean.TRUE.equals(renderer.getProperty(FOR_HEADER))) {
col.setHeaderRenderer(r);
} else {
col.setCellRenderer(r);
}
}
//cell editors
Set<Node> editors = current.getContentNodes(TableCellEditor.class, JComboBox.class, JCheckBox.class, JTextField.class);
for(Node editor : editors) {
if (editor.getMainObject() instanceof TableCellEditor) {
TableCellEditor e = (TableCellEditor) editor.getMainObject();
col.setCellEditor(e);
} else if (editor.getMainObject() instanceof JComboBox) {
JComboBox e = (JComboBox) editor.getMainObject();
col.setCellEditor(new DefaultCellEditor(e));
} else if (editor.getMainObject() instanceof JCheckBox) {
JCheckBox e = (JCheckBox) editor.getMainObject();
col.setCellEditor(new DefaultCellEditor(e));
} else if (editor.getMainObject() instanceof JTextField) {
JTextField e = (JTextField) editor.getMainObject();
col.setCellEditor(new DefaultCellEditor(e));
}
}
//table column header
String headerValue = current.getStringProperty(HEADER_VALUE);
if (headerValue == null) {
//create default header value if none specified
headerValue = String.valueOf(col.getHeaderValue());
col.setHeaderValue(JBStringUtils.getDisplayName(headerValue));
}
}
/* (non-Javadoc)
* @see org.javabuilders.IApplicable#getApplicableClass()
*/
public Class<TableColumn> getApplicableClass() {
return TableColumn.class;
}
}