JDK-4546123 : CardLayout becomes unusable after deleting an element
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_98,windows_2000
  • CPU: x86
  • Submitted: 2001-12-04
  • Updated: 2002-10-22
  • Resolved: 2002-09-20
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availabitlity Release.

To download the current JDK release, click here.
Other
1.4.0_03 03Fixed
Related Reports
Relates :  
Relates :  
Description

Name: gm110360			Date: 12/03/2001


java version "1.4.0-beta3"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta3-b84)
Java HotSpot(TM) Client VM (build 1.4.0-beta3-b84, mixed mode)


The cardlayout to me is the way that I would create a layout like I have in MS
word whereby I might have lots of word documents open but only one is showing.
When I am done with one I should be able to close it and remove it from the
cardlayout.  However it seems to me that the cardlayout becomes very unstable
after I delete an element from it.  This is not right at all.  I have included
the code below.  I took it from a bug report that is similar, but has to do
with an un-related cardlayout issue.  I looked at the cardlayout source and I
am really lost as to why this code would cause such a bad result.

Run the program and select a few different oanels from the second menu.  Make
sure your last choce is the red panel.  Then click close.  At that point the
program removes the redpanel from the cardlayout, but no other panels are
selectable from the second drop down.

Please help or advise.

Thanks
Jim Tyrrell

Source code below:
import java.awt.*;
import java.awt.event.*;
import java.awt.AWTEvent;


public class TestFrame extends Frame implements ActionListener
{
        public Panel            aPanel;
        public TestPanel        pageRed;
        public TestPanel        pageGreen;
        public TestPanel        pageBlue;
        public String           currentSelection = "";

        public MenuItem mi;
        public CardLayout       theCardLayout;


        public TestFrame()
        {
                super( "Test Frame - from Novell, Inc." );

                setBackground( Color.black );
                setLayout( new BorderLayout(5,5) );

                enableEvents( AWTEvent.WINDOW_EVENT_MASK );

                MenuBar mb = new MenuBar();

                Menu fileMenu = new Menu( "File" );
                Menu pageMenu = new Menu( "Pages" );

                mi = new MenuItem( "Exit" );
                mi.addActionListener( this );
                fileMenu.add( mi );

                mi = new MenuItem("Close");
                mi.addActionListener( this );
                fileMenu.add( mi );

                mi = new MenuItem( "Red" );
                mi.addActionListener( this );
                pageMenu.add( mi );

                mi = new MenuItem( "Green" );
                mi.addActionListener( this );
                pageMenu.add( mi );

                mi = new MenuItem( "Blue" );
                mi.addActionListener( this );
                pageMenu.add( mi );

                mb.add( fileMenu );
                mb.add( pageMenu );

                setMenuBar( mb );

                aPanel = new Panel();
                theCardLayout = new CardLayout();

                aPanel.setLayout( theCardLayout );

                pageRed = new TestPanel( "PageRed", Color.red );
                pageGreen = new TestPanel( "PageGreen", Color.green );
                pageBlue = new TestPanel( "PageBlue", Color.blue );

                aPanel.add( "PageRed", pageRed );
                aPanel.add( "PageGreen", pageGreen );
                aPanel.add( "PageBlue", pageBlue );

                add( "Center", aPanel );
                setSize( getPreferredSize());
        }


        public Insets getInsets()
        {
                return new Insets( 47, 9, 9, 9 );
        }


        public void actionPerformed( ActionEvent e )
        {
                if( e.getActionCommand().equals( "Exit" ))
                {
                        dispose();
                        System.exit(0);
                }
                else if( e.getActionCommand().equals( "Red" ))
                {
                        theCardLayout.show( aPanel, "PageRed" );
                        currentSelection = "PageRed";
                }
                else if( e.getActionCommand().equals( "Green" ))
                {
                        theCardLayout.show( aPanel, "PageGreen" );
                }
                else if( e.getActionCommand().equals( "Blue" ))
                {
                        theCardLayout.show( aPanel, "PageBlue" );
                }else if (e.getActionCommand().equals( "Close" )){
                    System.out.println("Closeing");

                    if(currentSelection.equals("PageRed"))
                    {
                        System.out.println("Remove page red");
                        theCardLayout.removeLayoutComponent(pageRed);
                    }
                }

        }

        protected void processEvent( AWTEvent event )
        {
                if( event instanceof WindowEvent )
                {
                        if( event.getID() == WindowEvent.WINDOW_CLOSING )
                        {
                                dispose();
                                System.exit(0);
                        }
                }

                super.processEvent( event );
        }

        static public void main( String[] args )
        {
                TestFrame       theTestFrame = new TestFrame();
                theTestFrame.setVisible( true );
        }
}

import java.awt.*;
import java.awt.event.*;
import java.awt.AWTEvent;
import javax.swing.*;


class TestPanel extends JPanel
{
        private String                  pageName;

      TestPanel(String pageName, Color color)
      {
         setBackground(color);
         add( new JLabel(pageName));
      }
}
(Review ID: 135826) 
======================================================================
I have another sample program.

1. Reproducing

 1) Compile the attached Test.java
 2) Invoke "java test"
    -> you will see green window.
 3) Click "remove red and show blue" button.
    -> The color stay green.

  CORRECT behavior:
    The color changes to blue.


2. configration
  MPU : Pentium  IV 1.4 [GHz]
  Mem : 384 [MB]
  OS  : Windows 2000 (SP2, Japanese)

2002-04-25
==========================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.4.0_03 1.4.1_02 mantis FIXED IN: 1.4.0_03 1.4.1_02 mantis INTEGRATED IN: 1.4.0_03 1.4.1_02 mantis
2004-08-24

WORK AROUND Name: gm110360 Date: 12/03/2001 None found. Breaks in all L&F's ======================================================================
2004-08-24

EVALUATION Commit to fix in Tiger (regression). ###@###.### 2002-05-28 Name: osR10079 Date: 09/04/2002 This bug is part of 4362381 (Once the remove button had press, next item from the list should show.) which was not fixed. To fix it we should call next() method before removing current card from CardLayou. ###@###.### 2002-09-04 ======================================================================
2002-09-04

SUGGESTED FIX --- CardLayout.java Fri Aug 16 05:23:20 2002 *************** *** 219,236 **** */ public void removeLayoutComponent(Component comp) { synchronized (comp.getTreeLock()) { ! for (int i = 0; i < vector.size(); i++) { ! if (((Card)vector.get(i)).comp == comp) { ! vector.remove(i); ! break; ! } ! } ! ! if (vector.isEmpty()) { ! currentCard = 0; ! } else { ! currentCard %= vector.size(); ! } } } --- 219,238 ---- */ public void removeLayoutComponent(Component comp) { synchronized (comp.getTreeLock()) { ! if (comp.visible) { ! next(comp.parent); ! } ! int n = -1; ! for (int i = 0; i < vector.size(); i++) { ! if (((Card)vector.get(i)).comp == comp) { ! vector.remove(i); ! n = i; ! break; ! } ! } ! if(n < currentCard) { ! currentCard--; ! } } } ###@###.### 2002-08-21 ------------------------------------------------------------------------
2002-08-21