Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4193267

JList getLastVisibleIndex

XMLWordPrintable

    • generic, x86
    • generic, windows_98



      Name: diC59631 Date: 11/27/98


      There appears to be a bug with the JList getListVisibleIndex()
      method which claims to return the index of the cell at the lower
      right corner or -1 if nothing in visible or the list is empty.

          

          This behaviour however fails if this viewable area of the JList
      is greater than the total size of the all the components in the
      list. Under such circumstance the JList reports -1 despite their
      still being a viewable cell on the screen.


            

            I include the following code. Its rather long Im afraid. The crucial
      method is updateCurrentlyViewedImages() which is the last method. If
      the JViewPort is larger than the JList contents the currentlyDisplayed
      array list will be cleared although it should have all of the cells in it.


      package phtfitdev;

      import javax.swing.*;
      import javax.swing.event.*;
      import java.util.*;
      import phtfitdev.datastructs.*;
      import java.lang.reflect.InvocationTargetException;


      /**
       * SyndromeThumbViewer.java <P>
       *
       * This class is essentially an embedded JList. It
       * is used to display the thumb nails of the syndromes which are
       * passed to it.
       * <P>
       * Compliant: 1.2
       * <P>
       * Created: Tue Sep 22 16:44:12 1998
       *
       * @author Phillip Lord
       * @version 1.0
       */

      public class SyndromeThumbViewer extends JScrollPane
        implements ImageObjectObserver, ChangeListener, ListDataListener
      {
        private JList list;
        private ChunkyListModel model;
        private Vector storedSyndromes;
        private static String noImageWarning = new String ( " :- No Images" );
        private InternalEventQueue qu;
        

        
        public SyndromeThumbViewer()
        {
          //Instantiate model and Jlist, with view
          model = new ChunkyListModel( );
          model.addListDataListener( this );
          list = new JList( model );
          getViewport().setView( list );
          getViewport().addChangeListener( this );
          //This Jlist uses a specialised cell rendered, which places both
          //the image and descript onto a JLabel. The thumbs are of a fixed
          //height, so the cells might as well be.
          list.setCellRenderer( new SyndromeThumbViewerCellRenderer( this ) );
          list.setFixedCellHeight( 100 );
          //This is set at an arbritarily wide value. It speeds up the processing
          //of the Jlist esp. when there are a lot of syndromes. It has the disadvantage
          //that the bottom scroll bar will reflect the arbritarily large width created
          //but this is not a particularly big disadvantage
          list.setFixedCellWidth( 2000 );
          //Instantiate the loader thread which loads Syndromes onto this
          //list
          qu = new InternalEventQueue();
        }

        public void addSyndrome( SyndromeDataObject syndrome )
        {
          qu.enqueue( new InternalEvent( this, "expandSyndrome", syndrome, "addSyndrome1" ) );
        }
        
        public void addSyndrome( SyndromeDataObject[] syndrome )
        {
          for ( int i = 0; i < syndrome.length; i++ ){
            addSyndrome( syndrome[ i ] );
          }
        }
        
        /**
         * Several methods use this method. It expands a SyndromeDataObject and returns
         * an ImageDataObject array, or a String. Its a pretty slow method (at least if
         * the ImageDataObject array has not been retrieved before) and is meant to be
         * used as the slow method in the internal event queue
         * @param synd the syndrome data object typed as an Object
         * @return an ImageDataObject or a String
         */
        Object expandSyndrome( Object synd )
        {
          SyndromeDataObject syndrome = (SyndromeDataObject)synd;
          //This bit requires lots of database access. V.Slow
          ImageDataObject[] imgs = syndrome.getImages();
          //If there are no images return the description
          if ( imgs == null ) return syndrome.getDescript() + noImageWarning;
          //If there are images return the array
          return imgs;
        }
        
        
        void addSyndrome1( Object images )
        {
          if ( images instanceof String ){
            model.addElement( (String)images );
            return;
          }
          model.addAll( (ImageDataObject[])images );
        }
        
       
        public void removeSyndrome( SyndromeDataObject[] syndrome )
        {
          for ( int i = 0; i < syndrome.length; i++ ){
            removeSyndrome( syndrome[ i ] );
          }
        }
        
        public void removeSyndrome( SyndromeDataObject syndrome )
        {
          qu.enqueue( new InternalEvent( this, "expandSyndrome", syndrome, "removeSyndrome1" ) );
        }

        void removeSyndrome1( Object images )
        {
          if ( images instanceof String ){
            model.removeElement( (String)images );
            return;
          }
          model.removeAll( (ImageDataObject[])images );
        }
        
        public void clearSyndromes()
        {
          qu.makeEmpty();
          model.clear();
        }

        
        public ImageDataObject[] getSelectedImages()
        {
          Object[] values = list.getSelectedValues();
          ImageDataObject[] img = new ImageDataObject[ values.length ];
          for ( int i = 0; i < img.length; i++ ){
            img[ i ] = (ImageDataObject)values[ i ];
          }
          
          return img;
        }
        
        
        /**
         * This method is predominately for debugging. It returns an object array
         * of the current contents of the JList, which will be either ImageDataObjects
         * or the description of the the syndrome
         * @return the contents
         */
        public Object[] getContents()
        {
          
          return model.toArray();
        }

        int count;
        
        public void imageObjectUpdate( ImageDataObject image )
        {
          //Get an array (arraylist is not sync'd )
          Object[] displaying = currentlyDisplayed.toArray();
          //Scan thru and repaint if necessary
          for ( int i = 0; i < displaying.length; i++ ){
            if ( displaying[ i ] == image ) {
      System.out.println (count++ + "Image has updated and repaint will occur" );
      repaint();
      return;
            }
          }
          System.out.println ( count++ + "Image has updated but repaint is not happening" );
          System.out.println( "Image updated is " + image.getSyndrome().getDescript() );
          // System.out.println( ((ImageDataObject)displaying[ 0 ]).getSyndrome().getDescript() );
          System.out.println ("displaying is " + displaying.length + " long" );
          if ( displaying.length > 0 ) System.out.println ( ((ImageDataObject)displaying[ 0 ]).getSyndrome().getDescript() );
        }

        //The next set of methods are used to maintain a list of the currently
        //viewed images, so that repaint can be called intelligently when
        //an Imageupdate occurs. It has the side effect that the currently viewed
        //images are referenced in an ArrayList which means that they wont
        //get GC'd in the mean time.
        
        //This method is called in response to changes in the JViewPort which
        //is being viewed, and is required byte the ChangeListener interface
        public void stateChanged( ChangeEvent e )
        {
          updateCurrentlyViewedImages();
        }
        
        //One of these methods occurs in response to changes in the list data model
        //and are required byte the ListDataListener interface
        public void contentsChanged( ListDataEvent e )
        {
          updateCurrentlyViewedImages();
        }
        
        public void intervalAdded( ListDataEvent e )
        {
          updateCurrentlyViewedImages();
        }
        
        public void intervalRemoved( ListDataEvent e )
        {
          updateCurrentlyViewedImages();
        }
        
        
        //Store the previous values here. Start off at -1 which means empty JList or
        //nothing viewable...
        private int firstVisibleIndex = -1;
        private int lastVisibleIndex = -1;
        private ArrayList currentlyDisplayed = new ArrayList();
        //Update the images currently on the screen
        void updateCurrentlyViewedImages()
        {
          
          //If selection has changed
          if ( list.getFirstVisibleIndex() != firstVisibleIndex || list.getLastVisibleIndex() != lastVisibleIndex ){
            //Store references to all of the ImageIcons, preventing them from GC'ing
            //as they are normally stored as Soft references
            
            //Clear the old images
            currentlyDisplayed.clear();
            int firstIndex = list.getFirstVisibleIndex();
            int lastIndex = list.getLastVisibleIndex();
            
            /*THIS BIT IS MY WORKAROUND FOR THE BUG
            
            if ( lastIndex == -1 && firstIndex != -1 ){
      lastIndex = model.getSize() - 1;
            }
            HERE ENDS THE WORKAROUND FOR THE BUG*/

            //There are still some images left
            if ( firstIndex != -1 ){
      System.out.println ("The currently displayed images are at indexes "
      + firstIndex + " and " + lastIndex );
      for ( int i = firstIndex ; i < lastIndex + 1; i++ ){
      currentlyDisplayed.add( model.elementAt( i ) );
      if ( model.elementAt( i ) instanceof ImageDataObject ){
      System.out.println ( ((ImageDataObject)model.elementAt( i )).getSyndrome().getDescript() );
      }

      }
            }
          }
        }
        
        
      } // SyndromeThumbViewer



           This bug appears to be to be identical to 4109697 however as that bug
      is reported as fixed it can't be.
      (Review ID: 43427)
      ======================================================================

            svioletsunw Scott Violet (Inactive)
            dindrigo Daniel Indrigo (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: