/* * (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); } }