package org.openswing.swing.table.editors.client;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
import javax.swing.table.*;
import org.openswing.swing.util.client.*;
import org.openswing.swing.table.client.Grids;
import org.openswing.swing.util.java.Consts;
import org.openswing.swing.table.client.Grid;
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Column editor used to edit a check-box type column.</p>
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
*
* <p> This file is part of OpenSwing Framework.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the (LGPL) Lesser General Public
* License as published by the Free Software Foundation;
*
* GNU LESSER GENERAL PUBLIC LICENSE
* Version 2.1, February 1999
*
* 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* The author may be contacted at:
* maurocarniel@tin.it</p>
*
* @author Mauro Carniel
* @version 1.0
*/
public class CheckBoxCellEditor extends AbstractCellEditor implements TableCellEditor {
/** flag used to store current check-box state */
private Boolean selected = Boolean.FALSE;
/** cell content (a check-box is drawed inside it) */
private CheckLabel label = new CheckLabel();
/** flag used to set mandatory property of the cell */
private boolean required;
/** ItemListener list associated to the check-box */
private ArrayList itemListenerList = null;
/** current row index */
private int row = -1;
/** current model column index */
private int column = -1;
/** table hook */
private Grids grids = null;
/** define if null value is alloed (i.e. distinct from Boolean.FALSE value); default value: <code>false</code> */
private boolean allowNullValue;
/** value used to select the check-box */
private Object positiveValue = null;
/** value used to deselect the check-box */
private Object negativeValue = null;
/**
* Construtor.
* @param required flag used to set mandatory property of the cell
* @param itemListenerList ItemListener list associated to the check-box
*/
public CheckBoxCellEditor(Grids grids,boolean required,ArrayList itemListenerList,boolean allowNullValue,Object positiveValue,Object negativeValue) {
this.grids = grids;
this.required = required;
this.itemListenerList = itemListenerList;
this.allowNullValue = allowNullValue;
this.positiveValue = positiveValue;
this.negativeValue = negativeValue;
label.setFocusable(true);
label.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Grid grid = CheckBoxCellEditor.this.grids.getGrid();
if (CheckBoxCellEditor.this.grids.getLockedGrid()!=null &&
column<CheckBoxCellEditor.this.grids.getLockedGrid().getColumnCount())
grid = CheckBoxCellEditor.this.grids.getLockedGrid();
int gridIndex = grid.convertColumnIndexToView(column);
if (!grid.hasFocus())
grid.requestFocus();
changeSelectedValue();
Object value = null;
if (selected==null && CheckBoxCellEditor.this.allowNullValue)
value = null;
else if (selected==null && !CheckBoxCellEditor.this.allowNullValue)
value = CheckBoxCellEditor.this.negativeValue;
else if (selected.booleanValue())
value = CheckBoxCellEditor.this.positiveValue;
else
value = CheckBoxCellEditor.this.negativeValue;
grid.setValueAt(
value,
grid.getSelectedRow(),
gridIndex
);
grid.editCellAt(
grid.getSelectedRow(),
gridIndex
);
for(int i=0;i<CheckBoxCellEditor.this.itemListenerList.size();i++)
((ItemListener)CheckBoxCellEditor.this.itemListenerList.get(i)).itemStateChanged(new ItemEvent(new JCheckBox(),column,CheckBoxCellEditor.this,-1));
grid.repaint();
}
});
}
});
}
public final boolean stopCellEditing() {
return(validate());
}
/**
* Perform the validation.
*/
private final boolean validate() {
fireEditingStopped();
return true;
}
public final Object getCellEditorValue() {
Object value = null;
if (selected==null && CheckBoxCellEditor.this.allowNullValue)
value = null;
else if (selected==null && !CheckBoxCellEditor.this.allowNullValue)
value = CheckBoxCellEditor.this.negativeValue;
else if (selected.booleanValue())
value = CheckBoxCellEditor.this.positiveValue;
else
value = CheckBoxCellEditor.this.negativeValue;
return value;
}
/**
* Prepare the editor for a value.
*/
private final Component _prepareEditor(Object value) {
if (value==null) {
if (allowNullValue)
selected = null;
else
selected = Boolean.FALSE;
}
else if (positiveValue.equals(value))
selected = Boolean.TRUE;
else
selected = Boolean.FALSE;
if (column!=-1 &&
grids.isEnableInReadOnlyMode(column)&&
grids.getMode()==Consts.READONLY) {
// if (row!=grids.getSelectedRow()) {
// if (selected==null || !selected.booleanValue())
// selected = Boolean.TRUE;
// else
// selected = Boolean.FALSE;
// }
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (grids.getSelectedRow()!=row) {
grids.setRowSelectionInterval(row, row);
changeSelectedValue();
}
}
});
}
label.repaint();
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
// table.editingStopped(null);
// table.setColumnSelectionInterval(column,column);
// }
// });
return label;
}
public final Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row,
int column) {
this.row = row;
this.column = table.convertColumnIndexToModel(column);
// table.setRowSelectionInterval(row,row);
label.setPreferredSize(new Dimension(table.getColumnModel().getColumn(column).getWidth(),table.getHeight()));
label.setOpaque(false);
// label.setBackground(table.getBackground());
return _prepareEditor(value);
}
public final void changeSelectedValue() {
if (allowNullValue) {
if (selected==null)
selected = Boolean.TRUE;
else if (Boolean.FALSE.equals(selected))
selected = null;
else
selected = Boolean.FALSE;
}
else {
if (selected!=null && Boolean.TRUE.equals(selected))
selected = Boolean.FALSE;
else
selected = Boolean.TRUE;
}
if (grids.getMode()!=Consts.READONLY ||
grids.isEnableInReadOnlyMode(column) && grids.getMode()==Consts.READONLY) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Object value = null;
if (selected==null && CheckBoxCellEditor.this.allowNullValue)
value = null;
else if (selected==null && !CheckBoxCellEditor.this.allowNullValue)
value = CheckBoxCellEditor.this.negativeValue;
else if (selected.booleanValue())
value = CheckBoxCellEditor.this.positiveValue;
else
value = CheckBoxCellEditor.this.negativeValue;
Grid grid = CheckBoxCellEditor.this.grids.getGrid();
if (CheckBoxCellEditor.this.grids.getLockedGrid()!=null &&
column<CheckBoxCellEditor.this.grids.getLockedGrid().getColumnCount())
grid = CheckBoxCellEditor.this.grids.getLockedGrid();
int gridIndex = grid.convertColumnIndexToView(column);
grid.setValueAt(
value,
grid.getSelectedRow(),
gridIndex
);
grid.editCellAt(grid.getSelectedRow(),gridIndex);
for(int i=0;i<CheckBoxCellEditor.this.itemListenerList.size();i++)
((ItemListener)CheckBoxCellEditor.this.itemListenerList.get(i)).itemStateChanged(new ItemEvent(new JCheckBox(),column,CheckBoxCellEditor.this,-1));
grid.repaint();
}
});
}
}
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Inner class used to draw the check-box into the cell.</p>
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
* <p> </p>
* @author Mauro Carniel
* @version 1.0
*/
class CheckLabel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (required) {
g.setColor(ClientSettings.GRID_REQUIRED_CELL_BORDER);
g.drawRect(0,0,this.getWidth()-1,this.getHeight()-1);
// g.drawString("*",15,0);
}
else {
g.setColor(Color.gray);
g.drawRect(0,0,this.getWidth()-1,this.getHeight()-1);
// g.drawString("*",15,0);
}
g.translate((int)this.getWidth()/2-6,this.getHeight()/2-5);
BasicGraphicsUtils.drawLoweredBezel(g,0,0,12,12,Color.darkGray,Color.black,Color.white,Color.gray);
if (allowNullValue && selected==null) {
g.setColor(Color.lightGray);
g.fillRect(1,1,10,10);
}
if (Boolean.TRUE.equals(selected)) {
g.setColor(Color.black);
g.drawLine(3,5,5,7);
g.drawLine(3,6,5,8);
g.drawLine(3,7,5,9);
g.drawLine(6,6,9,3);
g.drawLine(6,7,9,4);
g.drawLine(6,8,9,5);
}
}
public boolean processKeyBinding(KeyStroke ks, KeyEvent e,
int condition, boolean pressed) {
if (e.getSource()!=null &&
(e.getSource() instanceof org.openswing.swing.table.client.Grid ||
e.getSource().equals(this) )) {
if (e.getKeyChar()==' ' && pressed)
try {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (!grids.getGrid().hasFocus())
grids.getGrid().requestFocus();
changeSelectedValue();
// if (!table.hasFocus())
// table.requestFocus();
// grids.getGrid().setValueAt(selected,grids.getGrid().getSelectedRow(),column);
// grids.getGrid().editCellAt(grids.getGrid().getSelectedRow(),column);
// for(int i=0;i<CheckBoxCellEditor.this.itemListenerList.size();i++)
// ((ItemListener)CheckBoxCellEditor.this.itemListenerList.get(i)).itemStateChanged(new ItemEvent(new JCheckBox(),column,CheckBoxCellEditor.this,-1));
}
});
}
catch (Exception ex) {
}
}
return true;
}
}
public final void finalize() {
grids = null;
itemListenerList.clear();
}
}