我在渲染 JList 时遇到了一些错误

I have some errors with JList rendering JLists

提问人:martin 提问时间:3/6/2022 最后编辑:Andrew Thompsonmartin 更新时间:3/16/2022 访问量:160

问:

所以我想做一个主要的 JList,在里面渲染 JList。 问题是,当我实际向主 JList 中的某个 JList 添加新字符串时,我必须调用 mainList.updateUI();以显示该 JList 中添加的字符串,但它会导致以下异常:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot invoke "javax.swing.plaf.synth.SynthStyle.get(javax.swing.plaf.synth.SynthContext, Object)" because the return value of "javax.swing.plaf.synth.SynthContext.getStyle()" is null
    at java.desktop/javax.swing.plaf.synth.SynthDefaultLookup.getDefault(SynthDefaultLookup.java:43)
    at java.desktop/sun.swing.DefaultLookup.get(DefaultLookup.java:125)
    at java.desktop/sun.swing.DefaultLookup.getBorder(DefaultLookup.java:202)
    at java.desktop/sun.swing.DefaultLookup.getBorder(DefaultLookup.java:210)
    at java.desktop/javax.swing.DefaultListCellRenderer.getNoFocusBorder(DefaultListCellRenderer.java:105)
    at java.desktop/javax.swing.DefaultListCellRenderer.getListCellRendererComponent(DefaultListCellRenderer.java:172)
    at com.martin.gui.CostumJListRenderer.getListCellRendererComponent(CostumJListRenderer.java:10)
    at java.desktop/javax.swing.plaf.basic.BasicListUI.updateLayoutState(BasicListUI.java:1444)
    at java.desktop/javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(BasicListUI.java:1394)
    at java.desktop/javax.swing.plaf.basic.BasicListUI.paintImpl(BasicListUI.java:330)
    at java.desktop/javax.swing.plaf.basic.BasicListUI.paint(BasicListUI.java:306)
    at java.desktop/javax.swing.plaf.synth.SynthListUI.update(SynthListUI.java:90)
    at java.desktop/javax.swing.JComponent.paintComponent(JComponent.java:842)
    at java.desktop/javax.swing.JComponent.paint(JComponent.java:1119)
    at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:952)
    at java.desktop/javax.swing.JComponent.paint(JComponent.java:1128)
    at java.desktop/javax.swing.JComponent.paintToOffscreen(JComponent.java:5311)
    at java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBufferedImpl(RepaintManager.java:1657)
    at java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1632)
    at java.desktop/javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1570)
    at java.desktop/javax.swing.RepaintManager.paint(RepaintManager.java:1337)
    at java.desktop/javax.swing.JComponent._paintImmediately(JComponent.java:5259)
    at java.desktop/javax.swing.JComponent.paintImmediately(JComponent.java:5069)
    at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:879)
    at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:862)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:862)
    at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:835)
    at java.desktop/javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:784)
    at java.desktop/javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1898)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

我的目标是在一个主列表中拥有具有特定排名的用户类别,例如用户在 discord 中按排名列出的方式。

代码如下:

我的主列表渲染器

public class CostumJListRenderer extends DefaultListCellRenderer {

   @Override
    public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            if (value instanceof JList<?>) {
                c = (Component) value;
            }
            return c;
    }

}

添加部分:

if(object != null) {
    if(!ScreenGUI.getInstance().coloredString.containsKey(String.valueOf(object.get("rnk")))) {
        //checking if the colored string contains rank, if not then new list and rank+color will be assigned
        ScreenGUI.getInstance().coloredString.put(String.valueOf(object.get("rnk")), Color.decode(String.valueOf(object.get("usrClr"))));
        JList<String> list = new JList<>();
        Color color = Color.decode(String.valueOf(object.get("usrClr")));
        TitledBorder border = new TitledBorder(new LineBorder(Color.DARK_GRAY, 1), String.valueOf(object.get("rnk")));
        border.setTitleJustification(TitledBorder.LEFT);
        border.setTitlePosition(TitledBorder.TOP);
        border.setTitleColor(color);
        border.setTitleFont(new Font("", Font.BOLD, 13));
        list.setBorder(border);
        DefaultListModel<String> strModel = new DefaultListModel<>();
        ScreenGUI.getInstance().addOnlineUsers(strModel, String.valueOf(object.get("prefX")).charAt(0) + String.valueOf(object.get("rnk")) + String.valueOf(object.get("prefX")).charAt(1) + " - " + String.valueOf(object.get("usr")), String.valueOf(object.get("rnk"))); //username perimeter
        ScreenGUI.getInstance().list.add(new ListData(list, String.valueOf(object.get("rnk")), String.valueOf(object.get("usrClr")), strModel));
    }else {
        ScreenGUI.getInstance().list.forEach((current) -> {
            if(current.rank.equals(String.valueOf(object.get("rnk")))) {
                current.model.addElement(String.valueOf(object.get("prefX")).charAt(0) + String.valueOf(object.get("rnk")) + String.valueOf(object.get("prefX")).charAt(1) + " - " + String.valueOf(object.get("usr")));
            }
        });
        ScreenGUI.getInstance().updateUsrUI(); //mainList.updateUI();
}

我的 ListData 类,其中包含有关 JList 的信息

public class ListData {

    public JList<String> list;
    public DefaultListModel<String> model;
    public String rank;
    public String color;

    public ListData(JList<String> list, String rank, String color, DefaultListModel<String> model) {
        this.list = list;
        this.rank = rank;
        this.color = color;
        this.model = model;
        list.setFont(new Font("", Font.BOLD, 14));
        list.setModel(model);
        list.setForeground(Color.decode(color));
        ScreenGUI.getInstance().addToMainUserModel(list);
    }
}

我还必须提到我在 JFrame 中使用 Nimbus 主题

我怎样才能解决异常,我什至做对了吗?

感谢您在评论中的帮助!

修复:

您有两种选择:

  1. 使用 BoxLayout 制作 JPanel,然后将 JList(-s) 添加到其中!
  2. 击球一,只需转到 JavaFX 并使用手风琴组件!

(感谢@GilbertLeBlanc的帮助)

java swing nullpointerexception jlist listcellrenderer

评论

1赞 Gilbert Le Blanc 3/7/2022
JLists不是为渲染内部而设计的。也许 a 会是更好的 Swing 组件选择。JListsJTree
0赞 martin 3/7/2022
@GilbertLeBlanc我很难想到在 y 轴上带有 boxlayout 的 jpanel,然后向其添加 jlists,但 jtree 会是击球手吗?
0赞 Gilbert Le Blanc 3/7/2022
您要查找的组件在其他 GUI 库中称为折叠式。Swing 没有原生的手风琴小部件。如果你能做出工作,那就去做吧。JPanelJLists
0赞 martin 3/7/2022
非常感谢,我将使用 boxlayout 实现 JTree 和 JPanel,看看什么是击球手!

答: 暂无答案