Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / January 2005

Tip: Looking for answers? Try searching our database.

cellHasFocus argument is dead?

Thread view: 
hiwa - 11 Jan 2005 08:25 GMT
When we use JList component as is, mouse hovering over a cell
component doesn't change the cell color. Selection by clicking
can change the cell color to the selection color.

When we customize the ListCellRenderer to use cellHasFocus
argument in the getListCellRendererComponent() method:

if (isSelected){
 //set selection color : It's OK
}
else if (cellHasFocus){
 //set another color ... no effect!
}
else{
 //no-selection, no-focus color : It's OK
}

Still, focusing into a cell doesn't change the cell color both on Linux and Windows.

Is there a way to change cell color with focusing of MY
definition, that is mouse entering into the cell?
Christian Kaufhold - 11 Jan 2005 19:14 GMT
> When we use JList component as is, mouse hovering over a cell
> component doesn't change the cell color. Selection by clicking
[quoted text clipped - 17 lines]
> Is there a way to change cell color with focusing of MY
> definition, that is mouse entering into the cell?

You cannot just redefine what the "cellHasFocus" argument means.

Here is my attempt at a hover implementation:

import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;

public class Hover
{
   private static class Listener
    extends MouseInputAdapter
    implements ListDataListener, PropertyChangeListener, ComponentListener, HierarchyListener, HierarchyBoundsListener, Runnable
   {
    private JList list;

    private int hoverIndex;

    private boolean enabled, running;

    private Point lastLocation;

    public Listener(JList l)
    {
       list = l;

       hoverIndex = -1;
    }

    public void setEnabled(boolean value)
    {
       if (enabled == value)
        return;

       enabled = value;

       if (enabled)
           {
        list.addMouseListener(this);
        list.addMouseMotionListener(this);
        list.addPropertyChangeListener(this);
        list.getModel().addListDataListener(this);

        list.addComponentListener(this);
        list.addHierarchyListener(this);
        list.addHierarchyBoundsListener(this);

        list.putClientProperty(HOVER, this);
       }
       else
           {
        repaint(hoverIndex());

        list.removeMouseListener(this);
        list.removeMouseMotionListener(this);
        list.removePropertyChangeListener(this);
        list.getModel().removeListDataListener(this);

        list.removeHierarchyBoundsListener(this);
        list.removeHierarchyListener(this);
        list.removeComponentListener(this);

        list.putClientProperty(HOVER, null);
       }
    }

    public int hoverIndex()
    {
       return hoverIndex;
    }

    private void setHoverIndex(int value)
    {
       hoverIndex = value;
    }

    private void repaint(int index)
    {
       if (index != -1)
        list.repaint(list.getCellBounds(index, index));
    }

    private Point toScreen(Point p)
    {
       p = new Point(p);

       SwingUtilities.convertPointToScreen(p, list);

       return p;
    }

    private Point toList(Point p)
    {
       if (!list.isShowing())
        return null;

       Point s = list.getLocationOnScreen();
       
       s.x = p.x - s.x;
       s.y = p.y - s.y;

       return s;
    }

    // p is in screen coordinate system (or zero, denoting not known or outside)
    private void updateHover(Point p)
    {
       int h = hoverIndex();

       Point q = p == null ? null : toList(p);

       int newHoverIndex = p == null ? -1 : list.locationToIndex(q);

       if (h != newHoverIndex)
       {
        repaint(h);
        repaint(newHoverIndex);

        setHoverIndex(newHoverIndex);
       }

       lastLocation = p;
    }

    // updateLater is used to make sure that the cell bounds are already updated.
    // this may have problems if called initially not from the event-dispatch thread
    private void updateLater()
    {
       if (!running)
       {
        running = true;
        EventQueue.invokeLater(this);
       }
    }

    public void run()
    {
       running = false;

       updateHover(lastLocation);
    }

    public void propertyChange(PropertyChangeEvent e)
    {
       String name = e.getPropertyName();

       if (name.equals("model"))
       {
        ((ListModel)e.getOldValue()).removeListDataListener(this);
        ((ListModel)e.getNewValue()).addListDataListener(this);

        setHoverIndex(-1);
        updateLater();
       }
       else if (name.equals("font") || name.equals("cellRenderer") || name.equals("fixedRowWidth") || name.equals("fixedRowHeight") || name.equals("prototypeCellValue") || name.equals("layoutOrientation"))
       {
        // very unspecific
        list.repaint();

        updateLater();
       }
    }

    public void hierarchyChanged(HierarchyEvent e)
    {
       if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0)
       {
        if (!list.isShowing())
        {
           lastLocation = null;
           setHoverIndex(-1);
        }
        // else: nothing to be done as mouse location is not known (only 1.5)
       }
    }

    public void componentShown(ComponentEvent e)
    {
    }

    public void componentHidden(ComponentEvent e)
    {
       // handled by hierarchyChanged
    }

    public void componentMoved(ComponentEvent e)
    {
       updateHover(lastLocation);
    }

    public void ancestorMoved(HierarchyEvent e)
    {
       updateHover(lastLocation);
    }

    public void componentResized(ComponentEvent e)
    {
       updateLater();
    }

    public void ancestorResized(HierarchyEvent e)
    {
       updateLater();
    }

    public void mouseMoved(MouseEvent e)
    {
       updateHover(toScreen(e.getPoint()));
    }

    public void mouseEntered(MouseEvent e)
    {
       updateHover(toScreen(e.getPoint()));
    }

    public void mouseExited(MouseEvent e)
    {
       updateHover(null);
    }

    // These implementations are quite unspecific.

    public void intervalAdded(ListDataEvent e)
    {
       if (hoverIndex() >= e.getIndex0())
        setHoverIndex(-1);

       updateLater();
    }
   
    public void intervalRemoved(ListDataEvent e)
    {
       if (hoverIndex() >= e.getIndex0())
        setHoverIndex(-1);

       updateLater();
    }

    public void contentsChanged(ListDataEvent e)
    {
       updateLater();
    }
   }

   private static Object HOVER = "xxx.Hover";

   public static int index(JList l)
   {
    Listener h = (Listener)l.getClientProperty(HOVER);

    return h == null
       ? -1 : h.hoverIndex();
   }

   public static void install(JList l)
   {
    if (l.getClientProperty(HOVER) == null)
    {
       Listener h = new Listener(l);

       h.setEnabled(true);
    }
   }

   public static void uninstall(JList l)
   {
    Listener h = (Listener)l.getClientProperty(HOVER);

    if (l != null)
       h.setEnabled(false);
   }

   public static void main(String[] args)
   {
    final DefaultListModel data = new DefaultListModel();

    Object[] o = new java.io.File(System.getProperty("user.home")).list();

    for (int i = 0; i < o.length; i++)
       data.addElement(o[i]);

    final JList l = new JList(data);

    Hover.install(l);

    l.setCellRenderer(new DefaultListCellRenderer()
    {
       private Color hoverBackground = new Color(150, 255, 200);

       public Component getListCellRendererComponent
        (JList l, Object value, int index, boolean selected, boolean focused)
       {
        super.getListCellRendererComponent(l, value, index, selected, focused);

        if (Hover.index(l) == index)
           setBackground(hoverBackground);

        return this;
       }
    });

    l.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

    final JFrame f = new JFrame();

    f.getContentPane().add(new JScrollPane(l));

    f.pack(); f.show();

    Timer t = new Timer(5000, new ActionListener()
    {
       public void actionPerformed(ActionEvent e)
       {
        //data.insertElementAt(e.toString().substring(0, 10), 0);
        f.setLocation(f.getX(), f.getY() + 30);
       }
    });

    t.start();
   }
}
   

Christian
hiwa - 12 Jan 2005 01:33 GMT
Thanks Christian for your wonderful code.
But ...
Should it be that complex?!
Sigh ...

I shall struggle for a simpler one.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.