/** You may copy this example and use it for any purpose, commercial or otherwise. */ import com.ricebridge.xmlman.*; import java.awt.*; import java.awt.event.*; import java.awt.datatransfer.*; import javax.swing.*; import javax.swing.table.*; import javax.swing.border.*; import java.io.*; import java.util.*; import java.util.List; /** This is a little Swing application that shows you how to load and * save XML data into a JTable using XML Manager. The user selects * an XML file to load, enters the XPath expressions to apply to * the XML, and views the results in a table. The data can then be * edited and saved using the same XPath expressions. The data can * also be cut-and-pasted into a spreadsheet. * * To compile and run this program, you will need to include xmlman.jar * (in the lib folder of the XML Manager distribution) in your CLASSPATH. */ public class SwingTable { // Start the application. public static void main( String[] pArgs ) throws Exception { SwingTable rtm = new SwingTable(); } // Some static definitions. private static Font sLabelFont = new Font("SansSerif",0,11); private static Font sInputFont = new Font("Monospaced",0,11); // These are the main application logic veriables. private XmlManager iXmlManager = null; private RecordSpec iRecordSpec = null; private File iXmlFile = null; // These are the user interface variables private JFrame iMainFrame = null; private JTable iTable = null; private JFileChooser iFileChooser = null; private JTextField iRecordPath = null; private List iFieldPaths = null; private JToolBar iSpecBar = null; private JButton iReloadButton = null; private Clipboard iClipboard = null; /** Create the user interface and set up XML Manager. */ public SwingTable() throws Exception { // System integration. iClipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() ); // Set up XML Manager. // We turn off namespaces as the application has no facility to change them. // We also make the table editable. iXmlManager = new XmlManager(); iXmlManager.getXmlSpec().setNamespaceAware(false); iXmlManager.getXmlSpec().setProperty( "TableModel.editable", true ); // The rest of this method builds the user interface. iMainFrame = new JFrame("SwingTable"); iMainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); iFieldPaths = new ArrayList(); Box toolbox = new Box( BoxLayout.Y_AXIS ); toolbox.add( Box.createVerticalStrut(5) ); toolbox.add( makeLoadBar() ); toolbox.add( Box.createVerticalStrut(5) ); toolbox.add( makeSpecBar() ); makeTable(); JScrollPane ts = new JScrollPane( iTable ); iTable.setPreferredScrollableViewportSize(new Dimension(800, 300)); iMainFrame.getContentPane().add( toolbox, BorderLayout.NORTH); iMainFrame.getContentPane().add( ts, BorderLayout.CENTER); iMainFrame.pack(); iMainFrame.setVisible(true); } /** Build the data table, and add the cut and paste functionality. */ public void makeTable() { iTable = new JTable(); iTable.setRowSelectionAllowed(true); iTable.setColumnSelectionAllowed(true); iTable.setCellSelectionEnabled(true); ActionMap am = iTable.getActionMap(); am.put( "selectall", new AbstractAction() { public void actionPerformed( ActionEvent pEvent ) { iTable.selectAll(); } }); am.put( "copy", new AbstractAction() { public void actionPerformed( ActionEvent pEvent ) { int[] rows = iTable.getSelectedRows(); int[] cols = iTable.getSelectedColumns(); if( 0 < rows.length && 0 < cols.length ) { copy( rows[0], cols[0], rows[rows.length-1]+1, cols[cols.length-1]+1 ); } } }); am.put( "paste", new AbstractAction() { public void actionPerformed( ActionEvent pEvent ) { try { int[] srows = iTable.getSelectedRows(); int[] scols = iTable.getSelectedColumns(); if( 0 < srows.length && 0 < scols.length ) { int sr = srows[0]; int sc = scols[0]; int mr = iTable.getRowCount() - sr; int mc = iTable.getColumnCount() - sc; String datastr = (String)( iClipboard.getContents(this).getTransferData(DataFlavor.stringFlavor) ); String[] rows = datastr.split("\n"); for( int r = 0; r < rows.length && r < mr; r++ ) { String[] cols = rows[r].split("\t"); for( int c = 0; c < cols.length && c < mc; c++ ) { iTable.setValueAt( cols[c], sr+r, sc+c ); } } } } catch( Exception e ) { displayError( "Could not transfer data: "+e.getMessage() ); } } }); KeyStroke selectall = KeyStroke.getKeyStroke(KeyEvent.VK_A,ActionEvent.CTRL_MASK,false); KeyStroke copy = KeyStroke.getKeyStroke(KeyEvent.VK_C,ActionEvent.CTRL_MASK,false); KeyStroke paste = KeyStroke.getKeyStroke(KeyEvent.VK_V,ActionEvent.CTRL_MASK,false); InputMap im = iTable.getInputMap(); im.put( selectall, "selectall"); im.put( copy, "copy"); im.put( paste, "paste"); } /** Create the top row of buttons, and define their actions. */ public JToolBar makeLoadBar() { JToolBar toolbar = new JToolBar(); new BoxLayout( toolbar, BoxLayout.X_AXIS ); JButton reloadB = new JButton( "Reload" ); reloadB.setPreferredSize( new Dimension(50,20) ); reloadB.setEnabled(false); // enabled when we've loaded a file JButton loadB = new JButton( "Load XML File" ); loadB.setPreferredSize( new Dimension(100,20) ); JButton saveB = new JButton( "Save XML File" ); saveB.setPreferredSize( new Dimension(100,10) ); JButton viewB = new JButton( "View XML File" ); viewB.setPreferredSize( new Dimension(100,10) ); JButton genrsB = new JButton( "Show RecordSpec" ); genrsB.setPreferredSize( new Dimension(150,10) ); JButton copyB = new JButton( "Copy Table" ); copyB.setPreferredSize( new Dimension(100,10) ); reloadB.addActionListener( new AbstractAction() { public void actionPerformed( ActionEvent e ) { try { if( null != iXmlFile ) { load( iXmlFile ); } } catch( XmlManagerException xme ) { displayError( xme.getUserMessage() ); } } } ); loadB.addActionListener( new AbstractAction() { public void actionPerformed( ActionEvent e ) { try { File xmlFile = askForXmlFile( true ); if( null != xmlFile ) { load( xmlFile ); } } catch( XmlManagerException xme ) { displayError( xme.getUserMessage() ); } } } ); saveB.addActionListener( new AbstractAction() { public void actionPerformed( ActionEvent e ) { try { File xmlFile = askForXmlFile( false ); if( null != xmlFile ) { save( xmlFile ); } } catch( XmlManagerException xme ) { displayError( xme.getUserMessage() ); } } } ); // View the current file if there is one, otherwise ask the user for a file. viewB.addActionListener( new AbstractAction() { public void actionPerformed( ActionEvent e ) { try { File xmlFile = null; if( null == iXmlFile ) { xmlFile = askForXmlFile( false ); } else { xmlFile = iXmlFile; } show( xmlFile.getName(), readFile( xmlFile ), 500, 500 ); } catch( XmlManagerException xme ) { displayError( xme.getUserMessage() ); } } } ); // Generate the Java source code to define the current RecordSpec. genrsB.addActionListener( new AbstractAction() { public void actionPerformed( ActionEvent e ) { try { RecordSpec rs = makeRecordSpec(); StringBuffer rscode = new StringBuffer( " new RecordSpec( \"" ); rscode.append( iRecordPath.getText().replaceAll("\"","\\n") ); rscode.append( "\", new String[] { " ); for( int fI = 0; fI < iFieldPaths.size(); fI++ ) { rscode.append( 0