001package jmri.jmrix.rps.swing.soundset; 002 003import java.awt.FlowLayout; 004import java.awt.event.ActionListener; 005import java.beans.PropertyChangeListener; 006import javax.swing.BoxLayout; 007import javax.swing.JButton; 008import javax.swing.JCheckBox; 009import javax.swing.JLabel; 010import javax.swing.JPanel; 011import javax.swing.JSeparator; 012import javax.swing.JTextField; 013import jmri.jmrix.rps.Distributor; 014import jmri.jmrix.rps.Engine; 015import jmri.jmrix.rps.Measurement; 016import jmri.jmrix.rps.MeasurementListener; 017import jmri.jmrix.rps.Reading; 018import jmri.jmrix.rps.ReadingListener; 019import org.slf4j.Logger; 020import org.slf4j.LoggerFactory; 021 022/** 023 * Frame for control of the sound speed for the RPS system. 024 * 025 * @author Bob Jacobsen Copyright (C) 2008 026 */ 027public class SoundSetPane extends JPanel 028 implements ReadingListener, MeasurementListener, PropertyChangeListener { 029 030 public SoundSetPane() { 031 super(); 032 } 033 034 public void dispose() { 035 // separate from data source 036 Distributor.instance().removeReadingListener(this); 037 Distributor.instance().removeMeasurementListener(this); 038 Engine.instance().removePropertyChangeListener(this); 039 } 040 041 JTextField vsound; 042 JTextField newval; 043 JTextField dist; 044 JTextField id; 045 JTextField rcvr; 046 JTextField speed; 047 JCheckBox auto; 048 JTextField gain; 049 050 @Override 051 public void propertyChange(java.beans.PropertyChangeEvent e) { 052 if (e.getPropertyName().equals("vSound")) { 053 // update sound display 054 vsound.setText(nf.format(e.getNewValue())); 055 } 056 } 057 058 public void initComponents() { 059 // number format 060 nf = java.text.NumberFormat.getInstance(); 061 nf.setMinimumFractionDigits(1); 062 nf.setMaximumFractionDigits(5); 063 nf.setGroupingUsed(false); 064 065 // GUI 066 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 067 068 // current value 069 JPanel p = new JPanel(); 070 p.setLayout(new FlowLayout()); 071 p.add(new JLabel("Current sound velocity: ")); 072 vsound = new JTextField(5); 073 vsound.setEnabled(false); 074 vsound.setText(nf.format(Engine.instance().getVSound())); 075 p.add(vsound); 076 this.add(p); 077 078 this.add(new JSeparator()); 079 080 // set new value 081 p = new JPanel(); 082 p.setLayout(new FlowLayout()); 083 p.add(new JLabel("New sound velocity: ")); 084 newval = new JTextField(8); 085 p.add(newval); 086 JButton b = new JButton("Set"); 087 b.addActionListener(new ActionListener() { 088 @Override 089 public void actionPerformed(java.awt.event.ActionEvent e) { 090 setPushed(); 091 } 092 }); 093 p.add(b); 094 this.add(p); 095 096 this.add(new JSeparator()); 097 098 // calculate new speed 099 p = new JPanel(); 100 p.setLayout(new FlowLayout()); 101 p.add(new JLabel("Known Distance: ")); 102 dist = new JTextField(5); 103 p.add(dist); 104 p.add(new JLabel("Transmitter ID: ")); 105 id = new JTextField(5); 106 p.add(id); 107 p.add(new JLabel("Receiver Number: ")); 108 rcvr = new JTextField(3); 109 p.add(rcvr); 110 this.add(p); 111 p = new JPanel(); 112 p.setLayout(new FlowLayout()); 113 p.add(new JLabel("Measured Speed: ")); 114 speed = new JTextField(8); 115 speed.setEnabled(false); 116 p.add(speed); 117 auto = new JCheckBox("Auto Set"); 118 p.add(auto); 119 p.add(new JLabel("Damping: ")); 120 gain = new JTextField(3); 121 gain.setText("10."); 122 p.add(gain); 123 this.add(p); 124 125 // start working 126 Distributor.instance().addReadingListener(this); 127 Distributor.instance().addMeasurementListener(this); 128 Engine.instance().addPropertyChangeListener(this); 129 } 130 131 void setPushed() { 132 double val = Double.parseDouble(newval.getText()); 133 Engine.instance().setVSound(val); 134 } 135 136 java.text.NumberFormat nf; 137 138 @Override 139 public void notify(Reading r) { 140 try { 141 // right ID? 142 if (!r.getId().equals(id.getText())) { 143 return; 144 } 145 146 // get the right measurement 147 int i = Integer.parseInt(rcvr.getText()); 148 if (i < 1 || i > r.getNValues()) { 149 log.warn("resetting receiver number"); 150 rcvr.setText(""); 151 } 152 log.debug("Rcvr {} saw {}", i, r.getValue(i)); 153 double val = r.getValue(i); 154 155 // can't use speed too small 156 if (val < 100) { 157 log.warn("time too small to use: {}", val); 158 return; 159 } 160 161 // calculate speed 162 double newspeed = Double.parseDouble(dist.getText()) / val; 163 speed.setText(nf.format(newspeed)); 164 165 // if auto, do update 166 if (auto.isSelected()) { 167 double g = Double.parseDouble(gain.getText()); 168 if (g < 1) { 169 log.warn("resetting gain from {}", gain.getText()); 170 gain.setText("10."); 171 return; 172 } 173 double updatedspeed = (newspeed + g * Engine.instance().getVSound()) / (g + 1); 174 Engine.instance().setVSound(updatedspeed); 175 } 176 } catch (Exception e) { 177 log.debug("Error calculating speed: {}", e); 178 speed.setText(""); 179 } 180 } 181 182 @Override 183 public void notify(Measurement m) { 184 // don't have to do anything 185 } 186 187 private final static Logger log = LoggerFactory.getLogger(SoundSetPane.class); 188 189}