Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4304100
Votes 0
Synopsis Swing components don't repaint properly
Category java:classes_swing
Reported Against 1.2.2 , merlin , 1.2.1_04
Release Fixed 1.4(merlin-beta)
State 10-Fix Delivered, bug
Priority: 3-Medium
Related Bugs 4273647 , 4305636 , 4348072
Submit Date 12-JAN-2000
Description




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) 
======================================================================
Work Around




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.

- xxxxx@xxxxx  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?

- xxxxx@xxxxx  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).

- xxxxx@xxxxx  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.
 xxxxx@xxxxx  2000-03-10
Comments
  
  Include a link with my name & email   

Submitted On 13-JAN-2001
rameshbabur
I send my comments later



PLEASE NOTE: JDK6 is formerly known as Project Mustang