Добавление текста в JTextArea при нажатии кнопки? - PullRequest
3 голосов
/ 16 октября 2011

У меня есть простой графический интерфейс Swing, и я хочу добавить новую строку текста в JTextArea после нажатия кнопки, просто верно?

Кнопка и ее ActionListener работают правильно (печать материалов на консоль работает нормально), но когда я использую .append () или .setText () для добавления текста в текстовую область, я получаю исключение nullpointer.

Как всегда, код это ниже. Любой вклад будет принята с благодарностью, спасибо !!!

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.LineBorder;

public class GUI extends JFrame implements ActionListener {

private JFrame frame;
private JLabel paneHeader;
public JTextArea ipArea, portArea, outputLog, orderLog, cookLog;
private JButton newServer;

public String ipAddress, portNumber, cashierName, cookName;

public GUI() {
    initGUI();
}

public void initGUI() {

    frame  = new JFrame("Restaurant Overview");
    Container contentPane = frame.getContentPane(); 

    JLabel paneHeader = new JLabel("Restaurant Monitoring System");
    paneHeader.setBounds(200, 0, 200, 25);
    paneHeader.setFont(new Font("Calibri", Font.BOLD, 14));

    JLabel ipLabel = new JLabel("IP Address: ");
    ipLabel.setBounds(25, 30, 75, 20);
    ipLabel.setFont(new Font("Calibri", Font.PLAIN, 12));

    final JTextArea ipArea = new JTextArea();
    ipArea.setBorder(new LineBorder(Color.GRAY));
    ipArea.setBounds(105, 30, 100, 20);

    JLabel portLabel = new JLabel("Port Number: ");
    portLabel.setBounds(25, 55, 75, 20);
    portLabel.setFont(new Font("Calibri", Font.PLAIN, 12));

    final JTextArea portArea = new JTextArea();
    portArea.setBorder(new LineBorder(Color.GRAY));
    portArea.setBounds(105, 55, 100, 20);

    JButton newServer = new JButton("Create new Server");
    newServer.setBorder(new LineBorder(Color.GRAY));
    newServer.setBounds(250, 30, 150, 40);
    newServer.setActionCommand("createserver");
    newServer.addActionListener(this);

    JTextArea outputLog = new JTextArea(" ");
    outputLog.setBorder(new LineBorder(Color.GRAY));
    outputLog.setBounds(25, 90, 150, 150);
    //outputLog.setEditable(false);  

    JTextArea cashierLog = new JTextArea();
    cashierLog.setBorder(new LineBorder(Color.GRAY));
    cashierLog.setBounds(185, 90, 150, 150);
    //cashierLog.setEditable(false);  

    JTextArea cookLog = new JTextArea();
    cookLog.setBorder(new LineBorder(Color.GRAY));
    cookLog.setBounds(345, 90, 150, 150);
    //cookLog.setEditable(false);  

    contentPane.add(paneHeader);
    contentPane.add(ipLabel);
    contentPane.add(ipArea);
    contentPane.add(portLabel);
    contentPane.add(portArea);
    contentPane.add(outputLog);
    contentPane.add(cashierLog);
    contentPane.add(cookLog);

    contentPane.add(newServer);

    frame.setLayout(null);
    frame.pack();
    frame.setSize(600,400);
    frame.setVisible(true); 
}

public void test() {
    //ipAddress = ipArea.getText() + "\n";
    //portNumber = portArea.getText() + "\n";
    String text = "lemons";
    //System.out.println(text);
    outputLog.append(text);
    //outputLog.append(portNumber);
}


public void actionPerformed(ActionEvent e) {
    if ("createserver".equals(e.getActionCommand())) {
        //test();
        outputLog.append("lemons");
    } else {
        //Do Nothing
    }
}
}

Ответы [ 3 ]

9 голосов
/ 16 октября 2011

Вы, вероятно, создаете теневую переменную - объявляете ее более одного раза, но инициализируете локальную переменную, а не поле класса, и поэтому поле класса остается нулевым.

Edit:
Да, конечно, вы делаете. В вашем конструкторе у вас есть

JTextArea outputLog = new JTextArea(" ");

Это повторно объявляет переменную outputLog, и поэтому вы инициализируете только переменную, локальную для конструктора. Решение состоит не в том, чтобы повторно объявить переменную, а в том, чтобы инициализировать поле класса. Поэтому измените вышеприведенное на

outputLog = new JTextArea(" ");

Это необходимо сделать для каждой переменной, к которой необходимо получить доступ в области видимости класса. Для тех, кто может объявить локально, сделайте это, но в целях безопасности избавьтесь от их соответствующего объявления класса, чтобы не рискнуть вызвать такую ​​же ошибку в будущем.

4 голосов
/ 16 октября 2011

Ваша ошибка в том, что переменная экземпляра outputLog не инициализирована.

3 голосов
/ 16 октября 2011

ваш код не выполнен на EDT , вы должны поместить его в invokeLater ()

EventQueue.invokeLater(new Runnable() {

    @Override
    public void run() {
       outputLog.setText(outputLog.getText() 
          + System.getProperty("line.separator") + text);
    }
});
...