swingx
  1. swingx
  2. SWINGX-1418

Ensure that lookup for missing UI delegates returns null

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 1.6.2
    • Fix Version/s: 1.6.3
    • Component/s: Plaf
    • Labels:
      None

      Description

      A NPE can occur for SwingX based third party components in NetBeans visual editor.

      java.lang.NullPointerException
      at org.jdesktop.swingx.plaf.LookAndFeelAddons.getUI(LookAndFeelAddons.java:315)
      at de.javasoft.swing.JYLabel.updateUI(JYLabel.java:77)
      at javax.swing.JLabel.<init>(JLabel.java:145)
      at javax.swing.JLabel.<init>(JLabel.java:216)
      at de.javasoft.swing.JYLabel.<init>(JYLabel.java:49)
      at de.javasoft.swing.JYLabel.<init>(JYLabel.java:46)
      at de.javasoft.swing.plaf.basic.BasicJYTabbedPaneUI$5.<init>(BasicJYTabbedPaneUI.java:1029)
      at de.javasoft.swing.plaf.basic.BasicJYTabbedPaneUI.addTab(BasicJYTabbedPaneUI.java:1029)
      at de.javasoft.swing.plaf.basic.BasicJYTabbedPaneUI.access$17(BasicJYTabbedPaneUI.java:1021)
      at de.javasoft.swing.plaf.basic.BasicJYTabbedPaneUI$4.propertyChange(BasicJYTabbedPaneUI.java:809)
      at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:339)
      at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:276)
      at java.awt.Component.firePropertyChange(Component.java:8132)
      at de.javasoft.swing.JYTabbedPane.firePropertyChange(JYTabbedPane.java:1345)
      at de.javasoft.swing.JYTabbedPane.insertTab(JYTabbedPane.java:386)
      [catch] at org.netbeans.modules.form.layoutsupport.delegates.JTabbedPaneSupport.addComponentsToContainer(JTabbedPaneSupport.java:259)
      at org.netbeans.modules.form.layoutsupport.LayoutSupportManager.addComponentsToContainer(LayoutSupportManager.java:668)
      at org.netbeans.modules.form.VisualReplicator.addComponent(VisualReplicator.java:391)
      at org.netbeans.modules.form.VisualReplicator.updateAddedComponents(VisualReplicator.java:357)
      at org.netbeans.modules.form.FormDesigner$FormListener.run(FormDesigner.java:2414)
      at org.netbeans.modules.form.FormLAF$3.run(FormLAF.java:329)
      at org.openide.util.Mutex.doEventAccess(Mutex.java:1361)
      at org.openide.util.Mutex.readAccess(Mutex.java:271)
      at org.netbeans.modules.form.FormLAF.executeWithLookAndFeel(FormLAF.java:312)
      at org.netbeans.modules.form.FormDesigner$FormListener.processEvents(FormDesigner.java:2339)
      at org.netbeans.modules.form.FormDesigner$FormListener.formChanged(FormDesigner.java:2305)
      at org.netbeans.modules.form.FormModel.fireEvents(FormModel.java:1296)
      at org.netbeans.modules.form.FormModel.fireEventBatch(FormModel.java:1269)
      at org.netbeans.modules.form.FormModel.firePendingEvents(FormModel.java:1232)
      at org.netbeans.modules.form.FormModel.access$000(FormModel.java:68)
      at org.netbeans.modules.form.FormModel$2.run(FormModel.java:1212)
      at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
      at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:148)
      at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
      at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
      at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

      Fix proposal: simply add a ui null check
      if (ui == null)
      return null;
      String realUI = ui.getClass().getName();
      Class<?> realUIClass;
      try {
      ...

        Activity

        Hide
        Karl Schaefer added a comment -

        It doesn't bend the contract, it corrects it. Core returns null when a UI delegate cannot be found and JComponent is designed to work without a UI delegate. I think it is better behavior to return null and not throw an exception. Core force a giant System.err message by printing a stacktrace, but never actually bubbles up the exception, just returns null.

        Show
        Karl Schaefer added a comment - It doesn't bend the contract, it corrects it. Core returns null when a UI delegate cannot be found and JComponent is designed to work without a UI delegate. I think it is better behavior to return null and not throw an exception. Core force a giant System.err message by printing a stacktrace, but never actually bubbles up the exception, just returns null.
        Hide
        wzberger added a comment -

        To improve safety a null check has to be done - for me returning null is the correct behavior. The raising exception is thrown in core UIDefaults.getUI(), that's also OK.

        Related NetBeans issue: http://netbeans.org/bugzilla/show_bug.cgi?id=197521

        Show
        wzberger added a comment - To improve safety a null check has to be done - for me returning null is the correct behavior. The raising exception is thrown in core UIDefaults.getUI(), that's also OK. Related NetBeans issue: http://netbeans.org/bugzilla/show_bug.cgi?id=197521
        Hide
        kleopatra added a comment -

        interestingly you are right: core makes a lot of noice on any error in the lookup process, but ultimately returns null So SwingX should do the same.

        Me-thought that sure the addons method was incorrect in not guarding against null, but on detecting a null I would have thrown an exception like the rest of the method does if something goes wrong after it found a not-null ui.

        Hmm ... shouldn't we go the whole way and do the same as core if something goes wrong in the rest of the method: make noise and return null?

        Cheers
        Jeanette

        Show
        kleopatra added a comment - interestingly you are right: core makes a lot of noice on any error in the lookup process, but ultimately returns null So SwingX should do the same. Me-thought that sure the addons method was incorrect in not guarding against null, but on detecting a null I would have thrown an exception like the rest of the method does if something goes wrong after it found a not-null ui. Hmm ... shouldn't we go the whole way and do the same as core if something goes wrong in the rest of the method: make noise and return null? Cheers Jeanette
        Hide
        Karl Schaefer added a comment -

        Updated the title to capture the real issue. We need to ensure that we return null when the look up fails (making noise as appropriate).

        Show
        Karl Schaefer added a comment - Updated the title to capture the real issue. We need to ensure that we return null when the look up fails (making noise as appropriate).
        Hide
        Karl Schaefer added a comment -

        SWINGX-1418: Stop throwing exceptions and return null UI delegate when we cannot coerce a valid delegate. Instead of exceptions print to System.err (as core does). Use the same messages as core except for the case that core does not have.

        swingx-core/src/main/java/org/jdesktop/swingx/plaf/LookAndFeelAddons.java

        Committed revision 4004.

        Show
        Karl Schaefer added a comment - SWINGX-1418 : Stop throwing exceptions and return null UI delegate when we cannot coerce a valid delegate. Instead of exceptions print to System.err (as core does). Use the same messages as core except for the case that core does not have. swingx-core/src/main/java/org/jdesktop/swingx/plaf/LookAndFeelAddons.java Committed revision 4004.

          People

          • Assignee:
            Karl Schaefer
            Reporter:
            wzberger
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Time Tracking

              Estimated:
              Original Estimate - 5 minutes
              5m
              Remaining:
              Remaining Estimate - 5 minutes
              5m
              Logged:
              Time Spent - Not Specified
              Not Specified