/*
* (C) Copyright 2015 by fr3ts0n <erwin.scheuch-heilig@gmx.at>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
package com.fr3ts0n.ecu.gui.application;
import com.fr3ts0n.ecu.EcuCodeItem;
import com.fr3ts0n.ecu.ObdCodeItem;
import com.fr3ts0n.pvs.PvChangeEvent;
import com.fr3ts0n.pvs.PvChangeListener;
import com.fr3ts0n.pvs.PvList;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
/**
* GUI Panel to control reading/clearing OBD failure codes
*
* @author erwin
*/
public class ObdDtcPanel extends JPanel
implements PropertyChangeListener, PvChangeListener
{
/** serial version UID * */
private static final long serialVersionUID = -1285434908785275242L;
/** icons */
public ImageIcon icoMilOff = new javax.swing.ImageIcon(getClass().getResource("/com/fr3ts0n/ecu/gui/res/mil_off.png"));
public ImageIcon icoMilOn = new javax.swing.ImageIcon(getClass().getResource("/com/fr3ts0n/ecu/gui/res/mil_on.png"));
/** milStatus */
boolean milStatus = false;
/** Creates new form ObdDfcPanel */
public ObdDtcPanel()
{
initComponents();
panStatus.setVisible(false);
tblFCodes.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
tblFCodes.getSelectionModel().addListSelectionListener(new ListSelectionListener()
{
public void valueChanged(ListSelectionEvent e)
{
Integer stat = null;
int selIdx = tblFCodes.getSelectedRow();
if (selIdx >= 0)
stat = (Integer) tblFCodes.getModel().getValueAt(selIdx, EcuCodeItem.FID_STATUS);
panStatus.setVisible(stat != null);
if (stat != null)
{
panStatus.setStatusFlags(stat.intValue());
}
}
});
}
/**
* This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents()
{
java.awt.GridBagConstraints gridBagConstraints;
panHeader = new javax.swing.JPanel();
lblCodeType = new javax.swing.JLabel();
lblMil = new javax.swing.JLabel();
lblMil1 = new javax.swing.JLabel();
lblNumCodes = new javax.swing.JLabel();
panFooter = new javax.swing.JPanel();
btnReadCodes = new javax.swing.JButton();
btnReadPending = new javax.swing.JButton();
btnReadPermanent = new javax.swing.JButton();
btnClearCodes = new javax.swing.JButton();
panCenter = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
tblFCodes = new com.fr3ts0n.pvs.gui.PvTable();
panStatus = new com.fr3ts0n.ecu.gui.application.VagCodeStatPanel();
setLayout(new java.awt.BorderLayout());
panHeader.setBackground(new java.awt.Color(255, 255, 255));
panHeader.setLayout(new java.awt.BorderLayout(10, 10));
lblCodeType.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
lblCodeType.setText("Trouble codes");
panHeader.add(lblCodeType, java.awt.BorderLayout.CENTER);
lblMil.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
lblMil.setIcon(icoMilOff);
lblMil.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
panHeader.add(lblMil, java.awt.BorderLayout.WEST);
lblMil1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
lblMil1.setIcon(icoMilOff);
lblMil1.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
panHeader.add(lblMil1, java.awt.BorderLayout.EAST);
lblNumCodes.setFont(new java.awt.Font("Dialog", 0, 10));
lblNumCodes.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
lblNumCodes.setText("0 Trouble codes set");
panHeader.add(lblNumCodes, java.awt.BorderLayout.SOUTH);
add(panHeader, java.awt.BorderLayout.NORTH);
panFooter.setLayout(new java.awt.GridBagLayout());
btnReadCodes.setFont(new java.awt.Font("Dialog", 0, 10));
btnReadCodes.setMnemonic('R');
btnReadCodes.setText("Read Codes");
btnReadCodes.setToolTipText("Read all truble codes (Mode $3)");
btnReadCodes.setActionCommand("ReadCodes");
btnReadCodes.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
btnReadCodesActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
panFooter.add(btnReadCodes, gridBagConstraints);
btnReadPending.setFont(new java.awt.Font("Dialog", 0, 10));
btnReadPending.setMnemonic('P');
btnReadPending.setText("Read Pending");
btnReadPending.setToolTipText("Read pending fault codes (Mode $7)");
btnReadPending.setActionCommand("ReadPending");
btnReadPending.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
btnReadPendingActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
panFooter.add(btnReadPending, gridBagConstraints);
btnReadPermanent.setFont(new java.awt.Font("Dialog", 0, 10));
btnReadPermanent.setMnemonic('e');
btnReadPermanent.setText("Read Permanent");
btnReadPermanent.setToolTipText("Read permanent Trouble codes (Mode $A)");
btnReadPermanent.setActionCommand("ReadPermanent");
btnReadPermanent.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
btnReadPermanentActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
panFooter.add(btnReadPermanent, gridBagConstraints);
btnClearCodes.setFont(new java.awt.Font("Dialog", 0, 10));
btnClearCodes.setMnemonic('C');
btnClearCodes.setText("Clear Codes");
btnClearCodes.setToolTipText("Clear troble codes (Mode $4)");
btnClearCodes.setActionCommand("ClearCodes");
btnClearCodes.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
btnClearCodesActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
panFooter.add(btnClearCodes, gridBagConstraints);
add(panFooter, java.awt.BorderLayout.SOUTH);
panCenter.setLayout(new java.awt.BorderLayout());
tblFCodes.setAutoResizeMode(5);
tblFCodes.setName("CodeTable"); // NOI18N
jScrollPane1.setViewportView(tblFCodes);
panCenter.add(jScrollPane1, java.awt.BorderLayout.CENTER);
panCenter.add(panStatus, java.awt.BorderLayout.SOUTH);
add(panCenter, java.awt.BorderLayout.CENTER);
}// </editor-fold>//GEN-END:initComponents
private void btnReadPendingActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnReadPendingActionPerformed
{//GEN-HEADEREND:event_btnReadPendingActionPerformed
lblCodeType.setText("Pending trouble codes");
}//GEN-LAST:event_btnReadPendingActionPerformed
private void btnClearCodesActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnClearCodesActionPerformed
{//GEN-HEADEREND:event_btnClearCodesActionPerformed
if (JOptionPane.showConfirmDialog(this,
"This will reset the MIL and clear all emission-related diagnostic\n"
+ " information, including:\n\n"
+ " - Diagnostic trouble codes\n"
+ " - Freeze frame data\n"
+ " - Oxygen sensor com.fr3ts0n.test data\n"
+ " - Status of system monitoring tests\n"
+ " - On-board monitoring tests results\n"
+ " - Distance travelled while MIL activated\n"
+ " - Number of warm-ups since DTCs cleared\n"
+ " - Distance travelled since DTCs cleared\n"
+ " - Engine run time while MIL activated\n"
+ " - Time since DTCs cleared\n\n"
+ "Other manufacturer-specific 'clearing/resetting' actions may occur.\n"
+ "The loss of data may cause the vehicle to run poorly for a short \n"
+ "period of time while the ECU recalibrates itself.",
"Clear codes?",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION)
evt.setSource(null);
}//GEN-LAST:event_btnClearCodesActionPerformed
private void btnReadCodesActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnReadCodesActionPerformed
{//GEN-HEADEREND:event_btnReadCodesActionPerformed
lblCodeType.setText("Stored trouble codes");
}//GEN-LAST:event_btnReadCodesActionPerformed
private void btnReadPermanentActionPerformed(java.awt.event.ActionEvent evt)
{//GEN-FIRST:event_btnReadPermanentActionPerformed
lblCodeType.setText("Permanent trouble codes");
}//GEN-LAST:event_btnReadPermanentActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
protected javax.swing.JButton btnClearCodes;
protected javax.swing.JButton btnReadCodes;
protected javax.swing.JButton btnReadPending;
protected javax.swing.JButton btnReadPermanent;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JLabel lblCodeType;
private javax.swing.JLabel lblMil;
private javax.swing.JLabel lblMil1;
private javax.swing.JLabel lblNumCodes;
private javax.swing.JPanel panCenter;
private javax.swing.JPanel panFooter;
private javax.swing.JPanel panHeader;
private com.fr3ts0n.ecu.gui.application.VagCodeStatPanel panStatus;
private com.fr3ts0n.pvs.gui.PvTable tblFCodes;
// End of variables declaration//GEN-END:variables
public boolean getMilStatus()
{
return (milStatus);
}
public void setMilStatus(boolean newStatus)
{
milStatus = newStatus;
// set the MIL-status display
String msg = milStatus ? "MIL is ON" : "MIL is OFF";
ImageIcon icn = milStatus ? icoMilOn : icoMilOff;
Color clr = milStatus ? Color.RED : Color.GREEN;
lblMil.setIcon(icn);
lblMil.setText(msg);
lblMil.setToolTipText(msg);
lblMil.setForeground(clr);
lblMil1.setIcon(icn);
lblMil1.setText(msg);
lblMil1.setToolTipText(msg);
lblMil1.setForeground(clr);
}
/**
* Holds value of property tcList.
*/
private PvList tcList;
/**
* Holds value of property numCodes.
*/
private int numCodes;
/**
* Getter for property pvList.
*
* @return Value of property pvList.
*/
public PvList getTcList()
{
return this.tcList;
}
/**
* Setter for trouble code list
*
* @param tcList New value of trouble code list.
*/
public void setTcList(PvList tcList)
{
this.tcList = tcList;
// set the process var list of the table
tblFCodes.setProcessVar(tcList);
tcList.addPvChangeListener(this);
updateColumnWidths();
}
/**
* Getter for property numCodes.
*
* @return Value of property numCodes.
*/
public int getNumCodes()
{
return this.numCodes;
}
/**
* Setter for property numCodes.
*
* @param numCodes New value of property numCodes.
*/
public void setNumCodes(int numCodes)
{
this.numCodes = numCodes & 0x7F;
setMilStatus((numCodes & 0x80) != 0);
lblNumCodes.setText(this.numCodes + " Trouble codes set");
}
/**
* update the column widths of data table
*/
private void updateColumnWidths()
{
if (tcList.size() > 0)
{
/** set column sizes here, since this only works with inserted data */
tblFCodes.getColumn(ObdCodeItem.FIELDS[ObdCodeItem.FID_CODE]).setPreferredWidth(40);
tblFCodes.getColumn(ObdCodeItem.FIELDS[ObdCodeItem.FID_DESCRIPT]).setPreferredWidth(330);
}
}
/**
* This method gets called when a bound property is changed.
*
* @param evt A PropertyChangeEvent object describing the event source
* and the property that has changed.
*/
public void propertyChange(java.beans.PropertyChangeEvent evt)
{
if (evt.getPropertyName().equals("numCodes"))
{
setNumCodes(((Integer) evt.getNewValue()).intValue());
}
}
/**
* special handling of changes in displayed code list
*
* @param event Event to be handled
*/
public void pvChanged(PvChangeEvent event)
{
switch (event.getType())
{
/* update column width on added lines, since this only works with
* tables containing at least one row of data
*/
case PvChangeEvent.PV_ADDED:
updateColumnWidths();
break;
}
}
/**
* Add actionListener to all action sources on panel
*
* @param al ActionListener to be registered
*/
public void addActionListener(ActionListener al)
{
btnClearCodes.addActionListener(al);
btnReadCodes.addActionListener(al);
btnReadPending.addActionListener(al);
btnReadPermanent.addActionListener(al);
}
/**
* Remove actionListener from all action sources on panel
*
* @param al ActionListener to be registered
*/
public void removeActionListener(ActionListener al)
{
btnClearCodes.removeActionListener(al);
btnReadCodes.removeActionListener(al);
btnReadPending.removeActionListener(al);
btnReadPermanent.removeActionListener(al);
}
}