簡體   English   中英

單擊JTree時出現異常(空指針異常)

[英]Exception when clicking JTree (null pointer exception)

因此,當我單擊包含JtreeMessages tabPane時,這是我的 java swing 中的預覽,看起來不錯。

圖1(加載消息)

圖2.(完成)

當我單擊 JTree 中的任何checkboxes時,它應該正在加載(檢查)或卸載(取消選中)消息列表中的消息,並且 swingworker 正在運行以查看進度。 但是在我點擊復選框(任何條件)之后會發生什么,是的 swingworker 正在運行並給出加載/卸載進度,但在那之后,我得到了這個:

線程“AWT-EventQueue-0”中的異常 java.lang.NullPointerException:無法調用“model.Message.getContents()”,因為“消息”是 null

並使message lists不可點擊,在我嘗試點擊 JTree 中的復選框之前,這些列表是可點擊的。

目前我在學習 swing 的目的中不需要 JTree,所以我並沒有真正考慮到這個 JTree 課程,但我需要修復這個問題,以便我可以將 go 與教程一起保留。 這就是為什么我不太確定哪些代碼有問題並且需要放入這個線程。 如果我的問題不清楚,我很抱歉。 如果還有什么我必須在這個線程上放的東西,請問我,我很樂意把它放在這里。

這是異常中提到的 class

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());
        }
    });
 }

這是與上述 class 相關的 class 和方法

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;}
}

您的Message class構造函數需要兩個參數(屬於: String、String )才能創建 Message 的實例。 我不知道您當前使用什么來創建 Message 實例,也不知道是什么存儲了這些實例。 您確實需要跟蹤它們,否則您會將它們丟失到 JVM 垃圾收集。

我想也許您可能想要稍微修改一下您的 Message Class 以便您可以在內部(或外部)存儲您的 Message 實例並在需要時輕松訪問這些實例中的任何一個,例如:

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();
    }
}

做任何事情來創建 Message 實例。

現在,在ListSelectionListener內的MessagePanel class 中:

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;
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM