0

我的意图是使用 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 类中设置为 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 
     }
}

现在结果是一样的,如果我添加它们是绿色的行,那是正确的,如果我点击每一行,只要我点击了与我点击的第一行相邻的行,每轮读取一次,但是如果我,例如,有四行,我点击第一行和最后一行,所有行,包括中间的行(我没有点击)变成红色。同样,如果我添加新行,它们会变成红色。也就是说,如果我什至单击这些行之一,那么我之后添加的行将是红色的。

有人可以帮忙吗?

先感谢您,

干杯

4

1 回答 1

0

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

单独且不连续的 JTable 的单元格选择

这里有趣的是将鼠标事件添加到列表中。此鼠标事件模拟Ctrl按下事件,JList 和 JTable 使用的ListSelectionModel设置为MULTPLE_SELECTION_INTERVAL ,它的行为符合需要。也就是说,用户现在可以点击任何提要,即使它不是连续的,并且它将为所需的提要或多个提要着色,而不会对可能位于其间的任何未点击的提要着色。

至于渲染器,使用通过其方法getListCellRenderer() 传入的isSelected参数就足够了。但是,就我而言,我所做的与我使用数组添加提要的所有状态(含义、已读或未读)具有相同的效果。以这种方式进行,我想到如果我关闭程序并保存提要列表,包括其isRead参数设置为 true 或 false,然后在检索提要列表时,将恢复相同的提要状态,例如例如,一个文件,或者至少这是我的想法。

于 2013-10-02T12:24:47.263 回答