单击jtree时出现异常(空指针异常)

pieyvz9o  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(383)

所以当我点击 Messages tabPane 包含 Jtree ,这是我的java swing中的预览,看起来不错。
pict 1(加载消息)
图2(完成)
当我点击任何一个 checkboxes 在jtree中,它应该是加载(检查)或卸载(取消检查)消息列表中的消息,swingworker运行以查看进度。但是当我点击复选框(任何条件)后,会发生什么?是的,swingworker正在运行并给出加载/卸载进度,但在那之后,我得到了:
线程“awt-eventqueue-0”java.lang.nullpointerexception中出现异常:无法调用“model.message.getcontents()”,因为“message”为null
做一个 message lists 是不可点击的,在我尝试点击jtree中的复选框之前是可点击的。
目前我不需要jtree在我学习swing的目的,所以我不是真的考虑到这个jtree教训,但我需要这是固定的,这样我就可以继续与教程。这就是为什么我不太确定哪些代码是有问题的,需要放到这个线程中。如果我的问题不清楚,我很抱歉。如果这根线还有什么我要放的,请告诉我,我很乐意放在这里。
这是在exception中提到的类

public class MessagePanel extends JPanel implements ProgressDialogListener{
 public MessagePanel(JFrame parent) {
    messageListModel = new DefaultListModel();
    messageList = new JList(messageListModel);
    messageList.setCellRenderer(new MessageListRenderer());

    messageList.addListSelectionListener(new ListSelectionListener() {
        @Override
        public void valueChanged(ListSelectionEvent e) {
            Message message = (Message)messageList.getSelectedValue();
            textPanel.setText(message.getContents());
        }
    });
 }

这是与上述类相关的类和方法

public class MessageListRenderer implements ListCellRenderer {
    private JPanel panel;
    private JLabel label;
    private Color selectedColor,normalColor;

    public MessageListRenderer() {
     //some ui settings
    }

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

        Message message = (Message)value;
        label.setText(message.getTitle());
        panel.setBackground(cellHasFocus ? selectedColor: normalColor);
        return panel;
    }
}

===================

public class TextPanel extends JPanel{
    public void setText(String text) {
        textArea.setText(text);
    }
}

===================

public class Message {
    private String title,contents;

    public Message(String title, String contents) {
        super();
        this.title = title;
        this.contents = contents;
    }

    public String getTitle() {return title;}
    public void setTitle(String title) {this.title = title;}
    public String getContents() {return contents;}
    public void setContents(String contents) {this.contents = contents;}
}
vdzxcuhz

vdzxcuhz1#

您的消息类构造函数需要两个参数(of:string,string)才能创建消息的示例。我不知道您当前使用什么来创建消息示例,也不知道存储这些示例的是什么。您确实需要跟踪它们,否则会将它们释放到jvm垃圾收集中。
我认为您可能需要稍微修改一下您的消息类,以便您可以在内部(或外部)存储消息示例,并在需要时轻松访问其中任何一个示例,例如:

public class Message {

    // A List Interface object to hold Message instances.
    private static java.util.List<Message> messageInstances = new java.util.ArrayList<>();
    // The OS System's New-Line character to use for console writing. 
    private final static String ls = System.lineSeparator();

    // Instance member variables
    private String title;
    private String contents;

    /**
     * Constructor #1
     * Does Nothing but adds the instance to the messageInstances List!
     * Relies on Setters to fill instance member variables.
     */
    public Message() {  
        messageInstances.add((this));
    }

    /**
     * Constructor #2
     * Contains parameters of which the arguments will fill instance member 
     * variables listed within the Parameters list below.
     * 
     * @param title (String) The Message Title.<br>
     * 
     * @param contents (String) The message content related to the above title.
     */
    public Message(String title, String contents) {
        super();
        this.title = title;
        this.contents = contents;
        messageInstances.add((this));
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContents() {
        return contents;
    }

    public void setContents(String contents) {
        this.contents = contents;
    }

    public static java.util.List<Message> getMessageInstances() {
        return messageInstances;
    }

    /**
     * Removes one (or more) Message instances from the messageInstances List. 
     * This method must be supplied at least one integer index value of the 
     * Message instance to remove otherwise a Warning is displayed within the 
     * console window. Several index values can be supplied providing they are 
     * delimited with a comma or all desired Message Instance index values to 
     * remove are supplied within a Single Dimensional int[] Array.<br><br>
     * 
     * <b>Valid uses of this class method:</b><pre>
     * 
     *     removeMessageInstance(0, 4, 2, 16);
     * 
     *     OR
     * 
     *     int[] indexes = {0, 4, 2, 16};
     *     removeMessageInstance(indexes);</pre>
     * 
     * @param instanceIndexes
     */
    public static void removeMessageInstance(int... instanceIndexes) {
        int[] iIndex = null;
        if (instanceIndexes.length == 0) {
            System.err.println("Message.removeMessageInstance() method Warning!" + ls
                    + "Require an index value of the Message Instance to remove!" + ls
                    + "Ignoring Removal call!" );
            return;
        }

        iIndex = new int[instanceIndexes.length];
        System.arraycopy(instanceIndexes, 0, iIndex, 0, instanceIndexes.length);

        for (int i = 0; i < iIndex.length; i++) {
            if(iIndex[i] < 0 || iIndex[i] > messageInstances.size()) {
                System.err.println("Message.removeMessageInstance() method Warning!" + ls 
                        + "The supplied Message Instance index value (" + iIndex[i] + ") is invalid!" + ls
                        + "Ignoring Removal call for Message Instance at Index " + iIndex[i] + "!");
                continue;
            }
            messageInstances.remove(iIndex[i]);
        }
    }

    @Override
    public String toString() {
        return new StringBuilder("").append(title).append(" | ")
                                    .append(contents).toString();
    }
}

尽你所能创建消息示例。
现在,在listselectionlistener中的messagepanel类中:

public void valueChanged(ListSelectionEvent e) {
    String title = messageList.getSelectedValue().toString(); // toString() may not be required.
    List<Message> messages = Message.getMessageInstances();
    for (Message msg : messages) {
        if (msg.getTitle().equalsIgnoreCase(title)) {
            textPanel.setText(msg.getContents());
            break;
        }
    }
}

相关问题