Skip to main content

Swing / SceneGraph problem 0.4.1

3 replies [Last post]
mortennobel
Offline
Joined: 2004-11-03

I have a problem with an application that contains some swing elements on the West side and a JSGPanel in the Center (using a border layout).

In the swing part of the application I have a button that removes and adds some swing components (totally unrelated to the JSGPanel).
During this action, I get a strange stack trace (attached in the end of this post).

To me it seems like SG have attached a focus listener to my Swing components, and the error comes from a bug in that focus listener.

If anybody has an idea of what goes wrong, please let me know.

- Morten Nobel

Exception in thread "AWT-EventQueue-2" java.lang.IndexOutOfBoundsException: Index: -1
at java.util.Collections$EmptyList.get(Collections.java:2970)
at com.sun.scenario.scenegraph.FocusHandler.getLastLeaf(FocusHandler.java:78)
at com.sun.scenario.scenegraph.FocusHandler.getLastLeaf(FocusHandler.java:78)
at com.sun.scenario.scenegraph.FocusHandler.getLastLeaf(FocusHandler.java:78)
at com.sun.scenario.scenegraph.FocusHandler.access$300(FocusHandler.java:47)
at com.sun.scenario.scenegraph.FocusHandler$SGTreeIterator.getNextNode(FocusHandler.java:221)
at com.sun.scenario.scenegraph.FocusHandler$SGTreeIterator.doNext(FocusHandler.java:188)
at com.sun.scenario.scenegraph.FocusHandler$SGTreeIterator.hasNext(FocusHandler.java:155)
at com.sun.scenario.scenegraph.FocusHandler$SGFocusTraversalPolicy.getComponent(FocusHandler.java:369)
at com.sun.scenario.scenegraph.FocusHandler$SGFocusTraversalPolicy.getLastComponent(FocusHandler.java:388)
at javax.swing.SortingFocusTraversalPolicy.getLastComponent(SortingFocusTraversalPolicy.java:491)
at javax.swing.LayoutFocusTraversalPolicy.getLastComponent(LayoutFocusTraversalPolicy.java:172)
at java.awt.ContainerOrderFocusTraversalPolicy.getComponentAfter(ContainerOrderFocusTraversalPolicy.java:137)
at java.awt.ContainerOrderFocusTraversalPolicy.getComponentAfter(ContainerOrderFocusTraversalPolicy.java:147)
at java.awt.ContainerOrderFocusTraversalPolicy.getComponentAfter(ContainerOrderFocusTraversalPolicy.java:91)
at java.awt.Component.preNextFocusHelper(Component.java:7451)
at java.awt.Component.nextFocusHelper(Component.java:7430)
at java.awt.Container.nextFocusHelper(Container.java:3161)
at java.awt.Component.removeNotify(Component.java:6560)
at java.awt.Container.removeNotify(Container.java:2625)
at javax.swing.JComponent.removeNotify(JComponent.java:4699)
at javax.swing.AbstractButton.removeNotify(AbstractButton.java:1011)
at javax.swing.JButton.removeNotify(JButton.java:217)
at java.awt.Container.removeNotify(Container.java:2619)
at javax.swing.JComponent.removeNotify(JComponent.java:4699)
at java.awt.Container.remove(Container.java:1136)
at java.awt.Container.remove(Container.java:1203)
at com.Lefty.updateComponents(ColorSelectorPanel.java:204)
at com.Lefty.actionPerformed(ColorSelectorPanel.java:199)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6100)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
at java.awt.Component.processEvent(Component.java:5865)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4472)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4302)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
at java.awt.Container.dispatchEventImpl(Container.java:2102)
at java.awt.Component.dispatchEvent(Component.java:4302)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at com.sun.scenario.scenegraph.SGEventQueue.dispatchEvent(SGEventQueue.java:219)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
idk
Offline
Joined: 2005-01-12

I checked in a fix for this bug into the repository (rev 82).

> To me it seems like SG have attached a focus listener to my Swing components, and the error comes from a bug in that focus listener.

SG does not attach a focus listener. We have custom FocusTraversalPolicy set on JSGPanel which defines focus traversal order for the JSGPanel.

> However I still would like to know why this code in invoked, when I'm removing components outside JSGPanel.

When component is added or removed focus may need to be transferred. Next focused component may be an JSGPanel.
AWT focus traversal code checks where in JSGPanel focus would go to.

-Igor

mortennobel
Offline
Joined: 2004-11-03

After a little investigation thee seems to be a bug in the FocusHandler class.

I have modified the getLastLeaf method to the following (adding 2 lines of code). (I'm a bit unsure if this break anything, but it seems to work)
However I still would like to know why this code in invoked, when I'm removing components outside JSGPanel.

private static SGNode getLastLeaf(SGNode top) {
SGNode node = top;
if (top instanceof SGParent) {
SGParent group = (SGParent) top;
List children = group.getChildren();
[b] if (children.size()>0){ // ADDED - if children exist[/b]
int childIndex = children.size() - 1;
node = getLastLeaf(children.get(childIndex));
[b] } // ADDED[/b]
}
return node;
}

idk
Offline
Joined: 2005-01-12

Hi,

Thank you for the report.
Let me look into this.

-Igor