我有一个带有 JMenuBar 的程序。 JMenuBar内部有一个JButton,JButton打开一个JMenu,其中有2个JMenuItems。当您单击其中一项时,它会打开第二个 JFrame,并逐行打印文本文件的内容。
如果您选择其他选项(在同一 session 中),它应该更改 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(...)
——但这违反了得墨忒耳定律; - 或将
frmDocument
设为JFrame
子类,该子类具有仅委托(delegate)给其面板的setDocument
的setDocument
方法,然后只需调用frmDocument.setDocument(...)
。
关于Java - JPanel - 使用数组列表绘制文本文件的内容 - 仅第一次有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37748084/