OK, that helps. it sounds like you are wrapping a "detail" or "lookup"
table in an instance of DataContext to populate a list button in a
table view editor - is that correct? You are then passing an instance
of DataContext representing a row in the master table to
ListButton#setSelectedItem(), and using the foreign key in the master
row to identify the value in the list button to select? Only the
foreign key value is initially set to null, so you actually want to
clear the selection in the list button, but you can't because of how
ListButton currently works. Yes?
I think you mentioned that your DataContextList class (which you use
as the list data for the list button) is coded to return -1 in this
case. If so, that would translate to clearing the selection if
ListButton was modified so that it doesn't throw in this case. I think
it is probably OK to make this change. I just looked at the Swing docs
for comparision:
http://java.sun.com/javase/6/docs/api/javax/swing/JComboBox.html#setSelectedItem(java.lang.Object)
JComboBox#setSelectedItem() does not throw when the given item is not
in the list. It simply leaves the selection state as-is, which I don't
think is the right behavior. However, clearing the selection certainly
seems valid.
Unless there are any objections, I will make this change.
On Sep 14, 2009, at 9:31 PM, Scott Lanham wrote:
On Tue, 15 Sep 2009 10:44:40 am Greg Brown wrote:
DataContext does
represent a row but it also can represent a single field in that
row. It
overrides toString so it can also be used in ListView/ListButton.
That is an interesting approach. If it is not too much to explain, I
would be interested to learn more about how it works.
First of all I use business objects which abstract database tables/
rows/fields
into EntitySet/Entity/Attribute. But I will translate things to
database
speak. Also I am stating things you already know but the only way I
can think
through the process is to walk the pathways and describe them :-)
DataContext has three roles; To represent a row in the TableView, to
be an
item in ListButton/ListView and to be bindable to a Form. Internally
it keeps
reference to a database table and the row index within that table.
It also
holds a defaultKey and defaultDisplayKey the last of which is used
when
toString() is called.
When used with a Form, DataContext simply accesses the table/row
using the
given key with get() or put(). The only tricky thing it does is that
it has
the ability to transform field data to/from the data type the
database field
uses to the type the Form expects. These automatic transforms cut
out a heap
of boilerplate code.
When bound to a TableView a DataContextList is required. This
generates
DataContext items and passes them as the row data. For read only
TableViews
DataContext provides the same data as for the Form. For editable
TableViews
DataContextList can be put into "dataItemMode". This then passes a
DataContext
that is also in dataItemMode as row data to the TableView. When in
dataItemMode, the DataContext returns a new DataContext bound to a
single field
from a get();
Now for the ListButton. A DataContextList can be the listData for the
ListButton. If the ListButton is part of a TableViewRowEditor then the
DataContextList will have to be in dataItemMode. When the editor is
invoked on
a TableView row it grabs the DataContext for the row and then uses
get() on
that DataContext which returns another DataContext bound to a single
field.
This is then passed to indexOf() on the ListButtons' ListData which is
different DataContextList. The DataContext from the TableView won't
be in the
ListButtons DataContextList, they may even have different database
tables as
sources. The DataContextList will match the DataContext given in the
call to
indexOf() to it's list of DataContexts based on the value defaultKey
references in each DataContext. So it doesn't care if the field
names are
different, just as long as the values are the same. All that just to
accommodate foreign keys ... sigh ...
What a convoluted mess, but it works ;-)