Trying to build a date picker for Swing. See those blank cells either side of the numbers? Well, you shouldn't be able to select them because they don't represent anything usable. I can't seem to find any way to disable just specific cells in a JTable. I tried this in my cell renderer but it doesn't work
I just did this for now. Disabled the cells, but put last month's numbers in them. You can still select the cells which isn't what I wanted but they don't highlight. Either way, it will alow my stuff to work as expected.
/*
* Licensed under the terms of the GNU Lesser General Public License
* Please read the LICENSE file
*/
package org.w3style.calendar;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
/**
* CalendarTable is a JTable which does not allow empty cells to be selected
* @author Chris Corbyn
*/
public class CalendarTable extends JTable
{
/**
* Ctor
* @param model The table model to render
*/
CalendarTable(AbstractTableModel model)
{
super(model);
}
/**
* Overridden to prevent empty cells from being selected
*/
public void changeSelection(int row, int col, boolean toggle, boolean extend)
{
if ((String)(this.getValueAt(row, col)) != "")
super.changeSelection(row, col, toggle, extend);
}
}
In the windowsforms world this problem seems to be tackled as following (reducing the need to subclass a control):
- Before the changeSelection is called, a Selecting event is raised.. and after the call a Selected event is raised...
(the selecting event has a property bool Cancel that allows the user to cancel the operation)
I see... that's a bit like JS. I wondered if a changeListener could be used to do something similar but ChangeEvent has such a basic API it clearly isn't
I enhanced the subclass I made and allowed cells to be disabled and enabled by calling a disableCellAt() method now. It means I can actually put numbers in the disabled cells rather than leaving them blank
/*
* Licensed under the terms of the GNU Lesser General Public License
* Please read the LICENSE file
*/
package org.w3style.calendar;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import java.util.HashMap;
/**
* CalendarTable is a JTable which allows cells to be disabled
* @author Chris Corbyn
*/
public class CalendarTable extends JTable
{
/**
* A matrix of the disabled cell positions
*/
protected HashMap<Integer,HashMap<Integer,Boolean>> disabledRows;
/**
* Ctor
* @param model The table model to render
*/
public CalendarTable(AbstractTableModel model)
{
super(model);
this.disabledRows = new HashMap<Integer,HashMap<Integer,Boolean>>();
}
/**
* Disable a cell selection at the coordinates (row,col)
* @param row The row of the cell
* @param col The column of the cell
*/
public void disableCellAt(int row, int col)
{
if (!this.disabledRows.containsKey(row))
{
this.disabledRows.put(row, new HashMap<Integer,Boolean>());
}
this.disabledRows.get(row).put(col, true);
}
/**
* Clear out disabled cell statuses
*/
public void resetCellStates()
{
this.disabledRows.clear();
}
/**
* Enable a cell if it has been disabled
* @param row The row of the disabled cell
* @param col The column of the disabled cell
*/
public void enableCellAt(int row, int col)
{
if (this.isDisabledAt(row, col))
this.disabledRows.get(row).remove(col);
}
/**
* Check if the cell at row,col is disabled
* @param row The row to test
* @param col The column to test
* @return true, if the cell is disabled
*/
public boolean isDisabledAt(int row, int col)
{
if (this.disabledRows.containsKey(row))
{
if (this.disabledRows.get(row).containsKey(col) && this.disabledRows.get(row).get(col))
{
return true;
}
}
return false;
}
/**
* Overridden to prevent disabled cells from being selected
*/
public void changeSelection(int row, int col, boolean toggle, boolean extend)
{
if (!this.isDisabledAt(row, col))
super.changeSelection(row, col, toggle, extend);
}
}