Java-JPanel-用arraylist绘制文本文件的内容-只适用于第一次



我有一个带有JMenuBar的程序。在JMenuBar中有一个JButton,JButton打开一个包含2个JMenuItems的JMenu。当您单击其中一个项目时,它会打开第二个JFrame,并逐行打印文本文件的内容。

如果您选择了另一个选项(在同一会话中),它应该更改JFrame标题(这是有效的),并打印另一个文本文件的内容(这不起作用)。

我已经明确指出了问题所在,但我不知道为什么会出现这个问题。发生的情况是,代码在第一次显示文本文件的内容时工作得很好。然而,第二次它并没有改变文本。

评论中描述了我在第二次中发现的情况。从setDocument方法开始,然后转到paintComponent方法。

这是有问题的类(该程序还有其他几个类,但问题仅在这个类中)。。。

package PeriodicTable;
import javax.swing.JPanel;
import java.util.ArrayList;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.awt.Graphics;
import java.awt.Color;
import java.lang.Override;
class DocumentPanel extends JPanel {
private ArrayList<String> aryDocument;
DocumentPanel(){
super();
setBackground(Color.white);
}
@Override
protected void paintComponent(Graphics gr){
super.paintComponent(gr);
//aryDocument holds the contents of the old text file (should have the contents of the other text file)
for(int index = 0; index < aryDocument.size(); index++){
//enters loop, re-prints the old document
gr.drawString(aryDocument.get(index), 5, (index + 1)*10);
}
}
public void setDocument(String strFileDirectory){ //places contents of text file in an array (line by line)
//aryDocument is null at this time
aryDocument = new ArrayList<String>();
//aryDocument is empty at this time
try(BufferedReader reader = new BufferedReader(new FileReader(strFileDirectory))){
for(String strLine; (strLine = reader.readLine()) != null; ){
aryDocument.add(strLine);
}
reader.close();
}catch(IOException ioe){
ioe.printStackTrace();
}
//aryDocument holds the contents of the other text file
this.revalidate();
}
}

下面的方法在一个名为Table的类中(Table实现ActionListener)。这个方法由actionPerformed调用,他使用ActionCommand值来确定什么操作做什么。

private void loadTextFile(String strName, String strFileDirectory){
DocumentPanel clsDocumentPanel = new DocumentPanel();
if(frmDocument == null){
frmDocument = new JFrame(strName);
frmDocument.setPreferredSize(new Dimension(600, 700));
clsDocumentPanel.setDocument(strFileDirectory);
frmDocument.add(clsDocumentPanel);
frmDocument.pack();
frmDocument.setVisible(true);
}else{
if(!(frmDocument.getTitle().equals(strName))){
frmDocument.setTitle(strName);
clsDocumentPanel.setDocument(strFileDirectory);
frmDocument.pack();
frmDocument.setVisible(true);
}
}
}

我已经重新检查了strFileDirectory,并确认它们是正确的值。

我使用的是什么版本/程序等?

Java 8

记事本

命令提示符

我的问题在。。。

为什么当aryDocument进入paintComponent(加载其他文本文件后)时,它的值没有改变?我该怎么修?

此处,

DocumentPanel clsDocumentPanel = new DocumentPanel(); // <- yes, here!
if(frmDocument == null){
frmDocument = new JFrame(strName);
frmDocument.setPreferredSize(new Dimension(600, 700));
clsDocumentPanel.setDocument(strFileDirectory);
frmDocument.add(clsDocumentPanel);
frmDocument.pack();
frmDocument.setVisible(true);
}else{
if(!(frmDocument.getTitle().equals(strName))){
frmDocument.setTitle(strName);
clsDocumentPanel.setDocument(strFileDirectory);
frmDocument.pack();
frmDocument.setVisible(true);
}
}

每次执行操作时,都会创建一个新的DocumentPanel实例。第一次将其添加到frmDocument时。第二次,您只需调用它上的setDocument,并让它被垃圾回收。第一个实例(实际附加到显示的帧)永远不会更新。

因此,

  • clsDocumentPanel单独存储在某个地方,就像将frmDocument存储一样,而不是作为局部变量
  • 使frmDocument成为JFrame子类,公开对其文档面板的访问,并调用frmDocument.getDocumentPanel().setDocument(...)——但这违反了Demeter定律
  • 或者使frmDocument成为JFrame子类,该子类具有仅委托给其面板的setDocumentsetDocument方法,然后仅调用frmDocument.setDocument(...)

最新更新