United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4304100 Swing components don't repaint properly
JDK-4304100 : Swing components don't repaint properly

Details
Type:
Bug
Submit Date:
2000-01-12
Status:
Resolved
Updated Date:
2000-03-22
Project Name:
JDK
Resolved Date:
2000-03-22
Component:
client-libs
OS:
solaris_2.6,windows_nt,generic
Sub-Component:
javax.swing
CPU:
x86,sparc,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.2.1,1.2.1_04,1.2.2,1.3.0,1.3.0_02,1.4.0
Fixed Versions:
1.4.0 (beta)

Related Reports
Duplicate:
Duplicate:
Duplicate:
Relates:

Sub Tasks

Description

Name: krT82822			Date: 01/11/2000


12/19/99  -- NOT reproducible with 1.2 FCS, 1.2.1 or 1.2.2 reference (green threads versions) under Solaris 2.7, so must be Solaris (native threads) specific?
-------------
java version "1.2.1"
Solaris VM (build Solaris_JDK_1.2.1_04, native threads, sunwjit)

I have a test case where a component acts like a tree branch, listening for
mouse clicks and alternating between an open and closed state.  An open state
displays components underneath.

However, when the branch is opened the tree doesn't appear until the window is
resized.  Once the window is resized, you can open and close the tree to your
heart's content, until you resize while the tree is closed.  Then you're back
to the original behavior.

Here's the code I'm working with:

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

public class RepaintBug extends JFrame {
   public static void main(String args[]){
      new RepaintBug().show();
   }

   public RepaintBug(){
      setSize(640, 480);
      Container cp = getContentPane();
      cp.setLayout(new BorderLayout());
      FlowTreeNode ftn = new FlowTreeNode();
      ftn.addChild(new Label("Child 1"));
      ftn.addChild(new Label("Child 2"));
      ftn.addChild(new Label("Child 3"));
      ftn.addChild(new Label("Child 4"));
      ftn.addChild(new Label("Child 5"));
      cp.add(ftn, BorderLayout.CENTER);
   }
}


class FlowTreeNode extends JPanel {
   boolean isOpen = false;
   ImageIcon open = new ImageIcon(getClass().getResource("opennode.gif"));
   ImageIcon closed = new ImageIcon(getClass().getResource("closednode.gif"));
   Box expandedNode;
   JLabel button;
   public FlowTreeNode(){
      super(new BorderLayout());
      button = new JLabel(closed);
      add(button, BorderLayout.CENTER);
      expandedNode = Box.createVerticalBox();
      expandedNode.setVisible(false);
      add(expandedNode, BorderLayout.SOUTH);
      button.addMouseListener(new MouseAdapter(){
         public void mouseClicked(MouseEvent e){
            if(!e.isPopupTrigger()){
               if(isOpen){
                  button.setIcon(closed);
                  expandedNode.setVisible(false);
                  isOpen = false;
               }
               else{
                  button.setIcon(open);
                  expandedNode.setVisible(true);
                  isOpen = true;
               }
            }
         }
      });
   }

   public Component addChild(Component comp){
      return expandedNode.add(comp);
   }
}
(Review ID: 99108) 
======================================================================

                                    

Comments
WORK AROUND



Name: krT82822			Date: 01/11/2000


None known...  tried lots of stuff including invalidating components and
attempting to force repaints.
======================================================================

after the line

expandedNode.setVisible(true)

in the Listener, add the following line:

validate();

That will cause the FlowTreeNode to be validated after the setVisible,
which results in it asking the current layout manager to layout the
components inside it, thus repainting the expandedNode component.

-stephen.bohne@East 2000-01-18
                                     
2000-01-18
EVALUATION

This behavior (which I'm not yet sure is a bug) is due to the fact that the
swing Box class does not extend JComponent but instead directly extends Container.

When a normal Swing component (that extends JComponent) is setVisible, it
is marked as invalid and is added to the RepaintManager invalid component
list.  When a paint occurs, the component is validated which causes the
layout manager to layout the component, and it gets sized and painted.

With the Box class (or any component that doesn't extend JComponent), when
the Box is setVisible, the Box is never added to the Swing invalid component 
list because it doesn't extend JComponent, and the layout manager is never 
called to layout the Box.  The Box and its subcomponents never get painted.

In AWT, it was up to the programmer to call validate() when a subcomponent of
an already-showing Window was added or setVisible.  It needs to be investigated
whether this is actually a bug;  should Box, being in the Swing package, behave
like Swing components that extend JComponent?  Or should it act like AWT
components since it does not extend JComponent and cannot be (easily) made compatible with the Swing RepaintManager?

-stephen.bohne@East 2000-01-18

I was able to reproduce this with JavaSoft reference 1.2.2 and 1.3beta, this
should be a more general java category bug (not java_solaris).

-stephen.bohne@East 2000-01-19

A long time ago we had a discussion on whether or not Box needed to be a 
JComponent and decided not to change it since one could easily add BoxLayout
to a JComponent and have the desired functionality.  This report shows a
motiviation to change Box however, as one gets lured into a repaint problem
using Box in Swing, when box is a part of Swing.  Box will be upgraded to
be a JComponent.
timothy.prinzing@eng 2000-03-10
                                     
2000-03-10
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
generic

FIXED IN:
merlin-beta

INTEGRATED IN:
merlin-beta


                                     
2004-06-14



Hardware and Software, Engineered to Work Together