2012-12-26 151 views
1

我试图改变JList单元格的背景颜色时,它正在盘旋,但我不知道如何去做。这是我目前有:更改悬停上的JList项目背景颜色

package cats.youtube.gui; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Rectangle; 
import java.awt.event.MouseEvent; 
import java.util.LinkedList; 

import javax.swing.AbstractListModel; 
import javax.swing.DefaultListCellRenderer; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.ListSelectionModel; 
import javax.swing.border.EmptyBorder; 

import cats.youtube.search.YoutubeSearchResult; 

public class SearchResultsList extends JPanel{ 

    private class Renderer extends DefaultListCellRenderer{ 

     public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected, boolean focused){ 
      final JTextArea area = new JTextArea(model.get(index).toString()); 
      area.setBorder(new EmptyBorder(5, 0, 5, 0)); 
      area.setForeground(selected || focused ? Color.WHITE : Color.BLACK); 
      area.setBackground(selected || focused ? Color.RED : Color.WHITE); 
      return area; 
     } 
    } 

    public class Model extends AbstractListModel<String>{ 

     private LinkedList<YoutubeSearchResult> results; 
     private Object lock; 

     private Model(){ 
      results = new LinkedList<YoutubeSearchResult>(); 

      lock = new Object(); 
     } 

     public int getSize(){ 
      return results.size(); 
     } 

     public String getElementAt(final int i){ 
      return results.get(i).toString(); 
     } 

     public YoutubeSearchResult get(final int i){ 
      return results.get(i); 
     } 

     public void add(final YoutubeSearchResult r){ 
      synchronized(lock){ 
      results.add(r); 
      fireContentsChanged(this, 0, getSize()); 
      try{ 
       lock.wait(500L); 
      }catch(InterruptedException e){ 
       e.printStackTrace(); 
      } 
      } 
     } 

     public void remove(final YoutubeSearchResult r){ 
      results.remove(r); 
      fireContentsChanged(this, 0, getSize()); 
     } 

     public void removeAll(){ 
      results.clear(); 
      fireContentsChanged(this, 0, getSize()); 
     } 
    } 

    private JList<String> list; 
    private JScrollPane scroll; 
    private Model model; 
    private Renderer renderer; 

    public SearchResultsList(){ 
     super(new BorderLayout()); 

     list = new JList<String>(){ 
      public void processMouseMotionEvent(final MouseEvent e){ 
       super.processMouseMotionEvent(e); 
       final int i = locationToIndex(e.getPoint()); 
       if(i > -1){ 
        final Rectangle bounds = getCellBounds(i, i+1); 
        if(bounds.contains(e.getPoint())){ 
         //   <--------- here is line 95 
        } 
       } 

      } 
     }; 
     list.setModel(model = new Model()); 
     list.setCellRenderer(renderer = new Renderer()); 
     list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 

     add(scroll = new JScrollPane(list), BorderLayout.CENTER); 
    } 

    public Model getModel(){ 
     return model; 
    } 
} 

问题是在线95;我不知道该放什么。我尝试了多种方法,其中一种方法是通过渲染器调用getListCellRendererComponent方法,然后改变背景,但这并不奏效。

悬停部分确实工作(它确实得到正确的索引)我只是不知道该怎么放在第95行。如果有人可以帮助我,它将非常感激。

回答

2

我个人会使用MouseMotionListener来覆盖processMouseMotionEvent,但那只是我自己。

你需要一些方法来判断哪些行“突出”的渲染,这两个直接的方法,我能想到的实现,这是对的...

  1. 创建它拥有一些方法来设置自定义JList /获取突出显示的行。然后您需要投入实施并询问适当的方法,并根据需要采取行动。
  2. 在列表数据中提供一个将行标记为突出显示的方法。这将允许您直接询问数据。

第一种方法的优点是它将视图的责任与真正属于的视图隔离开来。它的缺点是你需要创建一个自定义的JList。使用getClientPropertyputClientProperty方法可能会更容易,这意味着您不需要自定义实现,也不需要在渲染器中投射列表,但具有对其他开发人员不明显的缺点。

第二种方式混合在一起显示和数据信息,而不是东西,我会鼓励你真的想保持这种东西分开;)

+0

我知道了,谢谢。实际上,我找到了一个更有效的替代方案。我只是使用一个带有BoxLayout的面板,然后将结果添加到面板,它模拟了一个列表,除了我不需要再添加该延迟。另外,它似乎也更有效率。不过谢谢你,我感谢你的回应。 –

+2

实际上,当你增加“列表”中的项目数时,你会发现你的工作效率低很多。 'JList'(和'JTable'和'JTree')针对性能进行了高度优化,以处理大型数据集(以及小型数据集) – MadProgrammer

0

这里是我是如何做到的(这里的解决方案:http://objectmix.com/java/73071-highlight-itemin-jlist-mouseenter-mouse-over.html,第二条消息):

private int mHoveredJListIndex = -1; 

... 

mList.addMouseMotionListener(new MouseAdapter() { 
    public void mouseMoved(MouseEvent me) { 
    Point p = new Point(me.getX(),me.getY()); 
    int index = mList.locationToIndex(p); 
    if (index != mHoveredJListIndex) { 
     mHoveredJListIndex = index; 
     mList.repaint(); 
    } 
    } 
}); 

而在你的渲染:

public class CellRenderer extends JComponent implements ListCellRenderer 
{ 

    @Override 
    public Component getListCellRendererComponent(JList aList, Object aValue, int aIndex, boolean aIsSelected, boolean aCellHasFocus) 
    { 
    Color backgroundColor = mHoveredJListIndex == aIndex ? Color.gray : Color.white; 
    JPanel pane = new JPanel(new BorderLayout()); // add contents here 

    pane.setBackground(backgroundColor); 
    return pane; 
    } 
} 
相关问题