JDK-4733624 : AccessibleIcon returns null on Accessible Children of JList (API change)
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.accessibility
  • Affected Version: 1.4.1
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_nt
  • CPU: x86
  • Submitted: 2002-08-19
  • Updated: 2017-05-16
  • Resolved: 2003-08-15
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
5.0 tigerFixed
Description

Name: jk109818			Date: 08/19/2002


FULL PRODUCT VERSION :

java version "1.3.1_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_04-b02)
Java HotSpot(TM) Client VM (build 1.3.1_04-b02, mixed mode)

AND

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

AND

java version "1.4.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-beta-b14)
Java HotSpot(TM) Client VM (build 1.4.1-beta-b14, mixed mode)


FULL OPERATING SYSTEM VERSION :
Windows NT 4.0

A DESCRIPTION OF THE PROBLEM :
getAccessibleIcon returns correctly on a JLabel but for an
AccessibleChild of a JList whose cell renderer is a JLabel
(with an ImageIcon) the getAccessibleIcon returns null.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.Create a JList whose cell renderer returns JLabels with Icon
2.Get AccessibleContext of JList, get AccessibleChild
3.Get AccessibleContext of Child and use to call
getAccesssibleIcon


EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected to get the AccessibleIcon.. just like if it was
called on the JLabel itself.
Actual: null

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Here's the test case:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.accessibility.*;
import javax.swing.border.*;



public class iconBug extends JPanel {

    static JFrame frame;
    public static int INITIAL_WIDTH = 400;
    public static int INITIAL_HEIGHT = 200;
    static int ITEMS = 5;
    ImageIcon images[];
    String desc[];
    JList listBox;
    //AccJList listBox;
    DefaultListModel listModel;

    // Fast Food
    public ImageIcon burger    = new
ImageIcon("d:/svk14/images/burger.gif","this burger");
    public ImageIcon fries     = new ImageIcon("images/fries.gif","fries");
    public ImageIcon softdrink = new ImageIcon("images/softdrink.gif","soft drink");
    public ImageIcon hotdog    = new ImageIcon("images/hotdog.gif","hot dog");
    public ImageIcon pizza     = new ImageIcon("images/pizza.gif","pizza");


    public iconBug() {


       images = new ImageIcon[ITEMS];
       desc = new String[ITEMS];



       int i = 0;
       // 5 - FastFood
       images[i] = burger;     desc[i++] = "Burger";
       images[i] = fries;      desc[i++] = "Fries";
       images[i] = softdrink;  desc[i++] = "Cola";
       images[i] = pizza;      desc[i++] = "Pizza";
       images[i] = hotdog;     desc[i++] = "Hotdog";

        // Create the list
        listModel = new DefaultListModel();
        listBox = new JList(listModel);
        //listBox = new AccJList(listModel);
        for(int j = 0; j < ITEMS; j++) {
                 listModel.addElement(new Integer(j));
             }
        listBox.setModel(listModel);

        listBox.setCellRenderer(new TestCellRenderer(listBox));
        AccessibleContext acL = listBox.getAccessibleContext();
        AccessibleContext acLc = acL.getAccessibleChild(1).getAccessibleContext();
        System.out.println("Icon " + acLc.getAccessibleIcon());


        add(listBox);



    }
    class TestCellRenderer extends DefaultListCellRenderer
    {
   TestCellRenderer(JList listBox) {
       super();

   }

   public Component getListCellRendererComponent(
            JList list,
            Object value,
            int modelIndex,
            boolean isSelected,
            boolean cellHasFocus)
        {
       int index = ((Integer)value).intValue();
       String text= desc[index];

       Component ccx = super.getListCellRendererComponent(list, text, index,
isSelected, cellHasFocus);
       setIcon(images[index]);
       return ccx;
   }
    }

    public static void main(String[] args) {

        WindowListener l = new WindowAdapter()
        {
                public void windowClosing(WindowEvent e) {System.exit(0);}
        };
        frame = new JFrame("Old");
        frame.addWindowListener(l);
        frame.getContentPane().add("Center", new iconBug());
        frame.setSize(INITIAL_WIDTH, INITIAL_HEIGHT);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        frame.setLocation(screenSize.width/2 - INITIAL_WIDTH/2,
                screenSize.height/2 - INITIAL_HEIGHT/2);
        frame.pack();
        frame.setVisible(true);
    }
}
-------------------------------------------
Here's the solutions... the wrapper to fix
import java.awt.*;
import javax.swing.*;
import javax.accessibility.*;
public class AccJList extends JList
{
   public AccJList(ListModel dataModel)
   {
      super(dataModel);
   }
/////////////////
// Accessibility support
////////////////

   public AccessibleContext getAccessibleContext()
   {
      if (accessibleContext == null)
      {
         accessibleContext = new AccessibleAccJList();
      }
      return accessibleContext;
   }

   protected class AccessibleAccJList extends AccessibleJList
   {
      public Accessible getAccessibleAt(Point p) {
          int i = locationToIndex(p);
          if (i >= 0) {
              return new AccessibleAccJListChild(AccJList.this, i);
          } else {
              return null;
          }
      }
      public Accessible getAccessibleChild(int i) {
          if (i >= getModel().getSize()) {
              return null;
          } else {
              return new AccessibleAccJListChild(AccJList.this, i);
          }
      }
      protected class AccessibleAccJListChild extends
AccessibleJList.AccessibleJListChild
      {

         public AccessibleAccJListChild(JList parent, int indexInParent)
         {
            super(parent,indexInParent);
         }

         public AccessibleIcon[] getAccessibleIcon()
            {
            AccessibleIcon[] iconArr = null;
            ListModel listModel = getModel();
            ListCellRenderer cellRenderer = getCellRenderer();
            if ((listModel != null)
                && cellRenderer != null) {
               int indParent = getAccessibleIndexInParent();
               Object value = listModel.getElementAt(indParent);
               boolean isSelected = isSelectedIndex(indParent);
               boolean isFocussed = hasFocus()
                                    && (indParent == getLeadSelectionIndex());
               Component c = cellRenderer.getListCellRendererComponent(
                                                                     
(JList)AccJList.this,
                                                                      value,
                                                                      indParent,
                                                                      isSelected,
                                                                      isFocussed);
               if (c instanceof Accessible) {
                  iconArr =
((Accessible)c).getAccessibleContext().getAccessibleIcon();
               }
            }
            // end getAccessibleIcon
            return iconArr;

         }
      }
   }

}

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

CUSTOMER WORKAROUND :
Wrap the AccessibleJList and the AccessibleJListChild to return
the AccessibleIcon.. see code AccJList above.
(Review ID: 160838) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger FIXED IN: tiger INTEGRATED IN: tiger tiger-b16
2004-06-14

EVALUATION Committing to Tiger since this requires an API change to implement the AccessibleIcon interface on JList.AccessibleJList. ###@###.### 2002-11-05 This bug will not be fixed in Tiger since it requires an API change and such changes are not being approved unless there is sufficient business justification. This bug does not cause a significant accessibility problem because it only effects icon information for a JList. ###@###.### 2003-03-26 This bug is desirable to fix in Tiger. Committing to Tiger. ###@###.### 2003-04-16
2003-03-26