我正在尝试更改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行放什么。如果有人可以帮助我,我将非常感激。
答案 0 :(得分:2)
我个人会使用MouseMotionListener
来覆盖processMouseMotionEvent
,但那只是我。
你需要一些方法来告诉渲染器哪些行是“突出显示的”,我能想到实现这两个目标的两个直接方法是......
JList
,其中包含设置/获取突出显示的行的方法。然后,您需要转换为此实现并询问适当的方法,并根据需要采取措施。第一种方法的优点是它将责任与视图分离,它确实属于它。它确实有缺点,意味着您需要创建自定义JList
。使用getClientProperty
和putClientProperty
方法可能更容易,这意味着您不需要自定义实现,也不需要在渲染器中强制显示列表,但是缺点是不明显其他开发者。
第二种方法将显示和数据信息混合在一起,而不是我鼓励的,因为你真的希望将这种东西分开;)
答案 1 :(得分:1)
实施AFAIK好RolloverSupportTest
/ Hightlighter
答案 2 :(得分:1)
以下是我的表现(解决方案: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;
}
}