ListCellRenderer将所有行设置为相同的颜色

时间:2013-10-01 05:16:17

标签: java swing listcellrenderer

我的目的是使用ListCellRenderer来突出显示包含已访问过(或点击过)的链接的红色单元格,以及绿色未访问过的部分,这部分但不完整。似乎渲染器的工作方式与将单元格标记为红色有关。但是,如果我添加更多行,则此后它们将全部变为红色。此外,如果我标记两个不相邻的单元格,那么它也会将它们全部标记为红色。

我有一个Feed类,我最初有一个布尔变量,但我修改了代码,以便m_isRead变量在listModel中,这里是构造函数:

    public Feed (URL url, String urlName) {
         this.m_urlName = urlName;
         this.m_observers = new ArrayList<Observer>();  
         this.m_isRead = isRead;
    }

现在,在listModel Class中将此实例变量设置为false,该类是包含渲染器的类。

 m_isRead = false.

使用我现在调整过的ListCellRenderer,以便它不需要这种方法:

m_feeds.get(index).getM_urlName();

我按照以下步骤进行:

 class MyCellRenderer extends JLabel implements ListCellRenderer {
         public MyCellRenderer() {
             setOpaque(true);
         }

         public Component getListCellRendererComponent(JList list,
                                                       Object value,
                                                       int index,
                                                       boolean isSelected,
                                                       boolean cellHasFocus) {

             setText(value.toString());

             Color background = Color.GREEN;
             Color foreground = Color.BLACK;

               //find out if the specific has been read or not
               if (m_feeds.get(index).isM_isRead() == true) {
                 background = Color.RED;
                 foreground = Color.WHITE;


             } else {
                 background = Color.GREEN;
                 foreground = Color.BLACK;
             };

             setBackground(background);
             setForeground(foreground);

             return this;
         }
     }

然后我有另一个内部类,我用一个方法来获取所选项目,此时我将 m_isRead 设置为true(读取)这现在独立于Feed类和与之相关的代码已被注释掉:

public class ChangeSelectedIndex implements ListSelectionListener {

    @Override
    public void valueChanged(ListSelectionEvent e) {

        for (int i = 0; i < m_listModel.size(); i++) {  
            if (m_listModel.getElementAt(i) != null) {    
                m_urlName = m_list.getSelectedValue();
                initiateParsing();
                m_updateFeedButton.setEnabled(true);

               // TODO fix behavior for cell renderer
               //this sets the value of the feed being clicked to true
              // m_feeds.get(i).setM_isRead(true);
                 m_isRead = true;
            }
         }// end for 
     }
}

现在结果是一样的,如果我添加它们是绿色的行并且这是正确的,如果我点击每一行,每次都会读取,只要我点击相邻的行到我点击的第一行但是如果我,例如,有四行,我点击第一行和最后一行,所有行,包括介于两者之间(我没有点击)变成红色。同样,如果我添加新行,它们会以红色显示。也就是说,如果我点击其中一行,那么我之后添加的行将是红色的。

有人可以帮忙吗?

提前谢谢你,

干杯

1 个答案:

答案 0 :(得分:0)

经过一段时间的思考,我得出的结论是我的原始单元格渲染器没有任何问题,它与列表模型本身有关。 JList只是不支持多个 NON 连续选择,而没有单击开箱即用的 Ctrl 按钮。这就是我在如何模仿 Ctrl 点击下进行进一步搜索的原因;我在答案号8 (工作代码)中找到了这个:

Individual and not continuous JTable's cell selection

这里有趣的是将鼠标事件添加到列表中。此鼠标事件模拟 Ctrl 向下事件,JList和JTable使用的 ListSelectionModel 设置为 MULTPLE_SELECTION_INTERVAL ,其行为符合要求。也就是说,用户现在可以点击任何Feed,即使它不是连续的,它也会为所需的Feed添加颜色,而不会为任何未被点击的Feed提供颜色。

对于渲染器,使用 isSelected 参数就足够了,该参数通过其方法 getListCellRenderer()进入。但是,在我的情况下,我所做的事情与我使用数组添加所有Feed的状态(即读取或未读取)的添加具有相同的效果。按照这种方式,我想到如果我关闭程序并保存提要列表,包括其 isRead 参数设置为true或false,那么稍后在检索提要列表时,相同的提要状态将从例如文件中恢复,或者至少是我想到的。