mirror of https://github.com/rusefi/RomRaider.git
more bug fixes and data convertors added
git-svn-id: http://svn.3splooges.com/romraider-arch/trunk@214 d2e2e1cd-ba16-0410-be16-b7c4453c7c2d
This commit is contained in:
parent
cda992eee1
commit
b6bc2a3677
Binary file not shown.
Binary file not shown.
|
@ -5,12 +5,20 @@ import enginuity.logger.definition.EcuParameter;
|
||||||
import enginuity.logger.definition.EcuParameterImpl;
|
import enginuity.logger.definition.EcuParameterImpl;
|
||||||
import enginuity.logger.definition.convertor.AcceleratorOpeningAngleConvertor;
|
import enginuity.logger.definition.convertor.AcceleratorOpeningAngleConvertor;
|
||||||
import enginuity.logger.definition.convertor.AirFuelRatioLambdaConvertor;
|
import enginuity.logger.definition.convertor.AirFuelRatioLambdaConvertor;
|
||||||
import enginuity.logger.definition.convertor.EcuParameterConvertor;
|
import enginuity.logger.definition.convertor.EngineSpeedConvertor;
|
||||||
import enginuity.logger.definition.convertor.ExhaustGasTemperatureConvertor;
|
import enginuity.logger.definition.convertor.ExhaustGasTemperatureConvertor;
|
||||||
import enginuity.logger.definition.convertor.GenericTemperatureConvertor;
|
import enginuity.logger.definition.convertor.GenericTemperatureConvertor;
|
||||||
import enginuity.logger.definition.convertor.ThrottleOpeningAngleConvertor;
|
import enginuity.logger.definition.convertor.ThrottleOpeningAngleConvertor;
|
||||||
import enginuity.logger.query.LoggerCallback;
|
import enginuity.logger.query.LoggerCallback;
|
||||||
import static enginuity.util.HexUtil.asHex;
|
import enginuity.logger.ui.LoggerDataRow;
|
||||||
|
import enginuity.logger.ui.LoggerDataTableModel;
|
||||||
|
import enginuity.logger.ui.SpringUtilities;
|
||||||
|
import org.jfree.chart.ChartFactory;
|
||||||
|
import org.jfree.chart.JFreeChart;
|
||||||
|
import org.jfree.chart.plot.PlotOrientation;
|
||||||
|
import org.jfree.data.xy.XYDataset;
|
||||||
|
import org.jfree.data.xy.XYSeries;
|
||||||
|
import org.jfree.data.xy.XYSeriesCollection;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import static javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED;
|
import static javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED;
|
||||||
|
@ -29,9 +37,10 @@ import java.util.List;
|
||||||
public final class EcuLogger extends JFrame implements WindowListener, PropertyChangeListener {
|
public final class EcuLogger extends JFrame implements WindowListener, PropertyChangeListener {
|
||||||
private final Settings settings = new Settings();
|
private final Settings settings = new Settings();
|
||||||
private final LoggerController CONTROLLER = new LoggerControllerImpl(settings);
|
private final LoggerController CONTROLLER = new LoggerControllerImpl(settings);
|
||||||
private final JTable dataTable = new JTable();
|
private final LoggerDataTableModel dataTableModel = new LoggerDataTableModel();
|
||||||
private final JTextArea dataTextArea = new JTextArea();
|
private final JPanel graphPanel = new JPanel();
|
||||||
private final JComboBox portsComboBox = new JComboBox();
|
private final JComboBox portsComboBox = new JComboBox();
|
||||||
|
private int loggerCount = 0;
|
||||||
|
|
||||||
public EcuLogger(String title) {
|
public EcuLogger(String title) {
|
||||||
super(title);
|
super(title);
|
||||||
|
@ -49,98 +58,63 @@ public final class EcuLogger extends JFrame implements WindowListener, PropertyC
|
||||||
|
|
||||||
// add test address to log (0x000008 = coolant temp, 8bit)
|
// add test address to log (0x000008 = coolant temp, 8bit)
|
||||||
final EcuParameter ecuParam1 = new EcuParameterImpl("Coolant Temperature", "Coolant temperature in degrees C", "0x000008", new GenericTemperatureConvertor());
|
final EcuParameter ecuParam1 = new EcuParameterImpl("Coolant Temperature", "Coolant temperature in degrees C", "0x000008", new GenericTemperatureConvertor());
|
||||||
CONTROLLER.addLogger(ecuParam1, new LoggerCallback() {
|
registerEcuParameterForLogging(ecuParam1);
|
||||||
public void callback(byte[] value, EcuParameterConvertor convertor) {
|
|
||||||
dataTextArea.append(ecuParam1.getName() + " (" + ecuParam1.getAddress() + ") => " + asHex(value) + " => " + convertor.convert(value)
|
|
||||||
+ " " + convertor.getUnits() + "\n");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// add test address to log (0x000106 = EGT, 8bit)
|
// add test address to log (0x000106 = EGT, 8bit)
|
||||||
final EcuParameter ecuParam2 = new EcuParameterImpl("EGT", "Exhaust gas temperature in degrees C", "0x000106", new ExhaustGasTemperatureConvertor());
|
final EcuParameter ecuParam2 = new EcuParameterImpl("EGT", "Exhaust gas temperature in degrees C", "0x000106", new ExhaustGasTemperatureConvertor());
|
||||||
CONTROLLER.addLogger(ecuParam2, new LoggerCallback() {
|
registerEcuParameterForLogging(ecuParam2);
|
||||||
public void callback(byte[] value, EcuParameterConvertor convertor) {
|
|
||||||
dataTextArea.append(ecuParam2.getName() + " (" + ecuParam2.getAddress() + ") => " + asHex(value) + " => " + convertor.convert(value)
|
|
||||||
+ " " + convertor.getUnits() + "\n");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// add test address to log (0x000046 = air/fuel ratio, 8bit)
|
// add test address to log (0x000046 = air/fuel ratio, 8bit)
|
||||||
final EcuParameter ecuParam3 = new EcuParameterImpl("AFR", "Air/Fuel Ratio in Lambda", "0x000046", new AirFuelRatioLambdaConvertor());
|
final EcuParameter ecuParam3 = new EcuParameterImpl("AFR", "Air/Fuel Ratio in Lambda", "0x000046", new AirFuelRatioLambdaConvertor());
|
||||||
CONTROLLER.addLogger(ecuParam3, new LoggerCallback() {
|
registerEcuParameterForLogging(ecuParam3);
|
||||||
public void callback(byte[] value, EcuParameterConvertor convertor) {
|
|
||||||
dataTextArea.append(ecuParam3.getName() + " (" + ecuParam3.getAddress() + ") => " + asHex(value) + " => " + convertor.convert(value)
|
|
||||||
+ " " + convertor.getUnits() + "\n");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// add test address to log (0x000029 = accelerator opening angle, 8bit)
|
// add test address to log (0x000029 = accelerator opening angle, 8bit)
|
||||||
final EcuParameter ecuParam4 = new EcuParameterImpl("Accel Opening Angle", "Accelerator opening angle in %", "0x000029", new AcceleratorOpeningAngleConvertor());
|
final EcuParameter ecuParam4 = new EcuParameterImpl("Accel Opening Angle", "Accelerator opening angle in %", "0x000029", new AcceleratorOpeningAngleConvertor());
|
||||||
CONTROLLER.addLogger(ecuParam4, new LoggerCallback() {
|
registerEcuParameterForLogging(ecuParam4);
|
||||||
public void callback(byte[] value, EcuParameterConvertor convertor) {
|
|
||||||
dataTextArea.append(ecuParam4.getName() + " (" + ecuParam4.getAddress() + ") => " + asHex(value) + " => " + convertor.convert(value)
|
|
||||||
+ " " + convertor.getUnits() + "\n");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// add test address to log (0x000015 = accelerator opening angle, 8bit)
|
// add test address to log (0x000015 = accelerator opening angle, 8bit)
|
||||||
final EcuParameter ecuParam5 = new EcuParameterImpl("Throttle Opening Angle", "Throttle opening angle in %", "0x000015", new ThrottleOpeningAngleConvertor());
|
final EcuParameter ecuParam5 = new EcuParameterImpl("Throttle Opening Angle", "Throttle opening angle in %", "0x000015", new ThrottleOpeningAngleConvertor());
|
||||||
CONTROLLER.addLogger(ecuParam5, new LoggerCallback() {
|
registerEcuParameterForLogging(ecuParam5);
|
||||||
public void callback(byte[] value, EcuParameterConvertor convertor) {
|
|
||||||
dataTextArea.append(ecuParam5.getName() + " (" + ecuParam5.getAddress() + ") => " + asHex(value) + " => " + convertor.convert(value)
|
|
||||||
+ " " + convertor.getUnits() + "\n");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// add test address to log (0x00000E 0x00000F = engine speed, 16bit)
|
// add test address to log (0x00000E 0x00000F = engine speed, 16bit)
|
||||||
// final EcuParameter ecuParam5 = new EcuParameterImpl("Engine Speed", "Engine speed in rpm", "0x00000E00000F", new EngineSpeedConvertor());
|
final EcuParameter ecuParam6 = new EcuParameterImpl("Engine Speed", "Engine speed in rpm", "0x00000E00000F", new EngineSpeedConvertor());
|
||||||
// CONTROLLER.addLogger(ecuParam5, new LoggerCallback() {
|
registerEcuParameterForLogging(ecuParam6);
|
||||||
// public void callback(byte[] value, EcuParameterConvertor convertor) {
|
|
||||||
// dataTextArea.append(ecuParam5.getName() + " (" + ecuParam5.getAddress() + ") => " + asHex(value) + " => " + convertor.convert(value)
|
|
||||||
// + " " + convertor.getUnits() + "\n");
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) {
|
private void registerEcuParameterForLogging(final EcuParameter ecuParam) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
// add to data table
|
||||||
public void run() {
|
final LoggerDataRow dataRow = new LoggerDataRow(ecuParam);
|
||||||
createAndShowGUI();
|
dataTableModel.addRow(dataRow);
|
||||||
|
|
||||||
|
// add to charts
|
||||||
|
final XYSeries series = new XYSeries(ecuParam.getName());
|
||||||
|
final XYDataset xyDataset = new XYSeriesCollection(series);
|
||||||
|
final JFreeChart chart = ChartFactory.createXYLineChart(ecuParam.getName(), "Time (ms)", ecuParam.getName() + " (" + ecuParam.getConvertor().getUnits() + ")",
|
||||||
|
xyDataset, PlotOrientation.VERTICAL, true, true, false);
|
||||||
|
final JLabel chartLabel = new JLabel();
|
||||||
|
chartLabel.setIcon(new ImageIcon(chart.createBufferedImage(500, 300)));
|
||||||
|
graphPanel.add(chartLabel);
|
||||||
|
SpringUtilities.makeCompactGrid(graphPanel, ++loggerCount, 1, 10, 10, 20, 20);
|
||||||
|
|
||||||
|
// add to dashboard
|
||||||
|
|
||||||
|
// add logger and setup callback
|
||||||
|
CONTROLLER.addLogger(ecuParam, new LoggerCallback() {
|
||||||
|
public void callback(byte[] value) {
|
||||||
|
// update data table
|
||||||
|
dataRow.updateValue(value);
|
||||||
|
|
||||||
|
// update graph
|
||||||
|
series.add(System.currentTimeMillis(), ecuParam.getConvertor().convert(value));
|
||||||
|
chartLabel.setIcon(new ImageIcon(chart.createBufferedImage(500, 300)));
|
||||||
|
|
||||||
|
// update dashboard
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createAndShowGUI() {
|
|
||||||
//set look and feel
|
|
||||||
setLookAndFeel();
|
|
||||||
|
|
||||||
//make sure we have nice window decorations.
|
|
||||||
setDefaultLookAndFeelDecorated(true);
|
|
||||||
JDialog.setDefaultLookAndFeelDecorated(true);
|
|
||||||
|
|
||||||
//instantiate the controlling class.
|
|
||||||
EcuLogger ecuLogger = new EcuLogger("Enginuity ECU Logger");
|
|
||||||
|
|
||||||
//set remaining window properties
|
|
||||||
ecuLogger.setSize(new Dimension(1000, 600));
|
|
||||||
ecuLogger.setIconImage(new ImageIcon("./graphics/enginuity-ico.gif").getImage());
|
|
||||||
ecuLogger.setDefaultCloseOperation(EXIT_ON_CLOSE);
|
|
||||||
ecuLogger.addWindowListener(ecuLogger);
|
|
||||||
|
|
||||||
//display the window
|
|
||||||
ecuLogger.setLocationRelativeTo(null); //center it
|
|
||||||
ecuLogger.setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setLookAndFeel() {
|
|
||||||
try {
|
|
||||||
//use the system look and feel.
|
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private JComponent buildLeftComponent() {
|
private JComponent buildLeftComponent() {
|
||||||
JTable parameterList = new JTable();
|
JTable parameterList = new JTable();
|
||||||
return new JScrollPane(parameterList, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
return new JScrollPane(parameterList, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||||
|
@ -217,12 +191,11 @@ public final class EcuLogger extends JFrame implements WindowListener, PropertyC
|
||||||
}
|
}
|
||||||
|
|
||||||
private JComponent buildDataTab() {
|
private JComponent buildDataTab() {
|
||||||
//return new JScrollPane(dataTable, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_NEVER);
|
return new JScrollPane(new JTable(dataTableModel), VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
return new JScrollPane(dataTextArea, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_NEVER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private JComponent buildGraphTab() {
|
private JComponent buildGraphTab() {
|
||||||
JPanel graphPanel = new JPanel();
|
graphPanel.setLayout(new SpringLayout());
|
||||||
return new JScrollPane(graphPanel, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_NEVER);
|
return new JScrollPane(graphPanel, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,4 +229,43 @@ public final class EcuLogger extends JFrame implements WindowListener, PropertyC
|
||||||
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
|
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
createAndShowGUI();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createAndShowGUI() {
|
||||||
|
//set look and feel
|
||||||
|
setLookAndFeel();
|
||||||
|
|
||||||
|
//make sure we have nice window decorations.
|
||||||
|
setDefaultLookAndFeelDecorated(true);
|
||||||
|
JDialog.setDefaultLookAndFeelDecorated(true);
|
||||||
|
|
||||||
|
//instantiate the controlling class.
|
||||||
|
EcuLogger ecuLogger = new EcuLogger("Enginuity ECU Logger");
|
||||||
|
|
||||||
|
//set remaining window properties
|
||||||
|
ecuLogger.setSize(new Dimension(1000, 600));
|
||||||
|
ecuLogger.setIconImage(new ImageIcon("./graphics/enginuity-ico.gif").getImage());
|
||||||
|
ecuLogger.setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||||
|
ecuLogger.addWindowListener(ecuLogger);
|
||||||
|
|
||||||
|
//display the window
|
||||||
|
ecuLogger.setLocationRelativeTo(null); //center it
|
||||||
|
ecuLogger.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setLookAndFeel() {
|
||||||
|
try {
|
||||||
|
//use the system look and feel.
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ public final class SerialConnectionImpl implements SerialConnection {
|
||||||
serialPort.setRTS(false);
|
serialPort.setRTS(false);
|
||||||
os.write(request, 0, request.length);
|
os.write(request, 0, request.length);
|
||||||
os.flush();
|
os.flush();
|
||||||
int timeout = 100;
|
int timeout = 1000;
|
||||||
while (is.available() < response.length) {
|
while (is.available() < response.length) {
|
||||||
TimeUnit.MILLISECONDS.sleep(5);
|
TimeUnit.MILLISECONDS.sleep(5);
|
||||||
timeout -= 5;
|
timeout -= 5;
|
||||||
|
|
|
@ -10,8 +10,6 @@ public interface EcuParameter {
|
||||||
|
|
||||||
String getAddress();
|
String getAddress();
|
||||||
|
|
||||||
String getValueLength();
|
|
||||||
|
|
||||||
EcuParameterConvertor getConvertor();
|
EcuParameterConvertor getConvertor();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,6 @@ public final class EcuParameterImpl implements EcuParameter {
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Is this required???
|
|
||||||
public String getValueLength() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EcuParameterConvertor getConvertor() {
|
public EcuParameterConvertor getConvertor() {
|
||||||
return convertor;
|
return convertor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,15 @@ import java.text.DecimalFormat;
|
||||||
public final class AcceleratorOpeningAngleConvertor implements EcuParameterConvertor {
|
public final class AcceleratorOpeningAngleConvertor implements EcuParameterConvertor {
|
||||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.0");
|
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.0");
|
||||||
|
|
||||||
public String convert(byte[] bytes) {
|
public double convert(byte[] bytes) {
|
||||||
double angle = (double) asInt(bytes) / 2.55;
|
return (double) asInt(bytes) / 2.55;
|
||||||
return AcceleratorOpeningAngleConvertor.DECIMAL_FORMAT.format(angle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUnits() {
|
public String getUnits() {
|
||||||
return "%";
|
return "%";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String format(double value) {
|
||||||
|
return DECIMAL_FORMAT.format(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,16 @@ import java.text.DecimalFormat;
|
||||||
public final class AirFuelRatioLambdaConvertor implements EcuParameterConvertor {
|
public final class AirFuelRatioLambdaConvertor implements EcuParameterConvertor {
|
||||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.0");
|
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.0");
|
||||||
|
|
||||||
public String convert(byte[] bytes) {
|
public double convert(byte[] bytes) {
|
||||||
double afr = (double) asInt(bytes) / 128.0;
|
return (double) asInt(bytes) / 128.0;
|
||||||
return DECIMAL_FORMAT.format(afr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUnits() {
|
public String getUnits() {
|
||||||
return "Lambda";
|
return "Lambda";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String format(double value) {
|
||||||
|
return DECIMAL_FORMAT.format(value);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,10 @@ package enginuity.logger.definition.convertor;
|
||||||
|
|
||||||
public interface EcuParameterConvertor {
|
public interface EcuParameterConvertor {
|
||||||
|
|
||||||
String convert(byte[] bytes);
|
double convert(byte[] bytes);
|
||||||
|
|
||||||
String getUnits();
|
String getUnits();
|
||||||
|
|
||||||
|
String format(double value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,20 @@ package enginuity.logger.definition.convertor;
|
||||||
|
|
||||||
import static enginuity.util.ByteUtil.asInt;
|
import static enginuity.util.ByteUtil.asInt;
|
||||||
|
|
||||||
public final class EngineSpeedConvertor implements EcuParameterConvertor {
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
public String convert(byte[] bytes) {
|
public final class EngineSpeedConvertor implements EcuParameterConvertor {
|
||||||
int rpm = asInt(bytes) / 4;
|
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0");
|
||||||
return String.valueOf(rpm);
|
|
||||||
|
public double convert(byte[] bytes) {
|
||||||
|
return asInt(bytes) / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUnits() {
|
public String getUnits() {
|
||||||
return "rpm";
|
return "rpm";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String format(double value) {
|
||||||
|
return DECIMAL_FORMAT.format(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,20 @@ package enginuity.logger.definition.convertor;
|
||||||
|
|
||||||
import static enginuity.util.ByteUtil.asInt;
|
import static enginuity.util.ByteUtil.asInt;
|
||||||
|
|
||||||
public final class ExhaustGasTemperatureConvertor implements EcuParameterConvertor {
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
public String convert(byte[] bytes) {
|
public final class ExhaustGasTemperatureConvertor implements EcuParameterConvertor {
|
||||||
int degreesC = (asInt(bytes) + 40) * 5;
|
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0");
|
||||||
return String.valueOf(degreesC);
|
|
||||||
|
public double convert(byte[] bytes) {
|
||||||
|
return (asInt(bytes) + 40) * 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUnits() {
|
public String getUnits() {
|
||||||
return "C";
|
return "C";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String format(double value) {
|
||||||
|
return DECIMAL_FORMAT.format(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,21 @@ package enginuity.logger.definition.convertor;
|
||||||
|
|
||||||
import static enginuity.util.ByteUtil.asInt;
|
import static enginuity.util.ByteUtil.asInt;
|
||||||
|
|
||||||
public final class GenericTemperatureConvertor implements EcuParameterConvertor {
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
public String convert(byte[] bytes) {
|
public final class GenericTemperatureConvertor implements EcuParameterConvertor {
|
||||||
int degreesC = asInt(bytes) - 40;
|
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0");
|
||||||
return String.valueOf(degreesC);
|
|
||||||
|
public double convert(byte[] bytes) {
|
||||||
|
return asInt(bytes) - 40;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUnits() {
|
public String getUnits() {
|
||||||
return "C";
|
return "C";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String format(double value) {
|
||||||
|
return DECIMAL_FORMAT.format(value);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
package enginuity.logger.definition.convertor;
|
|
||||||
|
|
||||||
import static enginuity.util.HexUtil.asHex;
|
|
||||||
|
|
||||||
public final class HexConvertor implements EcuParameterConvertor {
|
|
||||||
|
|
||||||
public String convert(byte[] bytes) {
|
|
||||||
return asHex(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUnits() {
|
|
||||||
return "hex";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,12 +7,15 @@ import java.text.DecimalFormat;
|
||||||
public final class ThrottleOpeningAngleConvertor implements EcuParameterConvertor {
|
public final class ThrottleOpeningAngleConvertor implements EcuParameterConvertor {
|
||||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.0");
|
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.0");
|
||||||
|
|
||||||
public String convert(byte[] bytes) {
|
public double convert(byte[] bytes) {
|
||||||
double angle = (double) asInt(bytes) / 2.55;
|
return (double) asInt(bytes) / 2.55;
|
||||||
return DECIMAL_FORMAT.format(angle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUnits() {
|
public String getUnits() {
|
||||||
return "%";
|
return "%";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String format(double value) {
|
||||||
|
return DECIMAL_FORMAT.format(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package enginuity.logger.manager;
|
||||||
import enginuity.Settings;
|
import enginuity.Settings;
|
||||||
import enginuity.logger.comms.SerialConnection;
|
import enginuity.logger.comms.SerialConnection;
|
||||||
import enginuity.logger.comms.SerialConnectionImpl;
|
import enginuity.logger.comms.SerialConnectionImpl;
|
||||||
import enginuity.logger.definition.convertor.EcuParameterConvertor;
|
|
||||||
import enginuity.logger.exception.NotConnectedException;
|
import enginuity.logger.exception.NotConnectedException;
|
||||||
import enginuity.logger.exception.SerialCommunicationException;
|
import enginuity.logger.exception.SerialCommunicationException;
|
||||||
import enginuity.logger.protocol.Protocol;
|
import enginuity.logger.protocol.Protocol;
|
||||||
|
@ -39,7 +38,7 @@ public final class TransmissionManagerImpl implements TransmissionManager {
|
||||||
|
|
||||||
public void sendEcuInit(LoggerCallback callback) {
|
public void sendEcuInit(LoggerCallback callback) {
|
||||||
if (serialConnection != null) {
|
if (serialConnection != null) {
|
||||||
callback.callback(serialConnection.sendEcuInit(), null);
|
callback.callback(serialConnection.sendEcuInit());
|
||||||
} else {
|
} else {
|
||||||
throw new NotConnectedException("TransmissionManager must be started before a query can be sent!");
|
throw new NotConnectedException("TransmissionManager must be started before a query can be sent!");
|
||||||
}
|
}
|
||||||
|
@ -66,7 +65,7 @@ public final class TransmissionManagerImpl implements TransmissionManager {
|
||||||
try {
|
try {
|
||||||
txManager.start();
|
txManager.start();
|
||||||
txManager.sendEcuInit(new LoggerCallback() {
|
txManager.sendEcuInit(new LoggerCallback() {
|
||||||
public void callback(byte[] value, EcuParameterConvertor convertor) {
|
public void callback(byte[] value) {
|
||||||
System.out.println("ECU Init Response = " + HexUtil.asHex(value));
|
System.out.println("ECU Init Response = " + HexUtil.asHex(value));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,9 +21,10 @@ public final class SSMProtocol implements Protocol {
|
||||||
private static final byte READ_ADDRESS_RESPONSE = (byte) 0xE8;
|
private static final byte READ_ADDRESS_RESPONSE = (byte) 0xE8;
|
||||||
private static final byte ECU_INIT_COMMAND = (byte) 0xBF;
|
private static final byte ECU_INIT_COMMAND = (byte) 0xBF;
|
||||||
private static final byte ECU_INIT_RESPONSE = (byte) 0xFF;
|
private static final byte ECU_INIT_RESPONSE = (byte) 0xFF;
|
||||||
private static final int NON_DATA_BYTES = 6;
|
private static final int RESPONSE_NON_DATA_BYTES = 6;
|
||||||
private static final int ADDRESS_SIZE = 3;
|
private static final int ADDRESS_SIZE = 3;
|
||||||
private static final int DATA_SIZE = 1;
|
private static final int DATA_SIZE = 1;
|
||||||
|
private static final int REQUEST_NON_DATA_BYTES = 7;
|
||||||
|
|
||||||
public byte[] constructReadMemoryRequest(RegisteredQuery query, int numBytes) {
|
public byte[] constructReadMemoryRequest(RegisteredQuery query, int numBytes) {
|
||||||
checkNotNull(query, "query");
|
checkNotNull(query, "query");
|
||||||
|
@ -42,7 +43,11 @@ public final class SSMProtocol implements Protocol {
|
||||||
public byte[] constructReadAddressResponse(Collection<RegisteredQuery> queries) {
|
public byte[] constructReadAddressResponse(Collection<RegisteredQuery> queries) {
|
||||||
checkNotNullOrEmpty(queries, "queries");
|
checkNotNullOrEmpty(queries, "queries");
|
||||||
// 0x80 0xF0 0x10 data_length 0xE8 value1 value2 ... valueN checksum
|
// 0x80 0xF0 0x10 data_length 0xE8 value1 value2 ... valueN checksum
|
||||||
return new byte[(DATA_SIZE * queries.size() + NON_DATA_BYTES) + (queries.size() * ADDRESS_SIZE + 7)];
|
int numAddresses = 0;
|
||||||
|
for (RegisteredQuery query : queries) {
|
||||||
|
numAddresses += (query.getBytes().length / ADDRESS_SIZE);
|
||||||
|
}
|
||||||
|
return new byte[(numAddresses * DATA_SIZE + RESPONSE_NON_DATA_BYTES) + (numAddresses * ADDRESS_SIZE + REQUEST_NON_DATA_BYTES)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"PointlessArithmeticExpression"})
|
@SuppressWarnings({"PointlessArithmeticExpression"})
|
||||||
|
@ -67,10 +72,9 @@ public final class SSMProtocol implements Protocol {
|
||||||
public byte[] extractResponseData(byte[] response) {
|
public byte[] extractResponseData(byte[] response) {
|
||||||
checkNotNullOrEmpty(response, "response");
|
checkNotNullOrEmpty(response, "response");
|
||||||
// 0x80 0xF0 0x10 data_length 0xE8 response_data checksum
|
// 0x80 0xF0 0x10 data_length 0xE8 response_data checksum
|
||||||
//TODO: Take possible echoed request into account when extracting response!!
|
|
||||||
validateResponse(response);
|
validateResponse(response);
|
||||||
byte[] data = new byte[response.length - NON_DATA_BYTES];
|
byte[] data = new byte[response.length - RESPONSE_NON_DATA_BYTES];
|
||||||
System.arraycopy(response, (NON_DATA_BYTES - 1), data, 0, data.length);
|
System.arraycopy(response, (RESPONSE_NON_DATA_BYTES - 1), data, 0, data.length);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +115,7 @@ public final class SSMProtocol implements Protocol {
|
||||||
assertEquals(HEADER, response[i++], "Invalid header");
|
assertEquals(HEADER, response[i++], "Invalid header");
|
||||||
assertEquals(DIAGNOSTIC_TOOL_ID, response[i++], "Invalid diagnostic tool id");
|
assertEquals(DIAGNOSTIC_TOOL_ID, response[i++], "Invalid diagnostic tool id");
|
||||||
assertEquals(ECU_ID, response[i++], "Invalid ECU id");
|
assertEquals(ECU_ID, response[i++], "Invalid ECU id");
|
||||||
assertEquals(asByte(response.length - NON_DATA_BYTES + 1), response[i++], "Invalid response data length");
|
assertEquals(asByte(response.length - RESPONSE_NON_DATA_BYTES + 1), response[i++], "Invalid response data length");
|
||||||
assertOneOf(new byte[]{READ_ADDRESS_RESPONSE, READ_MEMORY_RESPONSE, ECU_INIT_RESPONSE}, response[i], "Invalid response code");
|
assertOneOf(new byte[]{READ_ADDRESS_RESPONSE, READ_MEMORY_RESPONSE, ECU_INIT_RESPONSE}, response[i], "Invalid response code");
|
||||||
assertEquals(calculateChecksum(response), response[response.length - 1], "Invalid checksum");
|
assertEquals(calculateChecksum(response), response[response.length - 1], "Invalid checksum");
|
||||||
}
|
}
|
||||||
|
@ -147,7 +151,7 @@ public final class SSMProtocol implements Protocol {
|
||||||
System.arraycopy(tmp, 0, tmp2, data.length, tmp.length);
|
System.arraycopy(tmp, 0, tmp2, data.length, tmp.length);
|
||||||
data = tmp2;
|
data = tmp2;
|
||||||
}
|
}
|
||||||
byte[] request = new byte[data.length + (padContent ? 7 : NON_DATA_BYTES)];
|
byte[] request = new byte[data.length + (padContent ? REQUEST_NON_DATA_BYTES : RESPONSE_NON_DATA_BYTES)];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
request[i++] = HEADER;
|
request[i++] = HEADER;
|
||||||
request[i++] = ECU_ID;
|
request[i++] = ECU_ID;
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package enginuity.logger.query;
|
package enginuity.logger.query;
|
||||||
|
|
||||||
import enginuity.logger.definition.convertor.EcuParameterConvertor;
|
|
||||||
|
|
||||||
public interface LoggerCallback {
|
public interface LoggerCallback {
|
||||||
|
|
||||||
void callback(byte[] value, EcuParameterConvertor convertor);
|
void callback(byte[] value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,6 @@ import enginuity.logger.definition.EcuParameter;
|
||||||
import static enginuity.util.HexUtil.asBytes;
|
import static enginuity.util.HexUtil.asBytes;
|
||||||
import static enginuity.util.ParamChecker.checkNotNull;
|
import static enginuity.util.ParamChecker.checkNotNull;
|
||||||
|
|
||||||
//TODO: change address into an EcuParameter object with getAddress() & getLength() methods
|
|
||||||
//TODO: use the getLength() method to do the response data extraction in SSMProtocol
|
|
||||||
|
|
||||||
@SuppressWarnings({"FieldCanBeLocal"})
|
|
||||||
public final class RegisteredQueryImpl implements RegisteredQuery {
|
public final class RegisteredQueryImpl implements RegisteredQuery {
|
||||||
private final EcuParameter ecuParam;
|
private final EcuParameter ecuParam;
|
||||||
private final LoggerCallback callback;
|
private final LoggerCallback callback;
|
||||||
|
@ -29,6 +25,6 @@ public final class RegisteredQueryImpl implements RegisteredQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResponse(byte[] response) {
|
public void setResponse(byte[] response) {
|
||||||
callback.callback(response, ecuParam.getConvertor());
|
callback.callback(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package enginuity.logger.ui;
|
||||||
|
|
||||||
|
import enginuity.logger.definition.EcuParameter;
|
||||||
|
|
||||||
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
|
||||||
|
public final class LoggerDataRow {
|
||||||
|
private EcuParameter ecuParam;
|
||||||
|
private AbstractTableModel parentTableModel;
|
||||||
|
private double minValue;
|
||||||
|
private double maxValue;
|
||||||
|
private double currentValue;
|
||||||
|
|
||||||
|
public LoggerDataRow(EcuParameter ecuParam) {
|
||||||
|
this.ecuParam = ecuParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return ecuParam.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMinValue() {
|
||||||
|
return ecuParam.getConvertor().format(minValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMaxValue() {
|
||||||
|
return ecuParam.getConvertor().format(maxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrentValue() {
|
||||||
|
return ecuParam.getConvertor().format(currentValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUnits() {
|
||||||
|
return ecuParam.getConvertor().getUnits();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateValue(byte[] bytes) {
|
||||||
|
currentValue = ecuParam.getConvertor().convert(bytes);
|
||||||
|
if (currentValue < minValue || minValue == 0.0) {
|
||||||
|
minValue = currentValue;
|
||||||
|
}
|
||||||
|
if (currentValue > maxValue || maxValue == 0.0) {
|
||||||
|
maxValue = currentValue;
|
||||||
|
}
|
||||||
|
parentTableModel.fireTableDataChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParentTableModel(AbstractTableModel parentTableModel) {
|
||||||
|
this.parentTableModel = parentTableModel;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package enginuity.logger.ui;
|
||||||
|
|
||||||
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
|
||||||
|
public final class LoggerDataTableModel extends AbstractTableModel {
|
||||||
|
String[] columnNames = {"ECU Parameter", "Min Value", "Current Value", "Max Value", "Units"};
|
||||||
|
LoggerDataRow[] data = new LoggerDataRow[0];
|
||||||
|
|
||||||
|
public int getRowCount() {
|
||||||
|
return data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColumnCount() {
|
||||||
|
return columnNames.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getColumnName(int col) {
|
||||||
|
return columnNames[col];
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCellEditable(int row, int col) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValueAt(int row, int col) {
|
||||||
|
switch (col) {
|
||||||
|
case 0:
|
||||||
|
return data[row].getName();
|
||||||
|
case 1:
|
||||||
|
return data[row].getMinValue();
|
||||||
|
case 2:
|
||||||
|
return data[row].getCurrentValue();
|
||||||
|
case 3:
|
||||||
|
return data[row].getMaxValue();
|
||||||
|
case 4:
|
||||||
|
return data[row].getUnits();
|
||||||
|
default:
|
||||||
|
return "Error!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void addRow(LoggerDataRow newRow) {
|
||||||
|
newRow.setParentTableModel(this);
|
||||||
|
LoggerDataRow[] newData = new LoggerDataRow[data.length + 1];
|
||||||
|
System.arraycopy(data, 0, newData, 0, data.length);
|
||||||
|
newData[newData.length - 1] = newRow;
|
||||||
|
data = newData;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,197 @@
|
||||||
|
package enginuity.logger.ui;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 1.4 file that provides utility methods for
|
||||||
|
* creating form- or grid-style layouts with SpringLayout.
|
||||||
|
* These utilities are used by several programs, such as
|
||||||
|
* SpringBox and SpringCompactGrid.
|
||||||
|
*/
|
||||||
|
public class SpringUtilities {
|
||||||
|
|
||||||
|
private SpringUtilities() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A debugging utility that prints to stdout the component's
|
||||||
|
* minimum, preferred, and maximum sizes.
|
||||||
|
*/
|
||||||
|
public static void printSizes(Component c) {
|
||||||
|
System.out.println("minimumSize = " + c.getMinimumSize());
|
||||||
|
System.out.println("preferredSize = " + c.getPreferredSize());
|
||||||
|
System.out.println("maximumSize = " + c.getMaximumSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aligns the first <code>rows</code> * <code>cols</code>
|
||||||
|
* components of <code>parent</code> in
|
||||||
|
* a grid. Each component is as big as the maximum
|
||||||
|
* preferred width and height of the components.
|
||||||
|
* The parent is made just big enough to fit them all.
|
||||||
|
*
|
||||||
|
* @param rows number of rows
|
||||||
|
* @param cols number of columns
|
||||||
|
* @param initialX x location to start the grid at
|
||||||
|
* @param initialY y location to start the grid at
|
||||||
|
* @param xPad x padding between cells
|
||||||
|
* @param yPad y padding between cells
|
||||||
|
*/
|
||||||
|
public static void makeGrid(Container parent,
|
||||||
|
int rows, int cols,
|
||||||
|
int initialX, int initialY,
|
||||||
|
int xPad, int yPad) {
|
||||||
|
SpringLayout layout;
|
||||||
|
try {
|
||||||
|
layout = (SpringLayout)parent.getLayout();
|
||||||
|
} catch (ClassCastException exc) {
|
||||||
|
System.err.println("The first argument to makeGrid must use SpringLayout.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Spring xPadSpring = Spring.constant(xPad);
|
||||||
|
Spring yPadSpring = Spring.constant(yPad);
|
||||||
|
Spring initialXSpring = Spring.constant(initialX);
|
||||||
|
Spring initialYSpring = Spring.constant(initialY);
|
||||||
|
int max = rows * cols;
|
||||||
|
|
||||||
|
//Calculate Springs that are the max of the width/height so that all
|
||||||
|
//cells have the same size.
|
||||||
|
Spring maxWidthSpring = layout.getConstraints(parent.getComponent(0)).
|
||||||
|
getWidth();
|
||||||
|
Spring maxHeightSpring = layout.getConstraints(parent.getComponent(0)).
|
||||||
|
getWidth();
|
||||||
|
for (int i = 1; i < max; i++) {
|
||||||
|
SpringLayout.Constraints cons = layout.getConstraints(
|
||||||
|
parent.getComponent(i));
|
||||||
|
|
||||||
|
maxWidthSpring = Spring.max(maxWidthSpring, cons.getWidth());
|
||||||
|
maxHeightSpring = Spring.max(maxHeightSpring, cons.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Apply the new width/height Spring. This forces all the
|
||||||
|
//components to have the same size.
|
||||||
|
for (int i = 0; i < max; i++) {
|
||||||
|
SpringLayout.Constraints cons = layout.getConstraints(
|
||||||
|
parent.getComponent(i));
|
||||||
|
|
||||||
|
cons.setWidth(maxWidthSpring);
|
||||||
|
cons.setHeight(maxHeightSpring);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Then adjust the x/y constraints of all the cells so that they
|
||||||
|
//are aligned in a grid.
|
||||||
|
SpringLayout.Constraints lastCons = null;
|
||||||
|
SpringLayout.Constraints lastRowCons = null;
|
||||||
|
for (int i = 0; i < max; i++) {
|
||||||
|
SpringLayout.Constraints cons = layout.getConstraints(
|
||||||
|
parent.getComponent(i));
|
||||||
|
if (i % cols == 0) { //start of new row
|
||||||
|
lastRowCons = lastCons;
|
||||||
|
cons.setX(initialXSpring);
|
||||||
|
} else { //x position depends on previous component
|
||||||
|
cons.setX(Spring.sum(lastCons.getConstraint(SpringLayout.EAST),
|
||||||
|
xPadSpring));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i / cols == 0) { //first row
|
||||||
|
cons.setY(initialYSpring);
|
||||||
|
} else { //y position depends on previous row
|
||||||
|
cons.setY(Spring.sum(lastRowCons.getConstraint(SpringLayout.SOUTH),
|
||||||
|
yPadSpring));
|
||||||
|
}
|
||||||
|
lastCons = cons;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the parent's size.
|
||||||
|
SpringLayout.Constraints pCons = layout.getConstraints(parent);
|
||||||
|
pCons.setConstraint(SpringLayout.SOUTH,
|
||||||
|
Spring.sum(
|
||||||
|
Spring.constant(yPad),
|
||||||
|
lastCons.getConstraint(SpringLayout.SOUTH)));
|
||||||
|
pCons.setConstraint(SpringLayout.EAST,
|
||||||
|
Spring.sum(
|
||||||
|
Spring.constant(xPad),
|
||||||
|
lastCons.getConstraint(SpringLayout.EAST)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Used by makeCompactGrid. */
|
||||||
|
private static SpringLayout.Constraints getConstraintsForCell(
|
||||||
|
int row, int col,
|
||||||
|
Container parent,
|
||||||
|
int cols) {
|
||||||
|
SpringLayout layout = (SpringLayout) parent.getLayout();
|
||||||
|
Component c = parent.getComponent(row * cols + col);
|
||||||
|
return layout.getConstraints(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aligns the first <code>rows</code> * <code>cols</code>
|
||||||
|
* components of <code>parent</code> in
|
||||||
|
* a grid. Each component in a column is as wide as the maximum
|
||||||
|
* preferred width of the components in that column;
|
||||||
|
* height is similarly determined for each row.
|
||||||
|
* The parent is made just big enough to fit them all.
|
||||||
|
*
|
||||||
|
* @param rows number of rows
|
||||||
|
* @param cols number of columns
|
||||||
|
* @param initialX x location to start the grid at
|
||||||
|
* @param initialY y location to start the grid at
|
||||||
|
* @param xPad x padding between cells
|
||||||
|
* @param yPad y padding between cells
|
||||||
|
*/
|
||||||
|
public static void makeCompactGrid(Container parent,
|
||||||
|
int rows, int cols,
|
||||||
|
int initialX, int initialY,
|
||||||
|
int xPad, int yPad) {
|
||||||
|
SpringLayout layout;
|
||||||
|
try {
|
||||||
|
layout = (SpringLayout)parent.getLayout();
|
||||||
|
} catch (ClassCastException exc) {
|
||||||
|
System.err.println("The first argument to makeCompactGrid must use SpringLayout.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Align all cells in each column and make them the same width.
|
||||||
|
Spring x = Spring.constant(initialX);
|
||||||
|
for (int c = 0; c < cols; c++) {
|
||||||
|
Spring width = Spring.constant(0);
|
||||||
|
for (int r = 0; r < rows; r++) {
|
||||||
|
width = Spring.max(width,
|
||||||
|
getConstraintsForCell(r, c, parent, cols).
|
||||||
|
getWidth());
|
||||||
|
}
|
||||||
|
for (int r = 0; r < rows; r++) {
|
||||||
|
SpringLayout.Constraints constraints =
|
||||||
|
getConstraintsForCell(r, c, parent, cols);
|
||||||
|
constraints.setX(x);
|
||||||
|
constraints.setWidth(width);
|
||||||
|
}
|
||||||
|
x = Spring.sum(x, Spring.sum(width, Spring.constant(xPad)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Align all cells in each row and make them the same height.
|
||||||
|
Spring y = Spring.constant(initialY);
|
||||||
|
for (int r = 0; r < rows; r++) {
|
||||||
|
Spring height = Spring.constant(0);
|
||||||
|
for (int c = 0; c < cols; c++) {
|
||||||
|
height = Spring.max(height,
|
||||||
|
getConstraintsForCell(r, c, parent, cols).
|
||||||
|
getHeight());
|
||||||
|
}
|
||||||
|
for (int c = 0; c < cols; c++) {
|
||||||
|
SpringLayout.Constraints constraints =
|
||||||
|
getConstraintsForCell(r, c, parent, cols);
|
||||||
|
constraints.setY(y);
|
||||||
|
constraints.setHeight(height);
|
||||||
|
}
|
||||||
|
y = Spring.sum(y, Spring.sum(height, Spring.constant(yPad)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the parent's size.
|
||||||
|
SpringLayout.Constraints pCons = layout.getConstraints(parent);
|
||||||
|
pCons.setConstraint(SpringLayout.SOUTH, y);
|
||||||
|
pCons.setConstraint(SpringLayout.EAST, x);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue