JDK-4177727 : propagating disEnabled "event" to all children
  • Type: Enhancement
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.1.7,1.2.0,1.2.2,1.3.0
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS:
    generic,windows_95,windows_98,windows_nt generic,windows_95,windows_98,windows_nt
  • CPU: generic,x86
  • Submitted: 1998-09-30
  • Updated: 2017-05-19
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Description
Name: rk38400			Date: 09/30/98


The JTabbedPane and JPanel can contain many components
as children.  When the method setEnabled(false) is
called on the containers, the children of these
containers should be disabled as well.
(Review ID: 39637)
======================================================================

Name: krT82822			Date: 08/17/99


Calling the setEnabled method on any swing component does not 
disable/enable any of the chilren components of the parent.  
For example, if a JPanel contains a JButton, calling 
setEnabled(false) on the JPanel does not disable the JButton, 
but disables only the JPanel.  In awt, this method not only 
disables the Panel but any children components, which is the
expected behavior.
(Review ID: 94027)
======================================================================

Name: krT82822			Date: 11/22/99


Classic VM (build JDK-1.2.2-U, native threads, symcjit)


As explained in the report for Bug 1257395, containers do not recursively
invoke enable/disable on their children.  This results in a strange visual
appearance where components that are not active look like they are active.  I
believe this should be a platform independent problem, but I have given the
details of the particular setup I am using.  The code given below demonstrates
the issue and, by adding one line, can be made to show what I feel is the
correct behavior.  Although the bug is closed, the problem still exists, even
in the VM's that supposedly contain the fix.

Note that the problem is a visual one.  The children (in this case a button)
are in fact inactive.  However, they look the same as enable components.  On
the other hand, if containers were to recursively invoke disable on their
children, the correct visual cue would be given that the button is disabled.

// Testing whether Sun Bug 1257395 has been fixed (as reported).
// The bug is that containers do not recursively enable and disable
// their children.

import java.awt.*;
import java.awt.event.*;

public class Test extends Frame {
  public Test (String title) {
    super(title);
    init();
  }

  public void init () {
    addWindowListener(new WindowAdapter() {
      public void windowClosing (WindowEvent e) { System.exit(0); }
    });

    final JButton button = new JButton("Push Me!");
    button.addActionListener(new ActionListener() {
      public void actionPerformed (ActionEvent e) {
	// add the line below to see the difference between recursively
	// disabling all children vs. not doing so.
//  	button.setEnabled(!isEnabled());
	setEnabled(!isEnabled());
      }
    });

    add(button, BorderLayout.CENTER);
    pack();
    setVisible(true);
  }

  public static void main (String[] args) {
    new Test();
  }
}

------------

email from user 11/21/99:

You might want to consider (if it's possible), changing the category of
that bug (4177727) to AWT rather than Swing.  The problem appears more
often with the Swing classes, because it's worse when the container is a
lightweight component (ala JPanel), but it isn't really a Swing bug.
Fixing the problem in Swing would still leave an unresolved issue with
any other lightweight container.

I would add that with a slightly modified test case, the problem is not
limited to the visual appearance.  As I mentioned above, if the
container is a lightweight component, then the children are not disabled
at all (either visually or functionally).  I have included a new version
of my original test program which demonstrates this (and fixes a couple
of minor bugs that I had introduced while reducing the code size for
inclusion in my report).

As for your real question, yes, it would be fine if you added my
comments to the existing bug report rather than opening a new,
independent bug.


(Review ID: 98108)
======================================================================

Name: krT82822			Date: 12/26/99


C:\WINDOWS>java -version
java version "1.2.2"
Classic VM (build JDK-1.2.2-001, native threads, symcjit)


JMenuBar mbar = getJMenuBar();

mbar.setEnabled( !bShow); // Doesn't work! Menu bar is not disabled.

// but the following works
for ( int i = 0; i < mbar.getMenuCount(); i++ )
{
   mbar.getMenu(i).setEnabled( !bShow);
}

Comment to bug ID#4177732 implies this is not a bug and is, in fact,
known behavior of all JComponents.
However, one would be hard-pressed to find this "known" behavior documented,
whether in online documentation or in several advanced books on Swing.
(Review ID: 99343)
======================================================================

Comments
EVALUATION Contribution-Forum:https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?messageID=11928&forumID=1463
10-03-2006

WORK AROUND Name: rk38400 Date: 09/30/98 Override the JTabbedPane and JPanel's setEnabled() method. And disabled their children when that method is called ====================================================================== Name: krT82822 Date: 08/17/99 the only workaround would be to extend every swing component that extends JComponent and over-ride the setEnabled method. In that method call the setEnabled method of every child component. ex: public void setEnabled(boolean enabled) { super.setEnabled(enabled); Component[] components = getComponents(); if (components != null && components.length > 0) { int count = components.length; for (int i = 0; i < count; i++) components[i].setEnabled(enabled); } } (Review ID: 94027) ====================================================================== Name: krT82822 Date: 11/22/99 Write a utility function that calls enable/disable on a container's children. Use that function instead of the method. (Review ID: 98108) ======================================================================
17-09-2004

EVALUATION This is definitely a hole in the toolkit. disabling a container should automatically disable it's descendents, but it doesn't currently work that way, which requires programs to write lots of tree traversal code. We developing a proposal to fix this for merlin. amy.fowler@Eng 2000-03-09 As change of this scope would likely make more sense in awt, and then Swing would just pick it up. ###@###.### 2001-10-09
09-03-2000