From: Michael Rauscher on
Felix Natter wrote:
> The problem is definitely that the data table is wrapped in a
> JScrollPane, and, as Noel pointed out, that the footer JTable
> is _below_ the data table.

My theory:

It's a matter of sharing the TCM in conjunction with the layout
procedure and the fact that two nested validation roots are being used.

JTable and JTableHeader register themself as TCMListener and call
revalidate whenever column margins change. JTable acts as layout manager
and changes the column margins.

To prevent endless loops, revalidate doesn't do anything if the
validation root is already known as being invalid to the repaint
manager. By having more validation roots, one can break this rule
(revalidate the component which is under the 'other' validation root).

If the JScrollPane (= validation root) gets validated first, it will be
removed from the list of invalid components. If then the footerTable
gets validated, it sets the column widths. The TCM notifies the
dataTable about the changes and dataTable calls revalidate. This causes
the JScrollPane (as it is the validation root of the JTable) to be added
to the list of invalid components again.

If footerTable gets validated first, it sets the column widths and the
TCM also notifies the dataTable about the changes. But in this case the
following revalidate doesn't do anything because the JScrollPane is
already on the list of invalid components.

Bye
Michael
From: Felix Natter on
Michael Rauscher <michlmann(a)gmx.de> writes:

> Felix Natter wrote:
>> The problem is definitely that the data table is wrapped in a
>> JScrollPane, and, as Noel pointed out, that the footer JTable
>> is _below_ the data table.
>
> My theory:
>
> It's a matter of sharing the TCM in conjunction with the layout procedure
> and the fact that two nested validation roots are being used.
>
> JTable and JTableHeader register themself as TCMListener and call
> revalidate whenever column margins change. JTable acts as layout manager
> and changes the column margins.
>
> To prevent endless loops, revalidate doesn't do anything if the validation
> root is already known as being invalid to the repaint manager. By having
> more validation roots, one can break this rule (revalidate the component
> which is under the 'other' validation root).
>
> If the JScrollPane (= validation root) gets validated first, it will be
> removed from the list of invalid components. If then the footerTable gets
> validated, it sets the column widths. The TCM notifies the dataTable about
> the changes and dataTable calls revalidate. This causes the JScrollPane (as
> it is the validation root of the JTable) to be added to the list of invalid
> components again.
>
> If footerTable gets validated first, it sets the column widths and the TCM
> also notifies the dataTable about the changes. But in this case the
> following revalidate doesn't do anything because the JScrollPane is already
> on the list of invalid components.

hello Michael,

thanks for the analysis, this sounds feasible. Can you think of a way
to get arounds this, like modifying the validation order?

Is there a way to get the source that was responsible for marking
a component dirty? Then we could override the corresponding method...

How about subclassing the TCM so that it only emits a message to the
listeners when something (like columns swapped or pixel widths) actually
changed or the surrounding BoxLayout changed?

Can somebody think of another workaround?

I'd rather not like to rewrite all of this using JXTable (which _might_
work better)...

Thanks a lot!
--
Felix Natter
From: Noel on
On Nov 4, 1:29 pm, Felix Natter <felix.nat...(a)smail.inf.fh-brs.de>
wrote:
> Michael Rauscher <michlm...(a)gmx.de> writes:
>
> > My theory:
>
> > It's a matter of sharing the TCM in conjunction with the layout procedure
> > and the fact that two nested validation roots are being used.
>
> > JTable and JTableHeader register themself as TCMListener and call
> > revalidate whenever column margins change. JTable acts as layout manager
> > and changes the column margins.
>
> > To prevent endless loops, revalidate doesn't do anything if the validation
> > root is already known as being invalid to the repaint manager. By having
> > more validation roots, one can break this rule (revalidate the component
> > which is under the 'other' validation root).
>
> > [truncated]
>
> hello Michael,
>
> [...]
>
> How about subclassing the TCM so that it only emits a message to the
> listeners when something (like columns swapped or pixel widths) actually
> changed or the surrounding BoxLayout changed?

That actually sounds considerably more complex than reimplementing
with JXTable.

> Can somebody think of another workaround?

I thought to use GridBagLayout instead, adding the footer table to the
content pane as the second component, and adjusting
GridBagConstraints.gridy values to have the table appear below the
scrollable table:

--------- start ----------

private void initLayout() {
//Box container = new Box(BoxLayout.Y_AXIS);
Container container = getContentPane();
container.setLayout(new GridBagLayout());

TableModel dataModel = new MyTableModel();
TableModel headerModel = new HeaderFooterModel();
TableModel footerModel = new HeaderFooterModel();

JTable table = new JTable(dataModel);
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
table.setAutoCreateRowSorter(true);

JTable header = new JTable(headerModel,
table.getColumnModel());
header.setRowSelectionAllowed(false);

JTable footer = new JTable(footerModel,
table.getColumnModel());
footer.setRowSelectionAllowed(false);

GridBagConstraints cons = new GridBagConstraints();
cons.gridx = 0;
cons.fill = GridBagConstraints.BOTH;

cons.gridy = 0;
container.add(header, cons);

cons.gridy = 2;
container.add(footer, cons);

cons.gridy = 1;
cons.weightx = 1;
cons.weighty = 1;
container.add(new JScrollPane(table), cons);
//getContentPane().add(container);

---------- end ----------

I don't know how portable this technique is. It's functioning on
Windows XP with JRE 1.6. It solves the getValue spin for me, but
resizing still does not work.
From: Noel on
On Nov 4, 2:10 pm, Noel <prosthetic_conscien...(a)yahoo.com> wrote:
>
> I don't know how portable this technique is.  It's functioning on
> Windows XP with JRE 1.6.  It solves the getValue spin for me, but
> resizing still does not work.

That would be a Sun JRE 1.6.
From: Michael Rauscher on
Felix Natter wrote:
> Can you think of a way
> to get arounds this, like modifying the validation order?

If my theory is true, the following should work

tblSP = new JScrollPane(dataTable) {
public boolean isValidateRoot() {
return false;
}
};


Bye
Michael