Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.lang.StackOverflowError during "fast" scrolling in OutlineView of a Netbeans Platform application #6835

Closed
MKuettner opened this issue Dec 12, 2023 · 7 comments · Fixed by #6948
Labels
kind:bug Bug report or fix Look and Feel Platform [ci] enable platform tests (platform/*) UI User Interface

Comments

@MKuettner
Copy link
Contributor

MKuettner commented Dec 12, 2023

Apache NetBeans version

Apache NetBeans 20 release candidate

What happened

In my Netbeans Platform based application there is a special dialog to select some kind of modules and sub-modules.
This dialog uses an OutlineView with one column and a CheckRenderDataProvider to display/manage selection.
The dialog looks like this:
grafik

If there are "many" nodes contained and if user scrolles really "fast" a java.lang.StackOverflowError occurs:

java.lang.StackOverflowError
	at org.netbeans.swing.etable.ETableColumn$ETableColumnHeaderRendererDelegate.getTableCellRendererComponent(ETableColumn.java:464)
	at org.openide.explorer.view.OutlineView$OutlineViewOutline$OutlineViewOutlineColumn$OutlineViewOutlineHeaderRenderer.getTableCellRendererComponent(OutlineView.java:2258)
	at org.netbeans.swing.etable.ETableHeader$ETableHeaderRenderer.getTableCellRendererComponent(ETableHeader.java:129)
	at org.netbeans.swing.etable.ETableColumn$ETableColumnHeaderRendererDelegate.getTableCellRendererComponent(ETableColumn.java:464)
	at org.openide.explorer.view.OutlineView$OutlineViewOutline$OutlineViewOutlineColumn$OutlineViewOutlineHeaderRenderer.getTableCellRendererComponent(OutlineView.java:2258)
	at org.netbeans.swing.etable.ETableHeader$ETableHeaderRenderer.getTableCellRendererComponent(ETableHeader.java:129)
	at org.netbeans.swing.etable.ETableColumn$ETableColumnHeaderRendererDelegate.getTableCellRendererComponent(ETableColumn.java:464)
	at org.openide.explorer.view.OutlineView$OutlineViewOutline$OutlineViewOutlineColumn$OutlineViewOutlineHeaderRenderer.getTableCellRendererComponent(OutlineView.java:2258)
	at org.netbeans.swing.etable.ETableHeader$ETableHeaderRenderer.getTableCellRendererComponent(ETableHeader.java:129)
	at org.netbeans.swing.etable.ETableColumn$ETableColumnHeaderRendererDelegate.getTableCellRendererComponent(ETableColumn.java:464)
	at org.openide.explorer.view.OutlineView$OutlineViewOutline$OutlineViewOutlineColumn$OutlineViewOutlineHeaderRenderer.getTableCellRendererComponent(OutlineView.java:2258)
	at org.netbeans.swing.etable.ETableHeader$ETableHeaderRenderer.getTableCellRendererComponent(ETableHeader.java:129)
	at org.netbeans.swing.etable.ETableColumn$ETableColumnHeaderRendererDelegate.getTableCellRendererComponent(ETableColumn.

It seems that this behavior has been introduced in Netbeans 18. All versions below do not show this error.

How to reproduce

Currently i have no idea how to reproduce this issue outside of my application.

Did this work correctly in an earlier version?

Apache NetBeans 17

Operating System

Unix

JDK

JDK 8, 17, 21

Apache NetBeans packaging

Apache NetBeans platform

Anything else

No response

Are you willing to submit a pull request?

Yes

@MKuettner MKuettner added kind:bug Bug report or fix needs:triage Requires attention from one of the committers labels Dec 12, 2023
@mbien
Copy link
Member

mbien commented Dec 12, 2023

It seems that this behavior has been introduced in Netbeans 18. All versions below do not show this error.

hmm. The loop is actually quite tight:

	at org.netbeans.swing.etable.ETableColumn$ETableColumnHeaderRendererDelegate.getTableCellRendererComponent(ETableColumn.java:464)
	at org.openide.explorer.view.OutlineView$OutlineViewOutline$OutlineViewOutlineColumn$OutlineViewOutlineHeaderRenderer.getTableCellRendererComponent(OutlineView.java:2258)
	at org.netbeans.swing.etable.ETableHeader$ETableHeaderRenderer.getTableCellRendererComponent(ETableHeader.java:129)

and there were no code changes in that area for quite a while.

my only explanation I can come up with right now is that:

protected TableCellRenderer createDefaultHeaderRenderer() {
TableCellRenderer orig = super.createDefaultHeaderRenderer();
OutlineViewOutlineHeaderRenderer ovohr = new OutlineViewOutlineHeaderRenderer(orig);
return ovohr;
}

is creating a cycle in some situations (fast scrolling?), when createDefaultHeaderRenderer is returning the wrong renderer?

Are you sure your application calls UI code on EDT? Some SwingUtilities.isEventDispatchThread() checks might help here.

@mbien mbien added UI User Interface and removed needs:triage Requires attention from one of the committers labels Dec 12, 2023
@MKuettner
Copy link
Contributor Author

The dialog is invoked from a NodeAction by calling DialogDisplayer.getDefault().notify(..descriptor..) so this should automatically run on EDT. I also added some SwingUtilities.isEventDispatchThread() check that are all pass.

This problem is also hard to debug since all the involved methods are called so many times without any problem.
I will try to extract some kind of test case.

@mbien mbien added the Platform [ci] enable platform tests (platform/*) label Dec 17, 2023
@hclerx
Copy link

hclerx commented Dec 19, 2023

We had the same problem and we found it is caused by FlatLaf. We fixed it by patching FlatTableHeaderUI as follows in the paint() method:

	// temporary use own default renderer if necessary
	FlatTableCellHeaderRenderer tempRenderer = null;
	if ( !header.getDefaultRenderer().getClass().getName().equals("org.netbeans.swing.etable.ETableHeader$ETableHeaderRenderer") ) {
		// temporary use own default renderer
		tempRenderer = new FlatTableCellHeaderRenderer( header.getDefaultRenderer() );
		header.setDefaultRenderer( tempRenderer );
	}

	// paint header
	super.paint( g, c );

	// restore default renderer
	if( tempRenderer != null ) {
		tempRenderer.reset();
		header.setDefaultRenderer( tempRenderer.delegate );
	}

@mbien
Copy link
Member

mbien commented Dec 19, 2023

@hclerx interesting, thanks for posting your workaround!

cc @DevCharly

DevCharly added a commit to JFormDesigner/FlatLaf that referenced this issue Dec 22, 2023
@DevCharly
Copy link
Member

I've reworked FlatLaf's FlatTableHeaderUI. (commit JFormDesigner/FlatLaf@4df34b3)
It no longer temporary replaces cell renderer while painting header, which seems to cause the stack overflow in NB.

Please try latest FlatLaf 3.3-SNAPSHOT: https://github.com/JFormDesigner/FlatLaf#snapshots

@MKuettner
Copy link
Contributor Author

This seems to fix the problem.
I'm not able to reproducte the StackOverFlowError anymore using FlatLaf 3.3-SNAPSHOT.

It would be great to have this version available with one of the next Netbeans releases.
Thanks!

@oyarzun
Copy link
Contributor

oyarzun commented Jan 11, 2024

@DevCharly do you have an ETA for when FlatLAF v3.3 will be released or maybe a v3.2.6 bug fix release? It would be nice to get this fix in NetBeans 21.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug Bug report or fix Look and Feel Platform [ci] enable platform tests (platform/*) UI User Interface
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants