/*  J2TablePrinter Test Application
    (C) Copyright 2007
    Wildcrest Associates
    http://www.wildcrest.com
This source code may be freely used, modified, incorporated, and
distributed without restriction as part of any software that uses
J2PrinterWorks by Wildcrest Associates.
*/

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.io.*;
import java.util.*;
import com.wildcrest.j2printerworks.*;

public class J2TablePrinterTestApplication extends JFrame {

   public J2TablePrinterTestApplication() {
      getContentPane().setLayout(new BorderLayout(0, 0));
      setSize(800, 527);
      JPanel0.setDoubleBuffered(false);
      JPanel0.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
      getContentPane().add(BorderLayout.NORTH, JPanel0);
      JButton0.setText("New directory");
      JButton0.setActionCommand("Print");
      JPanel0.add(JButton0);
      JScrollPane1.setOpaque(true);
      getContentPane().add(BorderLayout.CENTER, JScrollPane1);
      JTable1.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
      JScrollPane1.getViewport().add(JTable1);
      JTable1.setFont(new Font("Dialog", Font.PLAIN, 11));
      JTable1.setBounds(0, 0, 0, 0);
      JPanel1.setAlignmentY(0.0F);
      JPanel1.setLayout(new BoxLayout(JPanel1, BoxLayout.X_AXIS));
      getContentPane().add(BorderLayout.SOUTH, JPanel1);
      JButton1.setText("Print");
      JButton1.setActionCommand("Print");
      JPanel1.add(JButton1);
      JButton2.setText("Print Preview");
      JButton2.setActionCommand("Print");
      JPanel1.add(JButton2);
      JButton3.setText("Simple Page Setup");
      JButton3.setActionCommand("Print");
      JPanel1.add(JButton3);
      JButton4.setText("Detailed Page Setup");
      JButton4.setActionCommand("Print");
      JPanel1.add(JButton4);
      JLabelSpacer.setText("  ");
      JPanel1.add(JLabelSpacer);
      JPanel1.add(JLabel1);

      //System.out.println(System.getProperty("java.version"));
      JButton0.setFocusPainted(false); // turn off "has focus" display

      printer = new J2Printer();

      printer.setLeftMargin(0.25); printer.setRightMargin(0.25); printer.setTopMargin(0.25); printer.setBottomMargin(0.25);
      printer.addPropertyChangeListener(new MyPrintingEventHandler());

      directory = new File(".");
      if (System.getProperty("os.name").startsWith("Windows")) directory = new File("C:\\");

      // Automatically starts up with C: directory (or ".")/
      // Reenable the following 5 lines to prompt for directory at beginning
      /*
             JFileChooser chooser = new JFileChooser();
             chooser.setCurrentDirectory(directory);
             chooser.setFileSelectionMode(chooser.DIRECTORIES_ONLY);
             chooser.setDialogTitle("Select a directory then Open");
             if (chooser.showOpenDialog(getParent())==JFileChooser.APPROVE_OPTION) directory = chooser.getSelectedFile();
      */

      setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
      attributes = readDirectory(directory);
      JTable1.setModel(new MyTableModel(attributes));
      adjustColumnWidths(JTable1);

      addRowHeader();

      // variable row height test, uses new setRowHeight(int) method, only compiles and runs under JDK 1.3
      //java.util.Random rand = new java.util.Random();
      //for (int i=0; i<JTable1.getRowCount(); i++) {
      //    int height = 12 + (Math.abs(rand.nextInt()) % 32);    // uniformly distributed numbers on [12,43]
      //    JTable1.setRowHeight(i,height);
      //}

      // variable header height test
      //JTableHeader jth = JTable1.getTableHeader();
      //Dimension size = new Dimension(jth.getSize().width, 50);
      //jth.setPreferredSize(size);
      //JTable1.setTableHeader(jth);

      repaint();
      setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

      /* some useful code so you can detect clicking on different cells within the JTable
      JTable1.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
         public void valueChanged(ListSelectionEvent e) {
         int colIndex = JTable1.getSelectedColumn();
         int rowIndex = JTable1.getSelectedRow();
         System.out.println("clicked on col, row: " + colIndex + " " + rowIndex);
      }});
      */

      // test n-up: printer.setNup(9);

      // locale tests (either of the next two lines work):
      //java.util.Locale.setDefault(java.util.Locale.FRANCE); // set overall default locale...
      //printer.setLocale(java.util.Locale.FRANCE);           // ...or set locale for the printer
      //java.util.Locale.setDefault(new java.util.Locale("nl","NL")); // use this style if Locale not predefined in Java
      //java.util.Locale.setDefault(new java.util.Locale("el","GR")); // use this style if Locale not predefined in Java

      tablePrinter = new J2TablePrinter();
      tablePrinter.setAutomaticRecalculation(false);
      //tablePrinter.setBreakOnColorIncrement(10);
      tablePrinter.setTable(JTable1);

      //test null TableHeader:  JTable1.setTableHeader(null);

      //test print area feature: tablePrinter.setPrintArea(0, 0, JTable1.getColumnCount(), 5);

     /* 0 row test
       Object[] columns = {"This", "is", "a", "JTable"};
       Object[][] data = {};
       JTable table = new JTable(data, columns);
       JScrollPane scrollPane = new JScrollPane(table);
       scrollPane.setPreferredSize(new Dimension(400, 83));
       tablePrinter.setTable(table);
     */

      // Java-style borders don't work right, see Bug Parade 4307724 and 4222732!
      // Java-style border: JTable1.setBorder(new javax.swing.border.LineBorder(Color.green,20));
      // J2PW-style border: tablePrinter.setOutsideLines(true);   // this works OK

      // test handling of intercell spacing and row margin values
      //JTable1.setRowMargin(5);        // rowMargin automatically updates intercellSpacing.height
      //Dimension ics = JTable1.getIntercellSpacing();
      //ics.height = 10;
      //ics.width = 10;
      //JTable1.setIntercellSpacing(ics);
      //printer.setPrintPreviewScale(2.0);     // useful to see print image magnified when debugging

      // test non-GUI (not displayed, data only) JTable:
      //JTable table2 = new JTable();
      //table2.setBounds(0,0,200,200);   // required
      //table2.setModel(JTable1.getModel());
      //tablePrinter.setTable(table2);

      // code for testing outside line drawing
      //tablePrinter.setShowOutsideLines(false);  // test outside lines feature
      //tablePrinter.setPrintArea(1,1,3,3);       // test print area feature

      SymAction lSymAction = new SymAction();
      JButton1.addActionListener(lSymAction);
      JButton2.addActionListener(lSymAction);
      JButton3.addActionListener(lSymAction);
      JButton4.addActionListener(lSymAction);
      JButton0.addActionListener(lSymAction);

      printer.setPrintPreviewScale(1.0);

      // set up J2FlowPrinter consisting of a title (JTextPane in a J2TextPrinter), followed by the table
      // (in a J2TablePrinter), followed by a caption JTextPane in a J2TextPrinter)
      flowPrinter = new J2FlowPrinter();
      JTextPane title = J2TextPrinter.makeHTMLPane("<html><center><h1>Table 1: J2TablePrinter Test"
                                                   + "<h3>Demonstration of JTable printing capability</html>");
      flowPrinter.setFlowable(new J2TextPrinter(title));
      flowPrinter.addFlowable(tablePrinter);
      JTextPane caption = J2TextPrinter.makeHTMLPane("<html>"
                                  + "<small>This output is a J2FlowPrinter consisting of a title "
                                  + "(a JTextPane defined using HTML "
                                  + "in a J2TextPrinter instance), followed by the table itself (a JTable in a "
                                  + "J2TablePrinter instance), followed by this caption (a second JTextPane "
                                  + "defined using HTML "
                                  + "in a second J2TextPrinter instance.  The \"Flowable\" mechanism of "
                                  + "J2PrinterWorks makes it easy to add titles and captions to tables "
                                  + "and images.<br></small></html>");
      flowPrinter.addFlowable(new J2TextPrinter(caption));

      //test: flowPrinter.addFlowable(new J2ComponentPrinter(JTable1.getTableHeader()));
   }


   class MyTableModel extends AbstractTableModel {
     String[] columnNames = {"Name", "Length", "Last modified", "Directory",
         "Read", "Write", "Hidden", "Path"};
      Vector[] attributes;
      MyTableModel(Vector[] attributes) { this.attributes = attributes; }
      public int getColumnCount() { return columnNames.length; }
      public int getRowCount() { return attributes[0].size(); }
      public String getColumnName(int col) { return columnNames[col]; }
      public Object getValueAt(int row, int col) { return attributes[col].elementAt(row); }
      public Class getColumnClass(int col) { return getValueAt(0, col).getClass(); }
      public boolean isCellEditable(int row, int col) { return true; }
      public void setValueAt(Object value, int row, int col) {
         attributes[col].setElementAt(value, row);
         fireTableCellUpdated(row,col);
      }
   }

   ImageIcon getImageIcon(String fileName) {
      return new ImageIcon(new File(".").getAbsolutePath() + "\\" + fileName);
      //java.net.URL url = this.getClass().getResource(fileName); // works either from .jar or loose files
      //return new ImageIcon(this.getClass().getResource(fileName)); // works either from .jar or loose files
   }

   Vector[] readDirectory(File directory) {
      Vector[] attributes = new Vector[8];
      ImageIcon check = getImageIcon("images" + File.separator + "check.gif");
      ImageIcon ex = getImageIcon("images" + File.separator + "ex.gif");
      ImageIcon red = getImageIcon("images" + File.separator + "red-ball.gif");
      ImageIcon yellow = getImageIcon("images" + File.separator + "yellow-ball.gif");
      ImageIcon green = getImageIcon("images" + File.separator + "green-ball.gif");
      ImageIcon white = getImageIcon("images" + File.separator + "white-ball.gif");

      for (int i = 0; i < 8; i++) attributes[i] = new Vector();
      String path = directory.getPath();
      String[] contents = directory.list();
      for (int i=0; i<contents.length; i++) {
         String fullName = path + File.separator + contents[i];
         File f = new File(fullName);
         attributes[0].addElement(f.getName());
         attributes[1].addElement(new Long(f.length()));
         attributes[2].addElement(new Date(f.lastModified()).toString());

         // simple text versions:
         //attributes[3].addElement(new Boolean(f.isDirectory()).toString());
         //attributes[4].addElement(new Boolean(f.canRead()).toString());
         //attributes[5].addElement(new Boolean(f.canWrite()).toString());
         //attributes[6].addElement(new Boolean(f.isHidden()).toString());

         // boolean test (except JDK 1.2.2 has a bug printing JCheckBox in JTable)
         attributes[3].addElement(new Boolean(f.isDirectory()));
         attributes[4].addElement(new Boolean(f.canRead()));
         attributes[5].addElement(new Boolean(f.canWrite()));
         attributes[6].addElement(new Boolean(f.isHidden()));

         // fancy image versions (nice but 3-4X slower on JDK 1.2.2):
    //     attributes[3].addElement(f.isDirectory() ? check : white);
    //     attributes[4].addElement(f.canRead() ? green : red);
    //     attributes[5].addElement(f.canWrite() ? green : red);
    //     attributes[6].addElement(f.isHidden() ? yellow : white);

         attributes[7].addElement(f.getPath());
      }
      return attributes;
   }


   void adjustColumnWidths(JTable table) {
      boolean stringCol[] = {true, false, true, false, false, false, false, true};
      int[] headerWidths = {33, 39, 77, 50, 35, 35, 40, 26}; // hard-coded header widths (yuck, see below)
      for (int i = 0; i < table.getColumnCount(); i++) {
         TableColumn column = table.getColumnModel().getColumn(i);
         Component comp;
         String javaVersion = System.getProperty("java.version");

         // incompatible change from JDK 1.2 to 1.3 (see Bug Parade 4276838)!!!  won't compile under JDK 1.2
         //if (javaVersion.startsWith("1.2"))
         // the next line works under 1.2 (won't run under 1.3 or 1.4)
         //    comp = column.getHeaderRenderer()
         //        .getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0);
         //else
         // the next line works only under JDK 1.3 or 1.4 (won't compile under 1.2)
         //    comp = table.getTableHeader().getDefaultRenderer()
         //        .getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0);
         //int headerWidth = comp.getPreferredSize().width+10;
         //
         // to provide sample code that will compile and run under both 1.2 and 1.3, we will hard-code column width values (yuck):
         int headerWidth = headerWidths[i] + 5;

         TableModel model = table.getModel();
         Object longest;
         if (stringCol[i]) {
            String longestStr = "";
            for (int j = 0; j < model.getRowCount(); j++)
               if ( ( (String) (model.getValueAt(j, i))).length() > longestStr.length())
                  longestStr = (String) (model.getValueAt(j, i));
            longest = longestStr;
         }
         else
            longest = model.getValueAt(0, i);

         comp = table.getDefaultRenderer(model.getColumnClass(i))
             .getTableCellRendererComponent(table, longest, false, false, 0, i);
         int cellWidth = comp.getPreferredSize().width;

         column.setPreferredWidth(Math.max(headerWidth, cellWidth));
      }
      return;
   }


   void addRowHeader() { // contains code for two alternative methods: JList-based and JTable-based
     /*
       // JList-based row headers code (assumes uniform row height and empty upper left box!)
           ListModel lm = new AbstractListModel() {
             public Object getElementAt(int index) { return "File: " + (index+1); }
             public int getSize() { return JTable1.getRowCount(); }
           };
           JList rowHeader = new JList(lm);

           ListCellRenderer lcr = new ListCellRenderer() {
             public Component getListCellRendererComponent(JList list,
                 Object value, int index, boolean isSelected, boolean cellHasFocus) {
                    JLabel label = new JLabel();
                    JTableHeader header = JTable1.getTableHeader();
                    label.setOpaque(true);
                    label.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
                    label.setHorizontalAlignment(JLabel.CENTER);
                    label.setForeground(header.getForeground());
                    label.setBackground(header.getBackground());
                    label.setFont(header.getFont());
                    label.setText( (value == null) ? "" : value.toString());
                    return label;
             }
           };

           rowHeader.setFixedCellWidth(50);
           rowHeader.setFixedCellHeight(JTable1.getRowHeight() + JTable1.getRowMargin() - 1);
           rowHeader.setCellRenderer(lcr);
           JScrollPane1.setRowHeaderView(rowHeader);

      // end JList-based row header code
     */

///*
// JTable-based row headers code (supports variable row height and upper left box)
           int numRows = JTable1.getRowCount();
           String[][] rowHeaders = new String[numRows][1];
           for (int i=0; i<numRows; i++) rowHeaders[i] = new String[] { "File: " + (i+1) };
           String[] headerHeader = {"My table"};
           JTable rowHeader = new JTable(rowHeaders, headerHeader);

           JTable1.setSelectionModel(rowHeader.getSelectionModel()); // keep selections in synch
           // but drag scroll in row header doesn't scroll body = Bug Parade 4202002

           rowHeader.setBackground(Color.lightGray);
           rowHeader.setColumnSelectionAllowed(false);
           rowHeader.setCellSelectionEnabled(false);
           JTableHeader header = JTable1.getTableHeader();
           rowHeader.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
           rowHeader.setForeground(header.getForeground());
           rowHeader.setBackground(header.getBackground());
           rowHeader.setFont(header.getFont());

           // set some variable row heights to test
      /*     JTable1.setRowHeight(3, 35); rowHeader.setRowHeight(3, 35);
           JTable1.setRowHeight(7, 25); rowHeader.setRowHeight(7, 25);
           JTable1.setRowHeight(13, 40); rowHeader.setRowHeight(13, 40);
           JTable1.setRowHeight(25, 35); rowHeader.setRowHeight(25, 35);
           JTable1.setRowHeight(40, 25); rowHeader.setRowHeight(40, 25);
           JTable1.setRowHeight(52, 40); rowHeader.setRowHeight(52, 40);
*/
           // add some exaggerated row heights for subdivide row/col testing
       //    int large = 60;
       //    JTable1.setRowHeight(15,large); rowHeader.setRowHeight(15,large);
       //    JTable1.setRowHeight(16,large); rowHeader.setRowHeight(16,large);
       //    JTable1.setRowHeight(17,large); rowHeader.setRowHeight(17,large);
       //    JTable1.setRowHeight(18,large); rowHeader.setRowHeight(18,large);

           JViewport jv = new JViewport();
           jv.setView(rowHeader);
           jv.setPreferredSize(new Dimension(50, 0));

           JScrollPane1.setRowHeader(jv);
           JScrollPane1.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER,rowHeader.getTableHeader());
    // end JTable-based row header code
    //*/
   }


   javax.swing.JButton JButton0 = new javax.swing.JButton();
   javax.swing.JScrollPane JScrollPane1 = new javax.swing.JScrollPane();
   javax.swing.JTable JTable1 = new javax.swing.JTable();
   javax.swing.JPanel JPanel0 = new javax.swing.JPanel();
   javax.swing.JPanel JPanel1 = new javax.swing.JPanel();
   javax.swing.JButton JButton1 = new javax.swing.JButton();
   javax.swing.JButton JButton2 = new javax.swing.JButton();
   javax.swing.JButton JButton3 = new javax.swing.JButton();
   javax.swing.JButton JButton4 = new javax.swing.JButton();
   javax.swing.JLabel JLabelSpacer = new javax.swing.JLabel();
   javax.swing.JLabel JLabel1 = new javax.swing.JLabel();

   J2Printer printer;
   J2TablePrinter tablePrinter;
   J2FlowPrinter flowPrinter;
   File directory;
   Vector[] attributes;

   class MyPrintingEventHandler extends PrintingEventHandler {
      int totalPages;

      public void printingStart() {
         showProgress("About to print..."); // printing started
         totalPages = printer.getPageable().getNumberOfPages(); // expensive so do only once
      }

      public void printingDone() {
         windowToFront(); // needed prior to JDK 1.4.1 due to Bug Parade #4514422
         brieflyShowProgress("Printing done");
      }

      public void printDialogOK() {
         windowToFront(); // needed prior to JDK 1.4.1 due to Bug Parade #4514422
         showProgress("Start printing...");
      }

      public void printDialogCanceled() {
         windowToFront(); // needed prior to JDK 1.4.1 due to Bug Parade #4514422
         brieflyShowProgress("Printing canceled");
      }

      public void pageSetupDialogOK() {
         brieflyShowProgress("Page setup dialog OK");
      }

      public void pageSetupDialogCanceled() {
         brieflyShowProgress("Page setup dialog canceled");
     }

      public void pageStart(int pageNum) {
        showProgress("Printing page " + pageNum + " of " + totalPages);
      }

   }

   private void showProgress(String str) { JLabel1.setText(str); }

   private void brieflyShowProgress(String str) {
      showProgress(str);
      new Thread() { public void run() {
          try { sleep(1500); } catch (Exception e) {}
          SwingUtilities.invokeLater( new Runnable() { public void run() { showProgress(" "); } } );
      } }.start();    // from different thread, wait 1 sec then erase
   }

   void windowToFront() { this.toFront(); }        // needed under JDK 1.4 due to Bug Parade #4514422


   class SymAction implements java.awt.event.ActionListener {
      public void actionPerformed(java.awt.event.ActionEvent event) {
         Object object = event.getSource();
         if (object == JButton1) JButton1_actionPerformed(event);
         else if (object == JButton2) JButton2_actionPerformed(event);
         else if (object == JButton3) JButton3_actionPerformed(event);
         else if (object == JButton4) JButton4_actionPerformed(event);
         else if (object == JButton0) JButton0_actionPerformed(event);
      }
   }

   void JButton1_actionPerformed(java.awt.event.ActionEvent event) {
     tablePrinter.setTable(JTable1); // recalculates row and column size in case changed
     tablePrinter.setHorizontalPageRule(J2TablePrinter.SHRINK_TO_FIT);
     printer.print(flowPrinter);
   }

   void JButton2_actionPerformed(java.awt.event.ActionEvent event) {
     tablePrinter.setTable(JTable1); // recalculates row and column size in case changed
     printPreview();
   }

   void printPreview() {
      // test custom print preview page setup dialog:
      J2TablePrinterPageSetupDialog J2TablePrinterPageSetupDialog1 = new
          J2TablePrinterPageSetupDialog(printer, tablePrinter);
      J2TablePrinterPageSetupDialog1.setModal(true);
      J2TablePrinterPageSetupDialog1.setTitle("Page Setup");
      printer.setPrintPreviewPageSetupDialog(J2TablePrinterPageSetupDialog1);

      // test omitting Page Setup button from Print Preview dialog:
      //printer.showPrintPreviewPageSetupButton(false);

      // tests:
      //tablePrinter.setPrintArea(2,10,7,35);
      tablePrinter.setMaximumPaginationGap(.3);
      //tablePrinter.setVerticalAlignment(J2Printer.TOP);
      //tablePrinter.setColumnHeaderPrinting(J2TablePrinter.ALL_PAGES);
      tablePrinter.setColumnHeaderPrinting(J2TablePrinter.TOP_PAGES);
      //tablePrinter.setColumnHeaderPrinting(J2TablePrinter.NO_PAGES);

      //tablePrinter.setRowHeaderPrinting(J2TablePrinter.ALL_PAGES);
      tablePrinter.setRowHeaderPrinting(J2TablePrinter.LEFT_PAGES);
      //tablePrinter.setRowHeaderPrinting(J2TablePrinter.NO_PAGES);

      //tablePrinter.setHorizontalAlignment(J2Printer.LEFT);
      tablePrinter.setHorizontalPageRule(J2TablePrinter.SHRINK_TO_FIT);
      //tablePrinter.setHorizontalPageRule(J2TablePrinter.BREAK_ON_COLUMNS);
      //tablePrinter.setHorizontalPageRule(J2TablePrinter.BREAK_ON_COLOR);
      //tablePrinter.setHorizontalBreakColor(table2.getGridColor());

      //tablePrinter.setVerticalPageRule(J2TablePrinter.SHRINK_TO_FIT);
      //tablePrinter.setVerticalPageRule(J2TablePrinter.BREAK_ON_ROWS);
      tablePrinter.setVerticalPageRule(J2TablePrinter.BREAK_ON_COLOR);
      //tablePrinter.setVerticalBreakColor(JTable1.getGridColor());
      //tablePrinter.setOverlap(true);
      //tablePrinter.setOutsideLines(true);
      //tablePrinter.setMaximumPages(1,0);

      printer.showPrintPreviewDialog(this, flowPrinter);

      /* 0 row, 0 height tests
           J2FlowPrinter flow = new J2FlowPrinter();
       flow.addFlowable(new HorizontalLine(0,30,300,Color.pink));
       // flow.addFlowable(tablePrinter);
       flow.addFlowable(new HorizontalLine(0,0,400,Color.blue));
       flow.addFlowable(new HorizontalLine(0,30,400,Color.green));
       printer.showPrintPreviewDialog(this, flow);
       */

   }

   void JButton3_actionPerformed(java.awt.event.ActionEvent event) {
      // Simple (native) Page Setup:
      printer.showPageSetupDialog();
      windowToFront(); // needed under JDK 1.4 due to Bug Parade #4514422
   }

   void JButton4_actionPerformed(java.awt.event.ActionEvent event) {
      // Detailed Page Setup:
      J2TablePrinterPageSetupDialog J2TablePrinterPageSetupDialog1 = new J2TablePrinterPageSetupDialog(printer, tablePrinter);
      J2TablePrinterPageSetupDialog1.setModal(true);
      J2TablePrinterPageSetupDialog1.setTitle("Page Setup");
      J2TablePrinterPageSetupDialog1.show();
   }

   void JButton0_actionPerformed(java.awt.event.ActionEvent event) {
      // New directory:
      JFileChooser chooser = new JFileChooser();
      if (directory.getParent() == null) chooser.setCurrentDirectory(directory);
      else chooser.setCurrentDirectory(new File(directory.getParent()));

      chooser.setFileSelectionMode(chooser.DIRECTORIES_ONLY);
      chooser.setDialogTitle("Select a directory then Open");
      if (chooser.showOpenDialog(getParent()) != JFileChooser.APPROVE_OPTION) return;

      File newDir = chooser.getSelectedFile();
      if (newDir.equals(directory)) return;
      directory = newDir;

      setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
      attributes = readDirectory(directory);
      TableModel tableModel = new MyTableModel(attributes);
      JTable1.setModel(tableModel);
      tablePrinter.setTable(JTable1);
      adjustColumnWidths(JTable1);
      addRowHeader();
      repaint();
      setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
   }


   static public void main(String args[]) {
      J2TablePrinterTestApplication app = new J2TablePrinterTestApplication();
      app.addWindowListener(new java.awt.event.WindowAdapter() {
         public void windowClosing(java.awt.event.WindowEvent event) {
            System.exit(0); // close the application
         }
      });
      app.setTitle("J2TablePrinter Test Application");
      app.setSize(640, 480);
      app.show();
   }

}
