Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8259687

JTabbedPane.setComponentAt doesn't hide previously visible tab component

    XMLWordPrintable

Details

    • b10
    • generic
    • generic

    Description

      A DESCRIPTION OF THE PROBLEM :
      We have a simple change listener in a tabbed pane that we lazily fill with components. We do this by adding them with `setComponentAt` at the selected index if not already done.

      Now the problem is that while `setComponentAt` changes the visible component to the new component it does not actually hide the currently visible component if necessary. This doesn't result in a problem if the BasicTabbedPaneUI change listener hides it after our change listener is done (It will do so in layoutComponents), but in order for that to work it has to have the component as its internal visibleComponent and that is not necessarily the case. In our case for instance it is still null since it has never been layed out.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create a tabbed pane with a change listener that lazily loads its contents through setComponentAt in a ChangeListener and add any number of tabs to it. When programmatically selecting anything other than the first tab the problem will become apparent.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The appropriate tab would be selected and only its contents would be visible.
      ACTUAL -
      The appropriate tab is selected, but a mix of its contents and the first tabs content is shown.

      ---------- BEGIN SOURCE ----------
      package jtabbedpanebug;

      import javax.swing.JLabel;
      import javax.swing.JFrame;
      import javax.swing.JTabbedPane;

      /**
       * A simple demonstration of a bug in {@link JTabbedPane#setComponentAt(int, java.awt.Component)}
       *
       * The expected behaviour is that only the Second Contents are visible. But
       * since {@link JTabbedPane#setComponentAt(int, java.awt.Component)} does not hide
       * the First Contents that is intermixed. If opaque components were used the
       * first component would be shown, which is still not correct.
       */
      public class TabbedPaneBug {

      private static final int FIRST = 0;
      private static final int SECOND = 1;
      private static JLabel firstTab = new JLabel("First Contents");
      private static JLabel secondTab = new JLabel("Second Contents");

      public static void main(String... args) {
      JFrame window = new JFrame("Tabbed Pane Bug");
      JTabbedPane tabs = new JTabbedPane();
      tabs.addChangeListener((e) -> {
      if (tabs.getSelectedComponent() == null ) {
      switch (tabs.getSelectedIndex()) {
      case FIRST:
      tabs.setComponentAt(tabs.getSelectedIndex(), firstTab);
      break;
      case SECOND:
      tabs.setComponentAt(tabs.getSelectedIndex(), secondTab);
      break;
      default:
      }
      }
      });
      tabs.addTab("First", null);
      tabs.addTab("Second", null);
      // Work around the problem by adding the change listener at this point
      // That forces one visible component, since it will never call the
      // change listener for the default selection FIRST. During user
      // interaction the BasicTabbedPaneUI will jump in and correct the
      // inconsistent state.
      tabs.setSelectedIndex(SECOND);
      window.add(tabs);
      window.pack();
      window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      window.setVisible(true);
      }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Add the change listener just before the intended first component is selected. This doesn't actually solve the problem, but since there is no immediate possibility for two components to be visible it is sufficient. This workaround only works because BasicTabbedPaneUI will hide the component that JTabbedPane leaves visible.

      Attachments

        1. TabbedPaneBug.java
          2 kB
        2. Capture-1.JPG
          Capture-1.JPG
          70 kB
        3. Capture.JPG
          Capture.JPG
          14 kB

        Issue Links

          Activity

            People

              honkar Harshitha Onkar
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: