更改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行放什么。如果有人能帮助我,我将不胜感激。

我是这样做的(解决方案: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;
  }
}

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

你需要一些方法来告诉渲染器哪些行是"高亮显示的",我能想到的实现这一目标的两种直接方法是…

  1. 创建一个自定义JList,它具有设置/获取突出显示行的方法。然后,您需要转换到该实现并询问适当的方法,根据需要采取行动。
  2. 在列表数据中提供一个方法,将行标记为高亮或不高亮。这将允许您直接查询数据。

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

第二种方法将显示和数据信息混合在一起,我不鼓励这样做,因为您确实希望将这类内容分开;)

AFAIK良好的RolloverSupportTest/Hightlighter实现

  • 物质L&F有荧光笔

  • RolloverSupportTest by @aephyr

相关内容

  • 没有找到相关文章

最新更新