I'm a Java newbie and I'm working on my first Java project. So far it consists of a GUI with a dynamically generated form (adapted from this question), a Save button and a Load button. With the Save button, the entire form is saved as an object, and with the Load button, an existing saved form can be loaded. Saving and loading themselves seem to work, but the GUI is not updated properly with the loaded form at the point where I (indirectly, i.e. via another function) call revalidate()
and repaint()
within the actionPerformed
method of the Load button:
public class LoadListener extends SingleFileChooser implements ActionListener {
private static final long serialVersionUID = -4418195536438874952L;
private EntryList listFromFile;
private ScrollBar panel;
@SuppressWarnings("hiding")
public LoadListener(String choosertitle, ScrollBar panel) {
super(choosertitle);
this.panel = panel;
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
try {
InputStream is = new FileInputStream(this.getFilePath());
ObjectInputStream ois = new ObjectInputStream(is);
listFromFile = (EntryList) ois.readObject();
ois.close();
panel.setEntryList(listFromFile);
} catch (FileNotFoundException e1) {
System.out.println("File not found: " + this.getFilePath());
e1.printStackTrace();
} catch (IOException e1) {
System.out.println("IO exception: " + this.getFilePath());
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
System.out.println("Class for input object not found: " + this.getFilePath());
e1.printStackTrace();
}
}
public EntryList getLoadedGatingList() {
return listFromFile;
}
}
Herein, panel
is of a subclass of JPanel
:
public class ScrollBar extends JPanel {
private static final long serialVersionUID = -3460555902426579496L;
private JScrollPane scrollPane;
private JButton saveList, loadList;
private EntryList entryList;
@SuppressWarnings("hiding")
public ScrollBar(EntryList entryList, MainFrame frame) {
scrollPane = new JScrollPane(entryList,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new Dimension(300,400));
this.entryList = entryList;
saveList = new JButton("Save List");
saveList.addActionListener(new SaveListener("Save List", this));
loadList = new JButton("Load List");
loadList.addActionListener(new LoadListener("Load List", this));
add(scrollPane);
add(saveList);
add(loadList);
}
public EntryList getEntryList() {
return entryList;
}
public void setEntryList(EntryList list) {
entryList = list;
this.saveList.setBackground(Color.PINK);
this.saveList.setText(entryList.getFirstText());
this.loadList.setBackground(Color.GREEN);
revalidate();
repaint();
}
}
The remaining classes that are needed to run the example are listed below:
public class Entry extends JPanel implements Serializable{
private static final long serialVersionUID = 8748191176188997955L;
private JTextField textField;
private JButton plus;
private JButton minus;
private EntryList parent;
public Entry(String textFieldText, EntryList list) {
this.parent = list;
this.plus = new JButton(new AddEntryAction());
this.minus = new JButton(new RemoveEntryAction());
this.textField = new JTextField(10);
this.textField.setText(textFieldText);
add(this.plus);
add(this.minus);
add(this.textField);
}
public String getText() {
return this.textField.getText();
}
public class AddEntryAction extends AbstractAction {
private static final long serialVersionUID = -1936452299010320790L;
public AddEntryAction() {
super("+");
}
public void actionPerformed(ActionEvent e) {
parent.cloneEntry(Entry.this);
}
}
public class RemoveEntryAction extends AbstractAction {
private static final long serialVersionUID = 4843871176230776949L;
public RemoveEntryAction() {
super("-");
}
public void actionPerformed(ActionEvent e) {
parent.removeItem(Entry.this);
}
}
public void enableAdd(boolean enabled) {
this.plus.setEnabled(enabled);
}
public void enableMinus(boolean enabled) {
this.minus.setEnabled(enabled);
}
}
public class EntryList extends JPanel implements Serializable{
private static final long serialVersionUID = 1426379083556312697L;
private List<Entry> entries;
public EntryList() {
this.entries = new ArrayList<Entry>();
Entry initial = new Entry("debugtext", this);
addItem(initial);
}
public int getLength() {
return this.entries.size();
}
public String getFirstText() {
return this.entries.get(0).getText();
}
public void cloneEntry(Entry entry) {
Entry theClone = new Entry("", this);
addItem(theClone);
}
private void addItem(Entry entry) {
entries.add(entry);
add(entry);
refresh();
}
public void removeItem(Entry entry) {
entries.remove(entry);
remove(entry);
refresh();
}
private void refresh() {
revalidate();
if (entries.size() == 1) {
entries.get(0).enableMinus(false);
}
else {
for (Entry e : entries) {
e.enableMinus(true);
}
}
}
}
public class SaveListener extends DirectoryChooser implements ActionListener {
private static final long serialVersionUID = -8842006866700189526L;
private EntryList list;
private String filename;
public SaveListener(String choosertitle, ScrollBar bar) {
super(choosertitle, false);
this.list = bar.getEntryList();
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
try {
filename = this.getResultsDirectory();
OutputStream os = new FileOutputStream(filename);
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(list);
oos.close();
System.out.println("Length of list at saving = " + this.list.getLength());
System.out.println("Length of list at saving = " + this.list.getFirstText());
} catch (FileNotFoundException e1) {
System.out.println("File not found: " + filename);
e1.printStackTrace();
} catch (IOException e1) {
System.out.println("IO Exception: " + e1);
e1.printStackTrace();
}
}
}
public class DirectoryChooser extends JPanel implements ActionListener {
private static final long serialVersionUID = -8143869075088499054L;
private JButton setwd;
private String workingdir;
private JFileChooser chooser;
private String choosertitle;
private boolean directoryOnly = true;
@SuppressWarnings("hiding")
public DirectoryChooser(String choosertitle) {
this.choosertitle = choosertitle;
setwd = new JButton(choosertitle);
setwd.addActionListener(this);
add(setwd);
workingdir = new File(System.getProperty("user.dir")).toString();
}
@SuppressWarnings("hiding")
public DirectoryChooser(String choosertitle, boolean directoryOnly) {
this(choosertitle);
this.directoryOnly = directoryOnly;
}
public void actionPerformed(ActionEvent e) {
chooser = new JFileChooser();
chooser.setCurrentDirectory(new java.io.File("."));
chooser.setDialogTitle(choosertitle);
if (directoryOnly) {
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
}
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
workingdir = chooser.getSelectedFile().toString();
} else {
workingdir = chooser.getCurrentDirectory().toString();
}
}
public String getResultsDirectory() {
return workingdir;
}
public Dimension getPreferredSize(){
return new Dimension(200, 200);
}
}
public class SingleFileChooser extends JPanel implements ActionListener {
private static final long serialVersionUID = -9068219101747975546L;
private JButton loadFiles;
private JFileChooser chooser;
private String choosertitle;
private File file;
private String filePath;
private FileNameExtensionFilter filter;
@SuppressWarnings("hiding")
public SingleFileChooser(String choosertitle) {
this.choosertitle = choosertitle;
loadFiles = new JButton(choosertitle);
loadFiles.addActionListener(this);
add(loadFiles);
}
@SuppressWarnings("hiding")
public SingleFileChooser(String choosertitle, FileNameExtensionFilter filter) {
this(choosertitle);
this.filter = filter;
}
public void actionPerformed(ActionEvent e) {
chooser = new JFileChooser();
chooser.setMultiSelectionEnabled(false);
if (filter != null) {
chooser.setFileFilter(filter);
}
chooser.setDialogTitle(choosertitle);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
int returnVal = chooser.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION) {
file = chooser.getSelectedFile();
filePath = file.getAbsolutePath();
}
}
public File getFile() {
return file;
}
public String getFilePath(){
return filePath;
}
public Dimension getPreferredSize(){
return new Dimension(200, 200);
}
}
public class MainFrame extends JFrame {
private static final long serialVersionUID = 512941639567306317L;
EntryList panel = new EntryList();
ScrollBar scrollPanel = new ScrollBar(panel, this);
public MainFrame() throws HeadlessException {
this.getContentPane().add(scrollPanel);
this.setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));
}
}
public class GUImain {
public static void main(String[] args) {
MainFrame frame = new MainFrame();
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null); // center the window
}
}
When I execute this code, modify the text in the text field, save the form and load it again, the saved text is not loaded into the text field and the Load button disappears. The Save button, on the other hand, is repainted: It turns pink and gets the correctly loaded content of the text field.
So my question is: How can I get the saved form loaded correctly and prevent buttons from disappearing?