DefaultListCellRenderer 工作正常但无法让 ListCellRenderer 工作

DefaultListCellRenderer working fine but could not get ListCellRenderer to work

我已经尝试扩展 DefaultListCellRenderer 以更改文本颜色,它工作正常 be.But 我无法显示 JList 我是 rendering.Then 我尝试实施 ListCellRenderer,但我什至无法显示 JList 的内容。我已经在鼠标点击 JList 时设置了渲染器,在 ListCellRenderer 的情况下,列表在鼠标点击时消失,但在 DefaultListCellRenderer 的情况下它工作正常。

我的第一个问题是为什么 JList 的内容在单击鼠标时消失,第二个问题是为什么我无法通过添加以下代码来添加图标 DefaultListCellRenderer

ImageIcon imageIcon = new ImageIcon(getClass().getResource("/images/im.png"));
setIcon(imageIcon);

以下是渲染器的全部代码。

public class RCellRenderer extends JLabel implements ListCellRenderer {

    String runm = "";

    public RCellRenderer(String runm) {
        this.runm = runm;

    }

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    //    Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

        if (value.equals(runm)) {
            Color fg = Color.BLACK;
            setForeground(fg);
        }

     //   return c;
     return this;
    }

}

DefaultListCellRenderer的代码如下:

public class RCellRenderer extends DefaultListCellRenderer {

    String runm = "";

    public RCellRenderer(String runm) {
        this.runm = runm;

    }

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        ImageIcon imageIcon = new ImageIcon(getClass().getResource("images/in.png"));

        setIcon(imageIcon);
        if (value.equals(runm)) {
            Color fg = Color.BLACK;
            setForeground(fg);
        }

        return c;
    }

}

在我的程序中执行此操作时的堆栈跟踪如下:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at javax.swing.ImageIcon.<init>(ImageIcon.java:217)
    at services.RCellRenderer.getListCellRendererComponent(RCellRenderer.java:29)
    at javax.swing.plaf.basic.BasicListUI.updateLayoutState(BasicListUI.java:1361)
    at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(BasicListUI.java:1311)
    at javax.swing.plaf.basic.BasicListUI.getCellBounds(BasicListUI.java:952)
    at javax.swing.plaf.basic.BasicListUI$Handler.repaintCellFocus(BasicListUI.java:2807)
    at javax.swing.plaf.basic.BasicListUI$Handler.focusLost(BasicListUI.java:2823)
    at java.awt.Component.processFocusEvent(Component.java:6425)
    at java.awt.Component.processEvent(Component.java:6289)
    at java.awt.Container.processEvent(Container.java:2237)
    at java.awt.Component.dispatchEventImpl(Component.java:4889)
    at java.awt.Container.dispatchEventImpl(Container.java:2295)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:1024)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:690)
    at java.awt.Component.dispatchEventImpl(Component.java:4760)
    at java.awt.Container.dispatchEventImpl(Container.java:2295)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at sun.awt.SunToolkit.run(SunToolkit.java:518)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access0(EventQueue.java:97)
    at java.awt.EventQueue.run(EventQueue.java:709)
    at java.awt.EventQueue.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

您试图通过从 JLabel 扩展来从头开始实现 ListCellRenderer 接口 (而不是从 DefaultListCellRenderer 又从 JLabel).

延伸

因此你需要实现所有的方法 DefaultListCellRenderer.getListCellRendererComponent 确实如此, 最重要的是,这涉及将 value 传递给此方法 并将其放入 JLabel.setText 调用中。

简而言之,我建议您从 DefaultListCellRenderer:

扩展您的渲染器
public class RCellRenderer extends DefaultListCellRenderer {

    String runm = "";

    public RCellRenderer2(String runm) {
        this.runm = runm;
    }

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

        if (value.equals(runm)) {
            Color fg = Color.BLACK;
            c.setForeground(fg);
        }

        return c;
    }
}

我刚刚删除了 getClass().getResource(...),它工作得很好。我不知道为什么,但就是这样。工作代码如下

public class RCellRenderer extends DefaultListCellRenderer {

    String runm = "";

    public RCellRenderer(String runm) {
        this.runm = runm;

    }

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        ImageIcon imageIcon = new ImageIcon("images/in.png");
        setIcon(imageIcon);
        if (value.equals(runm)) {
            Color fg = Color.BLACK;
            setForeground(fg);
        }

        return c;
    }

}

在这个问题解决后我还有一个问题,这张图片可以添加到JList的最右边吗?