Read a data file into a JTable and reload if data file have changedTag(s): Swing


We use the Observer/Observable mechanism to detect if the data file have been modifed since the last time.

We use the same data file and DataFileTableModel as the previous How-to. Some minor modifications are needed for the DataFileTable class. This class now implements the Observer interface (see the update() method which will be called when the Observable object send a notification).

[DataFileTable.java]

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
import java.util.*;

public class DataFileTable extends JPanel 
    implements Observer {
  protected JTable table;
  protected DataFileTableModel model;

 public DataFileTable(String dataFilePath) {
   DataFileWatchdog  wd;
   Font f;

   f = new Font("SanSerif",Font.PLAIN,24);
   setFont(f);
   setLayout(new BorderLayout());

   model = new DataFileTableModel(dataFilePath);

   table = new JTable();
   table.setModel(model);
   table.createDefaultColumnsFromModel();

   JScrollPane scrollpane = new JScrollPane(table);
   add(scrollpane);

   // this watchdog (an Observable object) 
   //   is monitoring any file change
   wd = new DataFileWatchdog(dataFilePath);
   wd.addObserver(this);
   }

 public void update(Observable o, Object arg) {
   // reload data because data file have changed
   model.initVectors();
   table.repaint();
   }

 public Dimension getPreferredSize(){
   return new Dimension(400, 300);
   }
    
 public static void main(String s[]) {
   JFrame frame = new JFrame("Data File Table");
   DataFileTable panel;
        
   panel = new DataFileTable("customers.dat");
   frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
   frame.setForeground(Color.black);
   frame.setBackground(Color.lightGray);
   frame.getContentPane().add(panel,"Center");
       
   frame.setSize(panel.getPreferredSize());
   frame.setVisible(true);
   frame.addWindowListener(new WindowCloser());
   }
 }

class WindowCloser extends WindowAdapter {
 public void windowClosing(WindowEvent e) {
   Window win = e.getWindow();
   win.setVisible(false);
   System.exit(0);
    }
}
The DataFileWatchdog, an Observable object, is simple. We use a Swing Timer to check every second if a given file have changed. If the timestamp is different then the last one, then all registered Observers are notified about it.

[DataFileWatchdog.java]

 import javax.swing.Timer;
 import java.awt.event.*;
 import java.io.*;
 import java.util.*;

 public class DataFileWatchdog extends Observable
     implements ActionListener {
   Timer t = new Timer(1000,this); // check every second
   long lastModified;
   String file;

   DataFileWatchdog (String s) {
     file = s;
     File f = new File(file);
     lastModified = f.lastModified(); // original timestamp
     t.start();
     }

   public void actionPerformed(ActionEvent e) {
     File f = new File(file);
     long actualLastModified = f.lastModified() ;
     if (lastModified != actualLastModified) {
        // the file have changed
        lastModified = actualLastModified;
        setChanged();
        notifyObservers();
        }
     }
}

See also this related howto.


blog comments powered by Disqus