2011-10-16 36 views
3

我有一个简单的Swing GUI,我想在按下按钮之后向JTextArea添加一行新文本,简单的权利?将文本追加到按钮上的JTextArea?

Button和它的ActionListener函数正确(打印的东西到控制台工作正常),但是当我使用.append()或.setText()添加文本到textarea,我得到一个空指针异常。

一如既往,在下面进行编码。任何输入将不胜感激,谢谢!

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 
    } 
} 
} 
+0

你也应该发表您的堆栈跟踪 – amit

回答

9

你很可能会遮蔽一个变量 - 声明它不止一次,但没有初始化一个局部变量的类字段,所以类字段保持为空。

编辑:
是的,果然,你做。在你的构造你有

JTextArea outputLog = new JTextArea(" "); 

这重新声明outputLog变量,所以你只在初始化局部变量的构造。解决方案不是重新声明变量,而是初始化类字段。因此,将上述内容更改为

outputLog = new JTextArea(" "); 

您需要为每个需要在类作用域中访问的变量执行此操作。对于那些可以在本地申报的人,这样做,但为了安全起见,摆脱他们相应的类别声明,以免在将来导致相同的错误。

+0

我怎么会如此盲目!谢谢HFoE! –

+0

@迈克尔:不客气! –

4

您的错误是实例变量outputLog未初始化。

3

你的代码不是EDT做,你必须THT包装成的invokeLater()

EventQueue.invokeLater(new Runnable() { 

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

OP不需要使用EDT与'JTextArea.append()',**是线程安全**。无论如何,总是从EDT调用'actionPerformed()'! – jfpoilpret