I have a program with a JMenuBar. Inside the JMenuBar has a JButton, the JButton opens up a JMenu that has 2 JMenuItems. When you click on one of the items, it opens a second JFrame, and prints the contents of a text file line by line.
If you select the other option (in the same session), it should change the JFrame title (this works), and print the contents of the other text file (this doesn't work).
I've pinpointed what the issue is, but I have no clue on why this issue is occurring. What's occurring is the code works perfectly the first time it displays the contents of the text file. However, the second time it does not change the text.
What I've found during the second time is described in the comments. Start at the setDocument method, and then move to the paintComponent method.
Here is the class with the issue (there are several other classes for the program, but the issue is solely within this 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();
}
}
The following method is in a class called Table (Table implements ActionListener). This method is called by actionPerformed, who uses the ActionCommand value to determine what action does what.
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);
}
}
}
I've rechecked strFileDirectory and confirmed they are the correct values.
What versions/programs/etc am I using?
Java 8
Notepad
Command Prompt
My question in clearly stated...
Why isn't aryDocument's value changing when it goes into paintComponent (after loading the other text file)? How can I fix it?
Here,
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);
}
}
you create a new instance of DocumentPanel
each time the action is performed. The first time you add it to frmDocument
. The second time you just call setDocument
on it and let it be garbage collected. The first instance (actually attached to the displayed frame) is never updated.
So, either
clsDocumentPanel
somewhere separately, just like you store frmDocument
, not as a local variable;frmDocument
a JFrame
subclass that exposes access to its document panel and call frmDocument.getDocumentPanel().setDocument(...)
—but this violates Demeter's Law;frmDocument
a JFrame
subclass that has a setDocument
method that just delegates to setDocument
of its panel, then just call frmDocument.setDocument(...)
.