/*
* Copyright (C) 2004 TiongHiang Lee
*
* 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
*
* Email: thlee@onemindsoft.org
*/
package org.onemind.swingweb.mapinput.peerdelegate.javax.swing;
import java.awt.*;
import java.util.Map;
import java.util.logging.Logger;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableModel;
import org.onemind.awtbridge.event.BridgeEventQueue;
import org.onemind.awtbridge.input.BridgeInputContext;
import org.onemind.awtbridge.input.InputException;
import org.onemind.awtbridge.peer.BridgeComponentPeer;
import org.onemind.awtbridge.peer.BridgePeer;
import org.onemind.swingweb.mapinput.peerdelegate.DefaultMapInputDelegate;
import org.onemind.swingweb.mapinput.peerdelegate.MapInputDelegate;
/**
* The JTable input delegate
* @author TiongHiang Lee (thlee@onemindsoft.org)
*
*/
public class JTableInputDelegate extends JComponentInputDelegate
{
/** the logger * */
private static final Logger _logger = Logger.getLogger(JTableInputDelegate.class.getName());
/** the instance **/
public static MapInputDelegate INSTANCE = new JTableInputDelegate();
/** for asserting the identity of the cell editor **/
private static class AssertCellEditorIdEvent extends AWTEvent implements ActiveEvent
{
private String _id;
public AssertCellEditorIdEvent(BridgePeer peer, String id)
{
super(peer, 0);
_id = id;
}
public void dispatch()
{
((BridgePeer) getSource()).setId(_id);
}
}
/** the editing event * */
private class EditingEvent extends AWTEvent implements ActiveEvent
{
/** the table * */
private JTable _table;
/** the bridge input context * */
private BridgeInputContext _context;
/** the input form * */
private Map _inputForm;
/**
* Constructor
* @param table the table
* @param cellPeer the cell peer
* @param context the context
* @param inputForm the input form
* @param rows the row
* @param cols the col
*/
public EditingEvent(BridgePeer peer, BridgeInputContext context, Map inputForm)
{
super(peer, 0);
_table = (JTable) peer.getComponentObject();
_context = context;
_inputForm = inputForm;
}
/**
* {@inheritDoc}
*/
public void dispatch()
{
try
{
BridgePeer peer = (BridgePeer) getSource();
TableModel model = _table.getModel();
int rows = model.getRowCount();
int cols = model.getColumnCount();
for (int i = 0; i < rows; i++)
{
//handle cell events
for (int j = 0; j < cols; j++)
{
boolean edit = model.isCellEditable(i, j);
if (edit)
{
TableCellEditor editor = _table.getCellEditor(i, j);
Component com = _table.prepareEditor(editor, i, j);
BridgePeer childPeer = _context.getContext().getPeer(com);
if (childPeer == null)
{
_table.add(com); //forge the peer creation
com.addNotify();
childPeer = _context.getContext().getPeer(com);
}
String oldId = childPeer.getId();
String newId = peer.getId() + "_" + i + "_" + j;
childPeer.setId(newId);
try
{
if (((DefaultMapInputDelegate) childPeer.getInputDelegate()).hasEvent(childPeer, _inputForm))
{
if (_table.editCellAt(i, j))
{
((BridgeEventQueue)_context.getEventQueue()).setImmediateDispatch(true);
try
{
childPeer.processInput(_context, _inputForm);
} finally
{
((BridgeEventQueue) _context.getEventQueue()).setImmediateDispatch(false);
}
} else
{
_logger.severe("Cannot focus cell on " + i + ", " + j);
}
}
} finally
{
childPeer.setId(oldId);
}
}
}
}
} catch (InputException ex)
{
_logger.severe("Problem dispatching table editing events");
_logger.throwing(getClass().getName(), "dispatch", ex);
}
}
}
/**
* {@inheritDoc}
*/
public void processInput(BridgeComponentPeer peer, BridgeInputContext context, Map inputForm) throws InputException
{
if (hasEvent(peer, inputForm)) //quick check for table visibility
{
JTable table = (JTable) peer.getComponentObject();
TableModel model = table.getModel();
int rows = table.getRowCount();
// handle selection
if ("select".equals(inputForm.get(peer.getId() + "-action")))
{
String value = (String) inputForm.get(peer.getId());
if (value != null)
{
String[] info = value.split(",");
if (info.length == 2)
{
int row = Integer.parseInt(info[0]);
int col = Integer.parseInt(info[1]);
if (row == -1)
{ //column selection
table.setColumnSelectionInterval(col, col);
} else
{ //row selection
table.getSelectionModel().setSelectionInterval(row, row);
}
} else
{
_logger.warning("Expecting row, col information for select action");
}
} else
{
_logger.warning("Expecting row, col information for select action");
}
}
//the whole editing must be done in an event to make sure whole event processing is in one thread (the EventDispatchThread)
//so no one is modifying the peer id while input is done on each cell.
EditingEvent evt = new EditingEvent(peer, context, inputForm);
postEvent(context, evt);
}
}
}