001package jmri.jmrix.can.cbus.swing.console; 002 003import java.util.LinkedList; 004import java.util.Locale; 005import java.util.TimerTask; 006 007import javax.swing.BorderFactory; 008import javax.swing.JButton; 009import javax.swing.JTextField; 010 011/** 012 * Panel for CBUS Console Stats 013 * 014 * @author Andrew Crosland Copyright (C) 2008 015 * @author Steve Young Copyright (C) 2018 016 */ 017public class CbusConsoleStatsPane extends javax.swing.JPanel { 018 019 private JTextField sentCountField; 020 private JTextField rcvdCountField; 021 private JTextField eventsCountField; 022 private JTextField dccCountField; 023 private JTextField totalCountField; 024 private JTextField framesLastSecondField; 025 private JTextField meanFramesPerSecondField; 026 private JTextField maxFramesPerSecondField; 027 private JButton statsClearButton; 028 029 private int sentTotal = 0; 030 private int rcvdTotal = 0; 031 private int eventTotal = 0; 032 private int dccTotal = 0; 033 private int total = 0; 034 private int maxPerSecondCount = 0; 035 private long startTime; 036 037 private final LinkedList<Long> frameTimes; 038 private transient TimerTask keepAliveTimer = null; 039 private boolean disposed = false; 040 041 public CbusConsoleStatsPane(CbusConsolePane mainPane){ 042 super(); 043 frameTimes = new LinkedList<>(); 044 initButtons(); 045 addToPanel(); 046 CbusConsoleStatsPane.this.setLayout(new jmri.util.swing.WrapLayout()); 047 } 048 049 private void addToPanel() { 050 051 setBorder(BorderFactory.createTitledBorder( 052 BorderFactory.createEtchedBorder(), Bundle.getMessage("StatisticsTitle"))); 053 add(sentCountField); 054 add(rcvdCountField); 055 add(totalCountField); 056 add(eventsCountField); 057 add(dccCountField); 058 add(framesLastSecondField); 059 add(meanFramesPerSecondField); 060 add(maxFramesPerSecondField); 061 062 add(statsClearButton); 063 statsClearButton.addActionListener(this::statsClearButtonActionPerformed); 064 startUpdateTimer(); 065 066 } 067 068 protected void incremenetTotal(){ 069 total++; 070 long currentTime = System.currentTimeMillis(); 071 frameTimes.add(currentTime); 072 countFramesInLastSecond(currentTime); // update Max value 073 } 074 075 protected void incremenetReceived(){ 076 rcvdTotal++; 077 } 078 079 protected void incremenetSent(){ 080 sentTotal++; 081 } 082 083 protected void incrementEvents() { 084 eventTotal++; 085 } 086 087 protected void incrementDcc() { 088 dccTotal++; 089 } 090 091 private void initButtons() { 092 sentCountField = new JTextField("0", 7); 093 rcvdCountField = new JTextField("0", 7); 094 eventsCountField = new JTextField("0", 7); 095 dccCountField = new JTextField("0", 7); 096 totalCountField = new JTextField("0", 7); 097 framesLastSecondField = new JTextField("0", 7); 098 meanFramesPerSecondField = new JTextField("0", 7); 099 maxFramesPerSecondField = new JTextField("0", 7); 100 statsClearButton = new JButton(); 101 initButtonBorderToolTips(); 102 } 103 104 private void initButtonBorderToolTips(){ 105 106 sentCountField.setToolTipText(Bundle.getMessage("TooltipSent")); 107 sentCountField.setBorder(BorderFactory.createTitledBorder( 108 BorderFactory.createEtchedBorder(), Bundle.getMessage("SentTitle"))); 109 110 rcvdCountField.setToolTipText(Bundle.getMessage("TooltipReceived")); 111 rcvdCountField.setBorder(BorderFactory.createTitledBorder( 112 BorderFactory.createEtchedBorder(), Bundle.getMessage("ReceivedTitle"))); 113 114 eventsCountField.setToolTipText(Bundle.getMessage("eventsCountFieldTip")); 115 eventsCountField.setBorder(BorderFactory.createTitledBorder( 116 BorderFactory.createEtchedBorder(), Bundle.getMessage("CbusEvents"))); 117 118 dccCountField.setToolTipText(Bundle.getMessage("dccCountFieldTip")); 119 dccCountField.setBorder(BorderFactory.createTitledBorder( 120 BorderFactory.createEtchedBorder(), Bundle.getMessage("dccCountField"))); 121 122 totalCountField.setToolTipText(Bundle.getMessage("totalCountFieldTip")); 123 totalCountField.setBorder(BorderFactory.createTitledBorder( 124 BorderFactory.createEtchedBorder(), Bundle.getMessage("totalCountField"))); 125 126 framesLastSecondField.setToolTipText(Bundle.getMessage("FramesPerSecondTip")); 127 framesLastSecondField.setBorder(BorderFactory.createTitledBorder( 128 BorderFactory.createEtchedBorder(), Bundle.getMessage("FramesPerSecond"))); 129 130 meanFramesPerSecondField.setToolTipText(Bundle.getMessage("AverageFramesPerSecondTip")); 131 meanFramesPerSecondField.setBorder(BorderFactory.createTitledBorder( 132 BorderFactory.createEtchedBorder(), Bundle.getMessage("AverageFramesPerSecond"))); 133 134 maxFramesPerSecondField.setToolTipText(Bundle.getMessage("MaxFramesPerSecondTip")); 135 maxFramesPerSecondField.setBorder(BorderFactory.createTitledBorder( 136 BorderFactory.createEtchedBorder(), Bundle.getMessage("MaxFramesPerSecond"))); 137 138 statsClearButton.setText(Bundle.getMessage("ButtonReset")); 139 statsClearButton.setVisible(true); 140 } 141 142 private void statsClearButtonActionPerformed(java.awt.event.ActionEvent e) { 143 frameTimes.clear(); 144 startTime = System.currentTimeMillis(); 145 sentTotal = 0; 146 rcvdTotal = 0; 147 eventTotal = 0; 148 dccTotal = 0; 149 total = 0; 150 maxPerSecondCount = 0; 151 } 152 153 /** 154 * Set up the GUI Update Timer, and start it. 155 */ 156 private void startUpdateTimer() { 157 disposed = false; 158 startTime = System.currentTimeMillis(); 159 keepAliveTimer = new TimerTask(){ 160 @Override 161 public void run () { 162 if ( disposed ) { 163 return; 164 } 165 long currentTime = System.currentTimeMillis(); 166 float secsDuration = (currentTime-startTime)/1000f; 167 framesLastSecondField.setText(Integer.toString( 168 countFramesInLastSecond(currentTime))); 169 maxFramesPerSecondField.setText(Integer.toString(maxPerSecondCount)); 170 float average = total / secsDuration; 171 meanFramesPerSecondField.setText(String.format(Locale.getDefault(), "%.01f", average)); 172 totalCountField.setText(Integer.toString(total)); 173 rcvdCountField.setText(Integer.toString(rcvdTotal)); 174 sentCountField.setText(Integer.toString(sentTotal)); 175 eventsCountField.setText(Integer.toString(eventTotal)); 176 dccCountField.setText(Integer.toString(dccTotal)); 177 statsClearButton.setToolTipText(Bundle.getMessage("ResetButtonLastRestTip", 178 String.format(Locale.getDefault(), "%.01f", secsDuration))); 179 jmri.util.TimerUtil.scheduleOnGUIThread(keepAliveTimer, 500); 180 } 181 }; 182 jmri.util.TimerUtil.scheduleOnGUIThread(keepAliveTimer, 500); 183 } 184 185 private int countFramesInLastSecond(long currentTime) { 186 while (!frameTimes.isEmpty() && currentTime - frameTimes.peek() > 1000) { 187 frameTimes.remove(); // Remove Frames older than 1 second 188 } 189 maxPerSecondCount = Math.max(maxPerSecondCount, frameTimes.size()); 190 return frameTimes.size(); 191 } 192 193 public void dispose() { 194 disposed = true; // cancels GUI updates 195 if (keepAliveTimer != null) { 196 keepAliveTimer.cancel(); 197 keepAliveTimer = null; 198 } 199 } 200 201 // private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CbusConsoleStatsPane.class); 202 203}