Defaultlistcellrenderer работает нормально, но не может заставить listcellrenderer работать

Я попытался расширить DefaultListCellRenderer для изменения цвета текста, и он работает нормально, как и должно быть. Но я не смог отобразить значок в том JList, который я визуализирую. Затем я попытался реализовать 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$1.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.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.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)

Вам действительно следует расширить DefaultListCellRenderer вместо того, чтобы напрямую реализовывать интерфейс. Прочтите документация, чтобы понять почему. Убедитесь, что getResource ("/ images / im.png") действительно возвращает ненулевое значение. И, очевидно, вашему модулю визуализации необходимо вызвать setIcon (чего он не делает в опубликованном вами коде).

VGR 10.08.2018 16:03

@VGR я пробовал сделать это и добавил все в свой код, и я попытался использовать DefaultListCellRenderer, он дает исключение нулевого указателя в ImageIcon

Nnnnn 10.08.2018 16:06

Если ваша конструкция ImageIcon выдает исключение NullPointerException, как вы ожидаете, что будет отображаться значок? Если вы запускаете файл .jar, убедитесь, что в нем есть запись images / im.png. Если вы работаете не из .jar, убедитесь, что родительский каталог изображений находится в пути к классам среды выполнения.

VGR 10.08.2018 16:09

С каталогом все в порядке, я дважды проверил, есть ли другая причина, по которой я могу это получить. Или мне следует обновить код вопроса с помощью кода DefaultListCellRenderer для лучшего обзора.

Nnnnn 10.08.2018 16:18

Нет смысла проверять ваш рендерер до тех пор, пока код ImageIcon не завершится без каких-либо исключений.

VGR 10.08.2018 16:20

@VGR, но вы всегда можете указать мне правильное направление, где я должен искать это

Nnnnn 10.08.2018 16:43

1) Для более быстрой помощи опубликуйте минимальный воспроизводимый пример или Краткий, автономный, правильный пример. 2) Один из способов получить изображение (я) для примера - установить горячую ссылку на изображения в этот вопрос и ответ. НАПРИМЕР. Этот ответ горячие ссылки на изображение, встроенное в этот вопрос.

Andrew Thompson 10.08.2018 17:45
0
7
515
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы пытались реализовать интерфейс ListCellRenderer с нуля, расширив его с JLabel. (вместо расширения от 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;
    }
}

Я пробовал именно это, это работает как шарм, но проблема в том, что я добавляю код ImageIcon, как указано в вопросе, он дает мне исключение нулевого указателя, я не знаю почему.

Nnnnn 10.08.2018 16:11

@Nnnnn Вы должны опубликовать трассировку стека исключений (добавьте ее в свой вопрос). Возможно, это исключение не имеет ничего общего с кодом вашего модуля рендеринга. Может быть исключение только что выброшено new ImageIcon(...).

Thomas Fritsch 10.08.2018 16:18

Я просто удалил 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.

new ImageIcon("images/in.png"); Это не сработает, если app. развернут (хотя он завершится ошибкой без создания исключения) и в любом случае должен выполняться в конструкторе.
Andrew Thompson 10.08.2018 17:46

Можете ли вы помочь мне понять, почему это не удастся, потому что в моем приложении я использую несколько ресурсов извне, таких как файлы, изображения и многое другое, не могли бы вы указать мне правильную статью, чтобы получить это.

Nnnnn 10.08.2018 17:57

Ресурсы приложения станут встроенными ресурсами к моменту развертывания, поэтому разумно начать доступ к ним, как если бы они были, прямо сейчас. Доступ к встроенный ресурс должен осуществляться по URL-адресу, а не по файлу. См. Информация. страница для встроенного ресурса, чтобы узнать, как сформировать URL.

Andrew Thompson 10.08.2018 18:07

Другие вопросы по теме