Adding pick maintenance program source code.

This commit is contained in:
Wes
2020-06-05 18:05:08 -04:00
parent d9cb000390
commit f77d8a486e
12 changed files with 3292 additions and 1 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
# Java_Examples # Java Examples
Java code examples Java code examples
File diff suppressed because it is too large Load Diff
+169
View File
@@ -0,0 +1,169 @@
package pickMaint;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Logger;
/**
* This is a quick routine I wrote to automatically run some SQL queries I developed to judge how well the layout/tablet programs are
* performing. It works by figuring out what and how many rows were adjusted by Gloria/Val after the data was submitted from the tablets
* by Chelsea/Traci.
*
* Spits out an excel file for all 3 shifts for each date in the DATE[] constant.
*
* @author Wes
*/
public class Analyze {
private static final int[] DATE = new int[]{ 141117 };
private static final Logger LOGGER = Logger.getLogger(Analyze.class.getName());
private static final String[] COLUMN_NAMES = new String[]{ "DATE", "SHIFT", "LOOM #", "WEAVER #", "HOURS", "PICKS", "HOURS ENTERED", "PICKS ACTUAL", "PICKS ENTERED", "HOUR ADJUSTMENT", "PICK ADJUSTMENT", "DOWN TIME CODE"};
private static final String ROWS_CHANGED_QUERY = "SELECT lddate, "
+ " ldshif, "
+ " ldloom, "
+ " ldweav, "
+ " ldhrs, "
+ " ldpick, "
+ " HOURS, "
+ " pksact, "
+ " pksent, "
+ " ldhrs - HOURS HRS_ADJ, "
+ " ldpick - pksact PKS_ADJ, "
+ " '(' "
+ " || stmdata.iedtfl.iedtcd "
+ " || ') ' "
+ " || stmdata.iedtfl.iedtds dtcode "
+ "FROM stmdata.loomds "
+ " LEFT JOIN stmdata.pksread ON lddate = DATE AND "
+ " ldshif = shift AND "
+ " ldloom = loom "
+ " LEFT JOIN stmdata.IEDTFL ON stmdata.loomds.ldreas = stmdata.iedtfl.iedtcd "
+ "WHERE lddate = ? AND "
+ " ldshif = ? AND "
+ " (ldhrs != HOURS OR "
+ " ldpick != pksact) AND "
+ " NOT (ldweav > 699) AND "
+ " ldloom NOT IN (SELECT ldloom "
+ " FROM stmdata.loomds "
+ " WHERE lddate = ? AND "
+ " ldshif = ? AND "
+ " ldsty1 = ' SAM') "
+ "ORDER BY ldloom ";
private static final String TOTAL_ROWS = "SELECT COUNT(*) total_rows "
+ "FROM stmdata.pksread "
+ "WHERE date = ? AND "
+ " shift = ? ";
public static void main(String[] args) throws SQLException, IOException {
// Register AS400 DB2 driver and open a connection with the AS400
LOGGER.info("Connecting to AS400 as user: WRAY\n");
DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver());
Connection conn = DriverManager.getConnection("jdbc:as400://0.0.0.0", "USER", "PASS");
LOGGER.info("Pre-compiling SQL statements...\n");
PreparedStatement rowsChanged = conn.prepareStatement(ROWS_CHANGED_QUERY, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
PreparedStatement totalRows = conn.prepareStatement(TOTAL_ROWS);
LOGGER.info("Downloading data for all shifts for " + DATE.length + " days...\n");
for (int date : DATE) {
//System.out.println("Date: " + date);
for (int shift = 1; shift < 4; shift++) {
//System.out.println("Shift: " + shift);
rowsChanged.setInt(1, date);
rowsChanged.setInt(2, shift);
rowsChanged.setInt(3, date);
rowsChanged.setInt(4, shift);
totalRows.setInt(1, date);
totalRows.setInt(2, shift);
ResultSet changed = rowsChanged.executeQuery();
ResultSet total = totalRows.executeQuery();
LOGGER.info(((shift == 1) ? "1st" : (shift == 2) ? "2nd" : (shift == 3) ? "3rd" : "") + " shift downloaded. Dumping to Excel sheet...\n");
int tot = 0;
if (total.next())
tot = total.getInt(1);
FileWriter out = new FileWriter(date + "_" + shift + ".xls");
String buffer = "";
for (int i = 0; i < COLUMN_NAMES.length; i++) {
buffer += (COLUMN_NAMES[i] + "\t");
}
out.write(buffer + "\n");
buffer = "";
while (changed.next()) {
for (int i = 0; i < COLUMN_NAMES.length; i++) {
if(i == 11) {
String dt = "" + changed.getObject(i + 1);
if(dt.equalsIgnoreCase("null"))
buffer += (" \t");
else
buffer += (dt.trim() + "\t");
} else {
buffer += (changed.getObject(i + 1) + "\t");
}
}
out.write(buffer + "\n");
buffer = "";
}
int c = getRowCount(changed);
out.write("\nROWS CHANGED\tTOTAL ROWS\n");
out.write(c + "\t" + tot + "\t \t" + "=1-(A" + (c + 4) + "/B" + (c + 4) + ")" + "\n");
out.write(" \t \t \t=1-(A" + (c + 5) + "/B" + (c + 4) + ")" + "\n");
out.flush(); // Make sure everything gets written
out.close();
out = null;
changed.close();
total.close();
}
}
LOGGER.info("Tidying up open resources and exiting...");
rowsChanged.close();
totalRows.close();
rowsChanged = null;
totalRows = null;
conn.close();
conn = null;
System.exit(0);
}
/**
* The ResultSet you pass to this method must be from a PreparedStatement created with these args:
* prepareStatement("select * from ...", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
*
* This will throw an exception with FORWARD_ONLY ResultSets (as in the default one you get with no extra arguments)
*
* ResultSet.CONCUR_READ_ONLY may actually be something else if you so desire. TYPE_SCROLL_INSENSITIVE is what is important.
*
* @param set - The ResultSet to count rows in
* @return The number of rows in the ResultSet
* @throws SQLException
*/
public static int getRowCount(ResultSet set) throws SQLException {
int rowCount;
int currentRow = set.getRow(); // Get current row
rowCount = set.last() ? set.getRow() : 0; // Determine number of rows
if (currentRow == 0) // If there was no current row
set.beforeFirst(); // We want next() to go to first row
else // If there WAS a current row
set.absolute(currentRow); // Restore it
return rowCount;
}
}
+183
View File
@@ -0,0 +1,183 @@
/*
* I grabbed this from the official Oracle JTabbedPane tutorial and slightly
* modified how it behaves when the close button is clicked to properly remove
* objects from the HashMaps in the Editor instance.
*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle or the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package pickMaint;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.plaf.basic.BasicButtonUI;
/**
* Component to be used as tabComponent;
* Contains a JLabel to show the text and
* a JButton to close the tab it belongs to
*/
public class ButtonTabComponent extends JPanel {
private static final long serialVersionUID = -5689913156783054837L;
private final JTabbedPane pane;
private final Editor editor;
public ButtonTabComponent(final JTabbedPane pane, final Editor editor) {
//unset default FlowLayout' gaps
super(new FlowLayout(FlowLayout.LEFT, 0, 0));
if (pane == null) {
throw new NullPointerException("TabbedPane is null");
}
this.pane = pane;
this.editor = editor;
setOpaque(false);
//make JLabel read titles from JTabbedPane
JLabel label = new JLabel() {
private static final long serialVersionUID = -3058269816351809172L;
public String getText() {
int i = pane.indexOfTabComponent(ButtonTabComponent.this);
if (i != -1) {
return pane.getTitleAt(i);
}
return null;
}
};
add(label);
//add more space between the label and the button
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
//tab button
JButton button = new TabButton();
add(button);
//add more space to the top of the component
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
}
private class TabButton extends JButton implements ActionListener {
private static final long serialVersionUID = 369894927571691780L;
public TabButton() {
int size = 17;
setPreferredSize(new Dimension(size, size));
setToolTipText("close this tab");
//Make the button looks the same for all Laf's
setUI(new BasicButtonUI());
//Make it transparent
setContentAreaFilled(false);
//No need to be focusable
setFocusable(false);
setBorder(BorderFactory.createEtchedBorder());
setBorderPainted(false);
//Making nice rollover effect
//we use the same listener for all buttons
addMouseListener(buttonMouseListener);
setRolloverEnabled(true);
//Close the proper tab by clicking the button
addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
int i = pane.indexOfTabComponent(ButtonTabComponent.this);
if (i != -1) {
String[] parse = pane.getTitleAt(i).split(" ");
int shift = Integer.parseInt(parse[2].substring(0, 1));
DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
try {
Date date = formatter.parse(parse[0]);
editor.unloadShiftDetail(date, shift);
//pane.remove(i);
} catch (ParseException e1) { e1.printStackTrace(); }
}
}
//we don't want to update UI for this button
public void updateUI() {
}
//paint the cross
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
//shift the image for pressed buttons
if (getModel().isPressed()) {
g2.translate(1, 1);
}
g2.setStroke(new BasicStroke(2));
g2.setColor(Color.BLACK);
if (getModel().isRollover()) {
g2.setColor(Color.MAGENTA);
}
int delta = 6;
g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
g2.dispose();
}
}
private final static MouseListener buttonMouseListener = new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
Component component = e.getComponent();
if (component instanceof AbstractButton) {
AbstractButton button = (AbstractButton) component;
button.setBorderPainted(true);
}
}
public void mouseExited(MouseEvent e) {
Component component = e.getComponent();
if (component instanceof AbstractButton) {
AbstractButton button = (AbstractButton) component;
button.setBorderPainted(false);
}
}
};
}
File diff suppressed because it is too large Load Diff
+132
View File
@@ -0,0 +1,132 @@
package pickMaint;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Logger;
/**
* This represents my attempts to recreate the incentive pay calculations done on the AS400
* This is for research purposes. Magic numbers are constants pulled from the DB.
* @author Wes
*/
public class EfficiencyBonusCalc {
private static final int[] DATE = new int[]{ 180219, 180220, 180221, 180222 };
private static final int WEAVER = 183;
private static final double[] MAX_BONUS = new double[]{ 0.0, 0.0, 0.0, 0.0, 2.5, 3.0, 3.75, 4.0, 4.25, 4.75, 7.0, 10.25, 33.0, 33.0 };
private static final Logger LOGGER = Logger.getLogger(EfficiencyBonusCalc.class.getName());
private static final String EFF_BONUS_BY_DATE = "SELECT y.lddate, "
+ " y.ldshif, "
+ " y.looms, "
+ " y.picks, "
+ " y.pickspossible, "
+ " ((((CAST(y.picks AS FLOAT) / y.pickspossible) * (y.loomhours * LMRTLH)) - (y.shiftlen * LMRATE)) * lmpct) EFF_BON "
+ "FROM (SELECT x.lddate, "
+ " x.ldshif, "
+ " CAST(ROUND(SUM(x.ldhrs) / max(x.ldhrs), 0) AS INT) looms, "
+ " SUM(x.ldhrs) loomhours, "
+ " max(x.ldhrs) shiftlen, "
+ " sum(x.ldpick) picks, "
+ " sum(x.maxpicks) pickspossible "
+ " FROM (SELECT lddate, "
+ " ldshif, "
+ " ldloom, "
+ " ldweav, "
+ " ldhrs, "
+ " ldpick, "
+ " CAST(ROUND((lmppm * ldhrs), 0) AS INT) maxpicks "
+ " FROM stmdata.loomds "
+ " INNER JOIN stmdata.loomms ON stmdata.loomds.ldloom = stmdata.loomms.lmlomn "
+ " WHERE lddate = ? AND "
+ " ldshif = ? AND "
+ " ldweav = ?) x "
+ " GROUP BY x.lddate,x.ldshif) y "
+ " LEFT JOIN stmdata.lmprir ON stmdata.lmprir.lmloom = 'D' AND "
+ " stmdata.lmprir.lmnolm = y.looms ";
private static final String WEAVER_INFO = "select wvrnam, shift from stmdata.iewvms where WVR# = " + WEAVER;
public static void main(String[] args) throws SQLException, IOException {
System.out.println(EFF_BONUS_BY_DATE);
// Register AS400 DB2 driver and open a connection with the AS400
LOGGER.info("Connecting to AS400 as user: WRAY\n");
DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver());
Connection conn = DriverManager.getConnection("jdbc:as400://0.0.0.0", "USER", "PASSWORD");
LOGGER.info("Pre-compiling SQL statements...\n");
PreparedStatement effBonusGet = conn.prepareStatement(EFF_BONUS_BY_DATE);
LOGGER.info("Looking up weaver name and shift for number " + WEAVER +"...\n");
int shift = 0;
String name = "";
double total = 0;
ResultSet weavInfo = conn.createStatement().executeQuery(WEAVER_INFO);
if(weavInfo.next()) {
shift = weavInfo.getInt(2);
name = weavInfo.getString(1).trim();
} else {
throw new RuntimeException("Weaver doesn't exist!");
}
System.out.println("Efficiency Bonus Calculations for " + name + " (" + WEAVER + ") " + ((shift == 1) ? "1st" : (shift == 2) ? "2nd" : (shift == 3) ? "3rd" : "") + " shift.\n");
for(int d : DATE){
effBonusGet.setInt(1, d);
effBonusGet.setInt(2, shift);
effBonusGet.setInt(3, WEAVER);
ResultSet rs = effBonusGet.executeQuery();
if(rs.next()){
int looms = rs.getInt(3);
if(looms > 13)
looms = 13;
double bonus = rs.getDouble(6);
bonus = Math.min(bonus, MAX_BONUS[looms]);
System.out.println(d + "_" + shift + " - " + looms + " looms. $" + bonus);
total += bonus;
rs.close();
} else {
System.out.println(d + "_" + shift + " - NO DATA");
}
}
System.out.println("\nTotal Efficiency Bonus: $" + total);
effBonusGet.close();
effBonusGet = null;
conn.close();
conn = null;
System.exit(0);
}
/**
* The ResultSet you pass to this method must be from a PreparedStatement created with these args:
* prepareStatement("select * from ...", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
*
* This will throw an exception with FORWARD_ONLY ResultSets (as in the default one you get with no extra arguments)
*
* ResultSet.CONCUR_READ_ONLY may actually be something else if you so desire. TYPE_SCROLL_INSENSITIVE is what is important.
*
* @param set - The ResultSet to count rows in
* @return The number of rows in the ResultSet
* @throws SQLException
*/
public static int getRowCount(ResultSet set) throws SQLException {
int rowCount;
int currentRow = set.getRow(); // Get current row
rowCount = set.last() ? set.getRow() : 0; // Determine number of rows
if (currentRow == 0) // If there was no current row
set.beforeFirst(); // We want next() to go to first row
else // If there WAS a current row
set.absolute(currentRow); // Restore it
return rowCount;
}
}
+62
View File
@@ -0,0 +1,62 @@
package pickMaint;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Logger;
import javax.swing.JTable;
import javax.swing.table.TableModel;
/**
* This class provides means to dump the contents of a JTable into a tab delimited file and then open it in Excel.
*
* @author Wesley Ray
*/
public class ExcelExporter {
private static final Logger LOGGER = Logger.getLogger(LoomDSRecord.class.getName());
/**
* Dumps the data in a JTable out to a tab delimited file.
* @param table
* @param outFile
* @throws IOException
*/
public static void exportJTableToFile(JTable table, String outFile) throws IOException{
TableModel m = table.getModel();
FileWriter out = new FileWriter(outFile);
String buffer = "";
LOGGER.info("Exporting " + m.getRowCount() + " rows to tab delmited file: " + outFile);
for (int i = 0; i < m.getColumnCount(); i++) {
buffer += (m.getColumnName(i) + "\t");
}
out.write(buffer + "\n");
buffer = "";
for (int i = 0; i < m.getRowCount(); i++) {
for (int j = 0; j < m.getColumnCount(); j++) {
buffer += (m.getValueAt(i, j) + "\t");
}
out.write(buffer + "\n");
buffer = "";
}
out.flush(); //Make sure everything gets written
out.close(); //Close the file
out = null; //Make sure this gets garbage collected
}
/**
* This only works on Windows. This will work with any file that you can double click to open really.
* XLS files happen to open in excel automatically.
*
* @param path
* @throws IOException
*/
public static void openInExcel(String path) throws IOException{
LOGGER.info("Invoking \"cmd.exe /c start " + path + "\"");
Runtime.getRuntime().exec("cmd.exe /c start " + path);
}
}
+49
View File
@@ -0,0 +1,49 @@
package pickMaint;
public class LoomDSKey {
private final int DATE;
private final int SHIFT;
private final int LOOM;
private final int WEAVER;
private final String TYPE;
public LoomDSKey(int date, int shift, int loom, int weaver, String type){
this.DATE = date;
this.SHIFT = shift;
this.LOOM = loom;
this.WEAVER = weaver;
this.TYPE = type;
}
public String toString(){
return DATE + "-" + SHIFT + "-" + LOOM + "-" + WEAVER + "-" + TYPE;
}
/**
* All 5 components of the composite key must be equal
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof LoomDSKey)) return false;
LoomDSKey key = (LoomDSKey) o;
return DATE == key.DATE &&
SHIFT == key.SHIFT &&
LOOM == key.LOOM &&
WEAVER == key.WEAVER &&
TYPE.equalsIgnoreCase(key.TYPE);
}
/**
* Obviously not a perfect hash; although I suspect collisions will be rare in our use case.
*/
@Override
public int hashCode() {
int hash = DATE * SHIFT;
hash = hash + LOOM;
hash = hash * (WEAVER / 2);
hash = hash + TYPE.hashCode();
return hash;
}
}
+293
View File
@@ -0,0 +1,293 @@
package pickMaint;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Logger;
/**
* This class is essentially just an Object representation of a single record in LOOMDS/LOOMDS2.
*
* The constructor takes a reference to an AS400Interface only in case we need to pull "no bonus" hours and picks from LOOMDS2.
* See below: if(deleteCode.equalsIgnoreCase("N")) { ... }
*
* The bulk of the object is created using the java.sql.ResultSet that is passed to the constructor. This ResultSet is expected to be
* generated by a particular query stored in AS400Interface.java
*
* The rest of the class is just getters/setters.
*
* @author Wesley Ray
*/
public class LoomDSRecord implements Comparable<Object> {
private static final Logger LOGGER = Logger.getLogger(LoomDSRecord.class.getName());
private Date date;
private int shift;
private int loomNumber;
private int weaverNumber;
private String weaverName;
private String ldStyle; //TRL, BLN, or SAM
private double hours;
private int picks;
private float picksPerHourBonus;
private float picksPerHourNoBonus;
private String downTimeCode;
private String downTimeCodeDescription;
private int cut;
private String cutSuffix;
private String typeCode;
private String deleteCode;
private boolean bonus;
private boolean changed = false; //Never ended up using this, not a bad idea though. leaving it here just in case
public LoomDSRecord(AS400Interface as400, ResultSet row) throws SQLException {
date = AS400Interface.intToDate(row.getInt(1));
loomNumber = row.getInt(2);
shift = row.getInt(3);
weaverNumber = row.getInt(4);
weaverName = row.getString(5).trim();
ldStyle = row.getString(6).trim();
hours = row.getDouble(7);
picks = row.getInt(8);
picksPerHourBonus = row.getFloat(11);
picksPerHourNoBonus = row.getFloat(12);
downTimeCode = row.getString(13).trim();
downTimeCodeDescription = AS400Interface.dtCodeLookup(downTimeCode);
cut = row.getInt(14);
cutSuffix = row.getString(15).trim();
typeCode = row.getString(16).trim();
deleteCode = row.getString(17);
bonus = !((weaverNumber > 699 && weaverNumber < 703) || (ldStyle.equalsIgnoreCase("TRL") || ldStyle.equalsIgnoreCase("BLN") || deleteCode.equalsIgnoreCase("N")));
if(deleteCode.equalsIgnoreCase("N")){
LOGGER.fine(logPrefix() + "is flagged NO_BONUS need to fetch hours and picks from LOOMDS2.");
float[] values = as400.getLoomDS2HoursPicks(AS400Interface.dateToInt(date), loomNumber, shift, weaverNumber);
hours = values[0];
picks = (int) values[1];
}
}
/**
* @return the weaverNumber
*/
public final int getWeaverNumber() {
return weaverNumber;
}
/**
* @param weaverNumber the weaverNumber to set
*/
public final void setWeaverNumber(int weaverNumber) {
LOGGER.info("Loom: " + loomNumber + " - " + ((shift == 1) ? "1st" : (shift == 2) ? "2nd" : (shift == 3) ? "3rd" : "") + " shift - " + new SimpleDateFormat("MM/dd/yyyy").format(date) +
" - Changing weaver from: " + weaverName + " (" + this.weaverNumber + ") to: " + AS400Interface.weaverLookup(weaverNumber) + " (" + weaverNumber + ")");
this.weaverNumber = weaverNumber;
this.weaverName = AS400Interface.weaverLookup(weaverNumber);
bonus = !((weaverNumber > 699 && weaverNumber < 703) || (ldStyle.equalsIgnoreCase("TRL") || ldStyle.equalsIgnoreCase("BLN")));
changed = true;
}
/**
* @return the ldStyle
*/
public final String getLdStyle() {
return ldStyle;
}
/**
* @param ldStyle the ldStyle to set
*/
public final void setLdStyle(String ldStyle) {
LOGGER.info(logPrefix() + "- Changing LDSTYL from: " + this.ldStyle + " to: " + ldStyle);
this.ldStyle = ldStyle;
bonus = !((weaverNumber > 699 && weaverNumber < 703) || (ldStyle.equalsIgnoreCase("TRL") || ldStyle.equalsIgnoreCase("BLN")));
changed = true;
}
/**
* @return the hours
*/
public final double getHours() {
return hours;
}
/**
* @param hours the hours to set
*/
public final void setHours(double hours) {
LOGGER.info(logPrefix() + "- Changing hours from: " + this.hours + " to: " + hours);
this.hours = hours;
changed = true;
}
/**
* @return the picks
*/
public final int getPicks() {
return picks;
}
/**
* @param picks the picks to set
*/
public final void setPicks(int picks) {
LOGGER.info(logPrefix() + "- Changing picks from: " + this.picks + " to: " + picks);
this.picks = picks;
changed = true;
}
public final int getMaxPicks(){
return (int) ((hours * (bonus ? picksPerHourBonus : picksPerHourNoBonus)) + 0.5); //The +0.5 combined with the (int) cast creates the effect of rounding up to nearest whole number
}
/**
* @return the downTimeCode
*/
public final String getDownTimeCode() {
return downTimeCode;
}
/**
* @param downTimeCode the downTimeCode to set
*/
public final void setDownTimeCode(String downTimeCode) {
LOGGER.info(logPrefix() + "- Changing down time code from: " + this.downTimeCode + " to: " + downTimeCode);
this.downTimeCode = downTimeCode;
this.downTimeCodeDescription = AS400Interface.dtCodeLookup(downTimeCode);
changed = true;
}
/**
* @return the typeCode
*/
public final String getTypeCode() {
return typeCode;
}
/**
* @param typeCode the typeCode to set
*/
public final void setTypeCode(String typeCode) {
LOGGER.info(logPrefix() + "- Changing type code from: " + this.typeCode + " to: " + typeCode);
this.typeCode = typeCode;
changed = true;
}
/**
* @return the date
*/
public final Date getDate() {
return date;
}
/**
* @return the shift
*/
public final int getShift() {
return shift;
}
/**
* @return the loomNumber
*/
public final int getLoomNumber() {
return loomNumber;
}
/**
* @return the weaverName
*/
public final String getWeaverName() {
return weaverName;
}
public final String getWeaverNameDisplay(){
return weaverName + " (" + weaverNumber + ")";
}
/**
* @return the picksPerHourBonus
*/
public final float getPicksPerHourBonus() {
return picksPerHourBonus;
}
/**
* @return the picksPerHourNoBonus
*/
public final float getPicksPerHourNoBonus() {
return picksPerHourNoBonus;
}
/**
* @return the downTimeCodeDescription
*/
public final String getDownTimeCodeDescription() {
return downTimeCodeDescription;
}
public final String getformattedDowntimeReason(){
if(downTimeCodeDescription != null)
return "(" + downTimeCode + ") " + downTimeCodeDescription;
else
return "";
}
/**
* @return the cut
*/
public final int getCut() {
return cut;
}
/**
* @return the cutSuffix
*/
public final String getCutSuffix() {
return cutSuffix;
}
public final String getFormattedCutNumber(){
if(cut < 1)
return "";
if(cutSuffix.length() == 0)
return "" + cut;
return cut + "-" + cutSuffix;
}
/**
* @return the deleteCode
*/
public final String getDeleteCode() {
return deleteCode;
}
/**
* @return the bonus
*/
public final boolean isBonus() {
return bonus;
}
public final boolean changed(){
return changed;
}
private String logPrefix(){
return "Loom: " + loomNumber + " - " + ((shift == 1) ? "1st" : (shift == 2) ? "2nd" : (shift == 3) ? "3rd" : "") + " shift - "
+ new SimpleDateFormat("MM/dd/yyyy").format(date) + " Weaver: " + weaverName + " (" + weaverNumber + ") ";
}
@Override
public int compareTo(Object o) {
if(o instanceof LoomDSRecord){
return loomNumber - ((LoomDSRecord) o).getLoomNumber();
} else {
throw new RuntimeException("Something screwed when sorting LoomDSRecord array");
}
}
}
+122
View File
@@ -0,0 +1,122 @@
package pickMaint;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
/**
* This class implements all abstract methods in AbstractTableModel as needed to display LoomDSRecords properly.
*
* @author Wesley Ray
*/
public class LoomDSTableModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
private static final String [] COL_HEADERS = {"Loom", "Weaver", "Style", "Hours", "Picks", "Picks Possible", "Down Time", "Sample Cut"};
private LoomDSRecord[] data;
private Integer[] sampleHighlight;
private Integer[] zeroHighlight;
/**
* Updates the data to be displayed by the table model.
* Also builds an array of specific rows to highlight in a different color due to them being sample cut-ins
* @param data The LoomDSRecord[] to display
*/
public void loadTable(LoomDSRecord[] data){
this.data = data;
ArrayList<Integer> q = new ArrayList<Integer>();
for(LoomDSRecord r : data){
if(r.getLdStyle().trim().equalsIgnoreCase("SAM"))
q.add(r.getLoomNumber());
}
sampleHighlight = q.toArray(new Integer[q.size()]);
q = new ArrayList<Integer>();
for(LoomDSRecord r : data){
float derp = (float) r.getPicks() / (float) r.getMaxPicks();
if(derp <= 0.75 && r.getWeaverNumber() != 700 && r.getWeaverNumber() != 701 && r.getWeaverNumber() != 702)
q.add(r.getLoomNumber());
}
zeroHighlight = q.toArray(new Integer[q.size()]);
this.fireTableDataChanged();
}
/**
* Returns true if the given row number is to be highlighted for being a sample cut
* @param row - the row number to check
* @return true/false if row contains sample cut
*/
public boolean highlightSample(int row){
int target = data[row].getLoomNumber();
for(int i : sampleHighlight){
if(i == target)
return true;
}
return false;
}
/**
* Returns true if the given row number is to be highlighted for having zero picks
* @param row - the row number to check
* @return true/false
*/
public boolean highlightZero(int row){
int target = data[row].getLoomNumber();
for(int i : zeroHighlight){
if(i == target)
return true;
}
return false;
}
/**
* Returns bonus status for a given row
* @param row - the row to check
* @return Bonus or not?
*/
public boolean bonus(int row){
return data[row].isBonus();
}
@Override
public int getRowCount() {
return data.length;
}
@Override
public int getColumnCount() {
return COL_HEADERS.length;
}
@Override
public String getColumnName(int column) {
return COL_HEADERS[column];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch(columnIndex){
case 0:
return data[rowIndex].getLoomNumber();
case 1:
return data[rowIndex].getWeaverNameDisplay();
case 2:
return data[rowIndex].getLdStyle();
case 3:
return data[rowIndex].getHours();
case 4:
return data[rowIndex].getPicks();
case 5:
return data[rowIndex].getMaxPicks() + " (+" + (data[rowIndex].getMaxPicks() - data[rowIndex].getPicks()) + ")";
case 6:
return data[rowIndex].getformattedDowntimeReason();
case 7:
return data[rowIndex].getFormattedCutNumber();
}
return null; //required to compile
}
}
+62
View File
@@ -0,0 +1,62 @@
package pickMaint;
import javax.swing.*;
import javax.swing.event.*;
/**
* Convenience class to request focus on a component.
*
* When the component is added to a realized Window then component will request
* focus immediately, since the ancestorAdded event is fired immediately.
*
* When the component is added to a non realized Window, then the focus request
* will be made once the window is realized, since the ancestorAdded event will
* not be fired until then.
*
* Using the default constructor will cause the listener to be removed from the
* component once the AncestorEvent is generated. A second constructor allows
* you to specify a boolean value of false to prevent the AncestorListener from
* being removed when the event is generated. This will allow you to reuse the
* listener each time the event is generated.
*/
public class RequestFocusListener implements AncestorListener {
private boolean removeListener;
/*
* Convenience constructor. The listener is only used once and then it is
* removed from the component.
*/
public RequestFocusListener() {
this(true);
}
/*
* Constructor that controls whether this listen can be used once or
* multiple times.
*
* @param removeListener when true this listener is only invoked once
* otherwise it can be invoked multiple times.
*/
public RequestFocusListener(boolean removeListener) {
this.removeListener = removeListener;
}
@Override
public void ancestorAdded(AncestorEvent e) {
JComponent component = e.getComponent();
component.requestFocusInWindow();
if (removeListener)
component.removeAncestorListener(this);
}
@Override
public void ancestorMoved(AncestorEvent e) {
}
@Override
public void ancestorRemoved(AncestorEvent e) {
}
}
+39
View File
@@ -0,0 +1,39 @@
package pickMaint;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/**
* Convenience class.
* When this FocusListener is added to a text field the contents of the text field will be highlighted
* automagicaly when the cursor enters the field.
* @author Wesley Ray
*/
public class SelectAllOnFocusListener implements FocusListener {
@Override
public void focusGained(FocusEvent e) {
/*
* The following causes any existing text to be selected on focusGained. Using invokeLater to ensure
* this happens after any other events pertaining to the text field in order to avoid any unexpected
* behavior
*/
final JTextField source = (JTextField) e.getSource();
SwingUtilities.invokeLater( new Runnable() {
@Override
public void run() {
source.selectAll();
}
});
}
@Override
public void focusLost(FocusEvent e) {
//Required to compile
}
}