public class MainFrame extends javax.swing.JFrame {	/**	 * 	 */	private static final long serialVersionUID = 1L;	static private JTable jtbl = new JTable(); // Table that holds the response from the database  	private JFrame jfrm; // The main display Windows	private JPanel orderspnl; // Frame that holds simple text object displaying total open orders.	private JScrollPane jscrlp; // Scrollable from that holds the database table	static private EtsyTable etsyTables; // Abstract table model used to get formatting of table correct	static private SqlEtsy sql; // Sql class used to handle SQL calls	static private JLabel jlbl; // Label used to hold number of open oders	private static long delayRate = 60;			public MainFrame() throws IOException {				 		int rowCount = 0;		int totalOrders[] = new int[2];		int gap = 50;		GridLayout myLayout = new GridLayout (2,1);				// This should set the main row color and an alternate row color.  For reasons beyond me, it only sets the alternate row color.    // Problem persists even when all other renderers are commented out.		try {			UIManager.put("Table.rowColor", new Color (0,0,0));//(219, 250, 255));			UIManager.put("Table.alternateRowColor", new Color (160, 242, 255));		    for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {		        if ("Nimbus".equals(info.getName())) {		            UIManager.setLookAndFeel(info.getClassName());		            		            break;		        }		    }		} catch (Exception e) {		    // If Nimbus is not available, fall back to cross-platform		    try {		        UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());		    } catch (Exception ex) {		        // not worth my time		    }		}				// Create the main frame to display our data		jfrm = new JFrame("All Wrapped Up");		
		// Create a grid 2 rows by 1 column and apply it to the JFrame		jfrm.setLayout(myLayout);		jfrm.setLayout(new FlowLayout());				// Get PNG image and place it as the icon 		BufferedImage img = ImageIO.read(getClass().getResource("/icon.png"));		jfrm.setIconImage(img);				// Exit the application when it is closed		jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);				// Set the JFrame to be the size of the current window    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();    Rectangle maxBounds = env.getMaximumWindowBounds();    jfrm.setBounds(maxBounds);        		// Create an interface to the SQL handler and load all information from the processing_orders database into the table		sql = new SqlEtsy();		etsyTables = new EtsyTable(sql.getAllOrders());
		// Make table filterable and searchable		jtbl = new JTable(etsyTables);		TableFilterHeader filterHeader = new TableFilterHeader(jtbl, AutoChoices.ENABLED);		IFilterEditor editor = filterHeader.getFilterEditor(1);		editor.setEditable(false);				// Any time the table is filtered, immediately update the displayed label text		filterHeader.getTable().getRowSorter().addRowSorterListener(new RowSorterListener() {            @Override            public void sorterChanged(RowSorterEvent e) {            	updateLableContent();            }         });						// Section controls look and feel of the table		// As a general note, I've somewhat complicated the way I call getColumnModel.  Instead of directly telling it the column number		// I have it return the column number associated with a specific header name.  The reason for this is I wanted to make it more robust in the event that		// late on down the road I copied and pasted the "removeColumn" line somewhere above this point.  If I did that, then my hard coded column numbers would be pointing to the 		// incorrect column location.  By using the column name to return the index, it allows me the freedom to move things around without it getting broken.		JTableHeader header = jtbl.getTableHeader(); // Get Table header information		header.setDefaultRenderer(new HeaderRenderer(jtbl)); // Create a new default renderer for the table header		header.setFont(new Font("Arial", Font.BOLD, 15)); // Set the font size and style for the table header		header.setAlignmentX(CENTER_ALIGNMENT); // Set header text to be centered		jtbl.setShowHorizontalLines(true); // Show lines between each row		jtbl.setRowHeight(jtbl.getRowHeight()+gap); // Adjust the row height to accommodate the text size with a little gap		// Make cells around check boxes transparent so row color can be seen.		((JComponent) jtbl.getDefaultRenderer(Boolean.class)).setOpaque(true);		jtbl.setFont(new Font("Arial", Font.PLAIN, 20)); // Sets the font and size for the table cells				MbTableCellRenderer.setCellsAlignment(jtbl, SwingConstants.CENTER); // Centers contents of table cells				MbTableCellRenderer dcRenderer = new MbTableCellRenderer(); // creates a new instance of DateCellREenderer to use with keeping center alignment with date formats  		dcRenderer.setHorizontalAlignment(SwingConstants.CENTER); // set alignment of the tablerenderer to center				// Transaction ID is only used when writing updates back to database, so remove the column				jtbl.removeColumn(jtbl.getColumnModel().getColumn(jtbl.getColumnModel().getColumnIndex("Trans ID"))); 		jtbl.getColumnModel().getColumn(jtbl.getColumnModel().getColumnIndex("Date Ordered")).setCellRenderer(dcRenderer); // Formats the date in a MMM dd format 		jtbl.getColumnModel().getColumn(jtbl.getColumnModel().getColumnIndex("Ship By")).setCellRenderer(dcRenderer); // Formats the date in a MMM dd format				// Button Column is a class that takes a column and adds a button to it.  The variable created is never directly used after the creation, so surpress the warning.		@SuppressWarnings("unused")		ButtonColumn buttonColumn = new ButtonColumn(jtbl, delete, jtbl.getColumnModel().getColumnIndex("Send To Cutter"));								// End of the look and feel section				// Now that jtbl is formated and filled, add it to the scroll panel		jscrlp = new JScrollPane(jtbl);						// Create panel to hold order information		orderspnl = new JPanel();		rowCount = jtbl.getRowCount(); // get total ordered wraps (rows in table)		totalOrders = sql.getOpenOrderCount(); // get total currently open orders		// Add Order information to a label and add label to Jpanel		jlbl = new JLabel("<html><center>There are currently "+ totalOrders[1] + " open orders and <b><font color='green'>" + totalOrders[0] + "</font></b> wraps to be cut.<br/>Currently displaying " + rowCount + " entries.</html>");		jlbl.setFont(new Font("Arial", Font.PLAIN, 20));		orderspnl.add(jlbl);				// The Jpanels to the frame		jfrm.add(jscrlp);		jfrm.add(orderspnl);		jfrm.setVisible(true);				// Pack it in (aka, I have no idea what pack does comment)		jfrm.pack();
		// Set window to maximized		jfrm.setExtendedState(MAXIMIZED_BOTH);				// Get the current size of the window	    Dimension size = maxBounds.getSize();	    Insets insets = jfrm.getInsets(); // Find border area	    if (insets != null) {	    	//  Change size to equal the window's dimensions without the borders, also leave a little extra space on the height for the order information.	        size.height -= (insets.top + insets.bottom)+20+90;	        size.width -= (insets.left+insets.right)+20;	    }
	    // Set the preferred scroll panel size to our new dimensions 		jtbl.setPreferredScrollableViewportSize(size);
	}
	// You know what this is	public static void main(String args[]) {				// Create a timer to execute on a scheduled basis (1 second? 2 Seconds?)		// Timer will be used to update table data		Timer timer = new Timer();
		// Create the window with all it's innards		java.awt.EventQueue.invokeLater(new Runnable () {			public void run() {				try {					new MainFrame();				} catch (IOException e) {					e.printStackTrace();				}			}		});						timer.scheduleAtFixedRate(new TimerTask() {			  @Override			  public void run() {				updateTableContent();							  }			}, delayRate*1000, delayRate*1000); // Timer executes 2 seconds after first called and at a fixd rate of every two seconds after timer is finished.	}				/**	 * Updates the table	 */	public static void updateTableContent() {		int row = jtbl.getSelectedRow(); // Get the currently selected row so we can pick up where we left off in the table after the refresh		etsyTables.update_table(sql.getAllOrders()); // Tell the table to update its data		updateLableContent();		((EtsyTable)jtbl.getModel()).fireTableDataChanged(); // Tell the table that its data may have changed and to check for updates.				// Try to return to the previously selected row.  If filters have been applied it may not be available any longer.		try {			jtbl.setRowSelectionInterval(row, row);		} catch (Exception e) {					}	}		private static void updateLableContent() {		int rowCount = jtbl.getRowCount(); // get total ordered wraps (rows in table)		int[] totalOrders = new int[2];		totalOrders = sql.getOpenOrderCount();// get total currently open orders		jlbl.setText("<html><center>There are currently "+ totalOrders[1] + " open orders and <b><font color='green'>" + totalOrders[0] + "</font></b> wraps to be cut.<br/>Currently displaying " + rowCount + " entries.</html>");	}		// Think about changing the action name.  It doesn't delete the row, it sends a command to cut the wrap.  It just took me forever to get this worked out	// and I'm in no rush to fix it!		// This action is triggered when the "Send to Cutter" button is pressed	final Action delete = new AbstractAction()	{
	/**		 * 		 */		private static final long serialVersionUID = 1L;
		@Override		public void actionPerformed(ActionEvent e) {			// Get the selected row and use it to get the size, mode, and buyer information about the row the button was pressed in.			int row = jtbl.getSelectedRow();			int pcSize = (Integer) jtbl.getValueAt(row, jtbl.getColumnModel().getColumnIndex("Size"));			String pcModel = (String) jtbl.getValueAt(row, jtbl.getColumnModel().getColumnIndex("Model"));			String buyer = (String) jtbl.getValueAt(row, jtbl.getColumnModel().getColumnIndex("Buyer"));			// Confirm that the correct button was pressed			int dialogResult = JOptionPane.showConfirmDialog (null, "Confirm Cutting " + pcSize + " Quart " + pcModel + " for " + buyer + "?","Warning",0);			if(dialogResult == JOptionPane.YES_OPTION){				Runtime rt = Runtime.getRuntime();				try {					// opens Inkscape with the correct svg and send it to the cutter					Process pr = rt.exec("\"C:\\Program Files\\Inkscape\\inkscape.exe\" --verb=org.ekips.filter.plot.noprefs \"\\\\192.168.25.37\\All Wrapped Up\\SVGs\\SVGs for Cutting\\Latest for Scripting\\" + pcModel + " - " + pcSize + " Quart.svg\" --verb=FileClose");					System.out.println(pr);				} catch (IOException e1) {					// TODO Auto-generated catch block					e1.printStackTrace();				}			}						}	};}
package mb.gui;
import java.awt.Color;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.Font;import java.awt.GraphicsEnvironment;import java.awt.GridLayout;import java.awt.Insets;import java.awt.Rectangle;import java.awt.event.ActionEvent;import java.awt.image.BufferedImage;import java.io.IOException;import java.util.Timer;import java.util.TimerTask;
import javax.imageio.ImageIO;import javax.swing.AbstractAction;import javax.swing.Action;import javax.swing.JComponent;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTable;import javax.swing.SwingConstants;import javax.swing.UIManager;
import javax.swing.UIManager.*;import javax.swing.event.RowSorterEvent;import javax.swing.event.RowSorterListener;import javax.swing.table.JTableHeader;
import net.coderazzi.filters.gui.AutoChoices;import net.coderazzi.filters.gui.IFilterEditor;import net.coderazzi.filters.gui.TableFilterHeader;
/** *  The MainFrame class provides an interface for the user to see current order status of Etsy Orders *  It handles all the front end rendering and control * */
public class MainFrame extends javax.swing.JFrame {	/**	 * 	 */	private static final long serialVersionUID = 1L;	static private JTable jtbl = new JTable(); // Table that holds the response from the database  	private JFrame jfrm; // The main display Windows	private JPanel orderspnl; // Frame that holds simple text object displaying total open orders.	private JScrollPane jscrlp; // Scrollable from that holds the database table	static private EtsyTable etsyTables; // Abstract table model used to get formatting of table correct	static private JLabel jlbl; // Label used to hold number of open oders	private static long delayRate = 5;			public MainFrame() throws IOException {				 		int rowCount = 0;		int totalOrders[] = new int[2];		int gap = 50;		GridLayout myLayout = new GridLayout (2,1);				// This should set the main row color and an alternate row color.  For reasons beyond me, it only sets the alternate row color.		try {			UIManager.put("Table.rowColor", new Color (0,0,0));//(219, 250, 255));			UIManager.put("Table.alternateRowColor", new Color (160, 242, 255));		    for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {		        if ("Nimbus".equals(info.getName())) {		            UIManager.setLookAndFeel(info.getClassName());		            		            break;		        }		    }		} catch (Exception e) {		    // If Nimbus is not available, fall back to cross-platform		    try {		        UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());		    } catch (Exception ex) {		        // not worth my time		    }		}				// Create the main frame to display our data		jfrm = new JFrame("All Wrapped Up");		
		// Create a grid 2 rows by 1 column and apply it to the JFrame				jfrm.setLayout(myLayout);		jfrm.setLayout(new FlowLayout());				// Get PNG image and place it as the icon 		//BufferedImage img = ImageIO.read(getClass().getResource("/icon.png"));		//jfrm.setIconImage(img);				// Exit the application when it is closed		jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);				// Set the JFrame to be the size of the current window        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();        Rectangle maxBounds = env.getMaximumWindowBounds();        jfrm.setBounds(maxBounds);        		// Create an interface to the SQL handler and load all information from the processing_orders database into the table        String[] columns = new String[] {                "Id", "Name", "Hourly Rate", "Part Time"            };        Object[][] data = new Object[][] {            {1, "John", 40.0, false },            {2, "Rambo", 70.0, false },            {3, "Zorro", 60.0, true },        };                etsyTables = new EtsyTable(data);        jtbl = new JTable(etsyTables);
		// Make table filterable and searchable		//jtbl = new JTable(etsyTables);		TableFilterHeader filterHeader = new TableFilterHeader(jtbl, AutoChoices.ENABLED);		IFilterEditor editor = filterHeader.getFilterEditor(1);		editor.setEditable(false);				// Any time the table is filtered, immediately update the displayed label text		filterHeader.getTable().getRowSorter().addRowSorterListener(new RowSorterListener() {            @Override            public void sorterChanged(RowSorterEvent e) {            	updateLableContent();            }         });						// Section controls look and feel of the table		// As a general note, I've somewhat complicated the way I call getColumnModel.  Instead of directly telling it the column number		// I have it return the column number associated with a specific header name.  The reason for this is I wanted to make it more robust in the event that		// late on down the road I copied and pasted the "removeColumn" line somewhere above this point.  If I did that, then my hard coded column numbers would be pointing to the 		// incorrect column location.  By using the column name to return the index, it allows me the freedom to move things around without it getting broken.		JTableHeader header = jtbl.getTableHeader(); // Get Table header information		//header.setDefaultRenderer(new HeaderRenderer(jtbl)); // Create a new default renderer for the table header		header.setFont(new Font("Arial", Font.BOLD, 15)); // Set the font size and style for the table header		header.setAlignmentX(CENTER_ALIGNMENT); // Set header text to be centered		jtbl.setShowHorizontalLines(true); // Show lines between each row		jtbl.setRowHeight(jtbl.getRowHeight()+gap); // Adjust the row height to accommodate the text size with a little gap		// Make cells around check boxes transparent so row color can be seen.		((JComponent) jtbl.getDefaultRenderer(Boolean.class)).setOpaque(true);		jtbl.setFont(new Font("Arial", Font.PLAIN, 20)); // Sets the font and size for the table cells				//MbTableCellRenderer.setCellsAlignment(jtbl, SwingConstants.CENTER); // Centers contents of table cells				//MbTableCellRenderer dcRenderer = new MbTableCellRenderer(); // creates a new instance of DateCellREenderer to use with keeping center alignment with date formats  		//dcRenderer.setHorizontalAlignment(SwingConstants.CENTER); // set alignment of the tablerenderer to center				// Transaction ID is only used when writing updates back to database, so remove the column		//		jtbl.removeColumn(jtbl.getColumnModel().getColumn(jtbl.getColumnModel().getColumnIndex("Trans ID"))); 		//jtbl.getColumnModel().getColumn(jtbl.getColumnModel().getColumnIndex("Date Ordered")).setCellRenderer(dcRenderer); // Formats the date in a MMM dd format 		//jtbl.getColumnModel().getColumn(jtbl.getColumnModel().getColumnIndex("Ship By")).setCellRenderer(dcRenderer); // Formats the date in a MMM dd format				// Set table widths numbers were decided largely by trial and error for a minimum 1300 pixel wide screen		
		// Button Column is a class that takes a column and adds a button to it.  The variable created is never directly used after the creation, so surpress the warning.		//@SuppressWarnings("unused")		//ButtonColumn buttonColumn = new ButtonColumn(jtbl, delete, jtbl.getColumnModel().getColumnIndex("Send To Cutter"));								// End of the look and feel section				// Now that jtbl is formated and filled, add it to the scroll panel		jscrlp = new JScrollPane(jtbl);						// Create panel to hold order information		orderspnl = new JPanel();		rowCount = jtbl.getRowCount(); // get total ordered wraps (rows in table)		totalOrders[0] = 3;		totalOrders[1] = 2;//sql.getOpenOrderCount(); // get total currently open orders		//etsyTables.update_table(sql.getAllOrders()); // Tell the table to update its data		updateLableContent();		((EtsyTable)jtbl.getModel()).fireTableDataChanged(); // Tell the table that its data may have changed and to check for updates.				// Try to return to the previously selected row.  If filters have been applied it may not be available any longer.		try {			jtbl.setRowSelectionInterval(row, row);		} catch (Exception e) {					}	}		private static void updateLableContent() {		int rowCount = jtbl.getRowCount(); // get total ordered wraps (rows in table)		int[] totalOrders = new int[2];		totalOrders[0] = 4;		totalOrders[1] = 2;//sql.getOpenOrderCount();// get total currently open orderspackage mb.gui;
import java.util.ArrayList;import java.util.List;
import javax.swing.table.AbstractTableModel;
import mb.gui.MainFrame;
/** *  The EtsyTable class creates a custom table model with the handlers I need to display and set MySQL table data. * */public class EtsyTable extends AbstractTableModel{
	private static final long serialVersionUID = 1L;
	// Column names are  hard coded for the table since I know these are the only column names that will exist within the table.	// There may be a way to dynamically get and set these at runtime, however I found it unnecessary for the scope of this project	public final String[]COLUMN_NAMES= {"Id", "Name", "Hourly Rate", "Part Time" };		// This array list will hold all the information from the SQL query on all order data	private Object[][]orders;			/**	 * Method will take an array list and store it for manipulation and retrieval in the local orders ListArray	 * 	 * @param orders List that holds table data	 */	public EtsyTable(Object[][]orders) {		this.orders=orders;	}	
	/**	 * Sets whether a cell can be edited or not	 * 	 * For future consideration.  I've been a bit lazy and hard coded the conditions for cells I want to be able to edit 	 * Now clearly I don't really understand how this function works as I never call it and yet it correctly allows only	 *   the cells with check boxes to be edited, but I really have no idea why.	 * 	 * @param row The specified table row	 * @param col The specified table column	 * @param return returns if the cell can be edited	 */	public boolean isCellEditable(int row, int col)	{ 		String colName = getColumnName(col);		if ((colName == "Sticky Note")||(colName == "Cut")||(colName == "Magnet")||(colName == "Boxed")|| (colName == "Shipped")|| (colName == "Send To Cutter") ){			return true; 		} else {			return false;		}	}		/**	 * @param value The value of the edit, is of type "Object" to allow any datatype to use this one function rather than recreating it for each type	 * @param row The specified table row	 * @param col The specified table column	 */	public void setValueAt(Object value, int row, int col) 	{		boolean updateSuccessful = false;		// Create SQL connection, we do not need to call the close function as it will automatically be called as part of the writeCellContents		//SqlEtsy sql = new SqlEtsy();				// Get the column name so we can update the correct column in the sql table		String colName = getColumnName(col);				// We only need to execute this if the column being edited is one of the check box columns		if ((colName == "Sticky Note")||(colName == "Cut")||(colName == "Magnet")||(colName == "Boxed")|| (colName == "Shipped") ){			//String trans_id = orders.get(row).getTransId(); // Get the transaction id, it is used to correctly update the associated MySQL table row			//updateSuccessful = sql.writeCellContents(colName, trans_id,((boolean) value)); // Call the SQL update function
			// After the cell has been updated, get the updated values from the table and show in the table			// This is included as one could potentially set the update time to a high value which would delay in showing the			// updated check box for quite a while.			// Only call if the SQL update was successful			if (updateSuccessful) {				MainFrame.updateTableContent();								// These two lines have been commented out as I test to see if the new updateTableContents function works as expected				// Now instead of firing updates from multiple points, I update it in one function and call it where required.								//this.update_table(sql.getAllOrders()); 			    //this.fireTableDataChanged(); 			}					}		 }
	/**	 * 	 * @param orders Updated table information from MySQL	 * @return updated list	 * 	 * Initially I had it set up as:	 * 		public List<OrderTracking> update_Table(List<OrderTracking>orders)	 * however after thinking about it I realized that I was not sure if I actually need to return anything.	 * I have commented out the return line and set the return to void, so far is appears to be working. 	 */	public void update_table(Object[][]orders) {		this.orders = orders;	}		/**	 * Basic overrides for AbstractTable Model	 */	@Override	public int getColumnCount() {		return COLUMN_NAMES.length;	}
	@Override	public int getRowCount() {		return orders.length;	}	
	@Override	public Object getValueAt(int rowIndex, int columnIndex) {				return orders.length;		}			@Override	public String getColumnName (int column) {		return COLUMN_NAMES[column];	}		// End of basic overrides
	/**	 * 	 * Method searches the column names array for a specific column.  If the column exists it returns the string value.	 * 	 * @param column Name of column to search for	 * @return the column name if found otherwise a blank string	 */	public String getColumnNames (String column) {		int index = -1;		for (int i=0;i<COLUMN_NAMES.length;i++) {			if (COLUMN_NAMES[i].equals(column)) {				index = i;			}		}		if (index == -1) {			return "";		} else {			return COLUMN_NAMES[index];		}	}		/**	 *  Method returns the class type of each column.  It is required to get check boxes to show instead of displaying true/false	 *  	 * @param column the column's index	 * @return the class of the column's datatypes	 */	public Class<?> getColumnClass(int column)    {        for (int row = 0; row < getRowCount(); row++)        {            Object o = getValueAt(row, column);
            if (o != null)            {                return o.getClass();            }        }
        return Object.class;    }
}
	public static void main(String args[]) {				// Create a timer to execute on a scheduled basis (1 second? 2 Seconds?)		// Timer will be used to update table data	//Timer timer = new Timer();		        		 timer = new Timer((int) (delayRate*1000), new ActionListener() {			 @Override			 public void actionPerformed(ActionEvent evt) {				 java.awt.EventQueue.invokeLater(new Runnable () {			            public void run() {			 			            	updateTableContent();			            	timer.stop();			            	timer.restart();			          }				 });			 }		 });		 		timer.start();
		// Create the window with all it's innards		java.awt.EventQueue.invokeLater(new Runnable () {			public void run() {				try {					new MainFrame();									} catch (IOException e) {					e.printStackTrace();				}			}		});	}