Java - JPanel - 使用数组列表绘制文本文件的内容 - 仅在第一次有效
Java - JPanel - painting contents of a text file with an arraylist - Only works the first time
我有一个带有 JMenuBar 的程序。 JMenuBar 内部有一个 JButton,JButton 打开一个包含 2 个 JMenuItem 的 JMenu。当您单击其中一项时,它会打开第二个 JFrame,并逐行打印文本文件的内容。
如果您 select 其他选项(在同一个 session 中),它应该更改 JFrame 标题(这行得通),并打印其他文本文件的内容(这行不通)没用)。
我已经查明了问题所在,但我不知道为什么会出现这个问题。发生的事情是代码在第一次显示文本文件的内容时完美运行。但是,第二次它不会更改文本。
我第二次发现的东西在评论中有描述。从 setDocument 方法开始,然后转到 paintComponent 方法。
这是有问题的 class(该程序还有其他几个 class,但问题仅在这个 class 中)...
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();
}
}
以下方法在 class 中称为 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 并确认它们是正确的值。
我在使用什么versions/programs/etc?
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
子类,该子类具有 setDocument
方法,该方法仅委托给其面板的 setDocument
,然后只需调用 frmDocument.setDocument(...)
。
我有一个带有 JMenuBar 的程序。 JMenuBar 内部有一个 JButton,JButton 打开一个包含 2 个 JMenuItem 的 JMenu。当您单击其中一项时,它会打开第二个 JFrame,并逐行打印文本文件的内容。
如果您 select 其他选项(在同一个 session 中),它应该更改 JFrame 标题(这行得通),并打印其他文本文件的内容(这行不通)没用)。
我已经查明了问题所在,但我不知道为什么会出现这个问题。发生的事情是代码在第一次显示文本文件的内容时完美运行。但是,第二次它不会更改文本。
我第二次发现的东西在评论中有描述。从 setDocument 方法开始,然后转到 paintComponent 方法。
这是有问题的 class(该程序还有其他几个 class,但问题仅在这个 class 中)...
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();
}
}
以下方法在 class 中称为 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 并确认它们是正确的值。
我在使用什么versions/programs/etc?
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
子类,该子类具有setDocument
方法,该方法仅委托给其面板的setDocument
,然后只需调用frmDocument.setDocument(...)
。