001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.iso.gui; 020 021import org.jpos.iso.ISOMsg; 022 023import javax.swing.*; 024import java.awt.*; 025import java.awt.event.MouseAdapter; 026import java.awt.event.MouseEvent; 027import java.awt.event.MouseListener; 028 029/** 030 * ISOMsgPanel 031 * Swing based GUI to ISOMsg 032 * @author apr@cs.com.uy 033 * @author Kris Leite <kleite at imcsoftware.com> 034 * @see org.jpos.iso.ISOMsg 035 */ 036@SuppressWarnings("deprecation") 037public class ISOMeter extends JComponent implements Runnable { 038 039 private static final long serialVersionUID = -1770533267122111538L; 040 /** 041 * @serial 042 */ 043 Color color = new Color (255, 255, 255); 044 /** 045 * @serial 046 */ 047 Image im; 048 /** 049 * @serial 050 */ 051 Graphics img; 052 /** 053 * @serial 054 */ 055 Font fontBig, fontSmall; 056 /** 057 * @serial 058 */ 059 String positiveText; 060 /** 061 * @serial 062 */ 063 String negativeText; 064 /** 065 * @serial 066 */ 067 Timer ti; 068 /** 069 * handle ISOMeter's counters outside of this class in order 070 * to reduce 'int' to 'String' conversions. 071 * @serial 072 */ 073 String positiveCounter; 074 /** 075 * @serial 076 */ 077 String negativeCounter; 078 /** 079 * @serial 080 */ 081 int lastPositive; 082 /** 083 * @serial 084 */ 085 int lastNegative; 086 /** 087 * @serial 088 */ 089 boolean connected; 090 /** 091 * @serial 092 */ 093 ISOChannelPanel parent; 094 095 final static int width = 200; 096 final static int height = 60; 097 final static int mass = height/2; 098 final static int MAX_VALUE = 1000; 099 100 /** 101 * @serial 102 */ 103 int[] yPoints; 104 /** 105 * @serial 106 */ 107 int[] xPoints; 108 /** 109 * counter to keep the scrolling active 110 */ 111 int continueScroll; 112 /** 113 * used to determine if to scroll mark to end of graph 114 */ 115 boolean scroll = true; 116 /** 117 * Refresh panel in millseconds 118 */ 119 int refreshPanel = 50; 120 121 private Image imb; 122 private Thread repaintThread; 123 124 public ISOMeter(ISOChannelPanel parent) { 125 super(); 126 this.parent = parent; 127 128 fontBig = new Font ("Helvetica", Font.ITALIC, mass*3/4); 129 fontSmall = new Font ("Helvetica", Font.PLAIN, 10); 130 yPoints = new int[width]; 131 xPoints = new int[width]; 132 for (int i=0; i<width; i++) { 133 xPoints[i] = i; 134 yPoints[i] = mass; 135 } 136 positiveText = null; 137 negativeText = null; 138 positiveCounter = negativeCounter = ""; 139 connected = false; 140 141 MouseListener mouseListener = new MouseAdapter() { 142 public void mouseClicked(MouseEvent e) { 143 showLogList(); 144 } 145 }; 146 addMouseListener(mouseListener); 147 } 148 149 public synchronized void start() { 150 if (repaintThread == null) { 151 repaintThread = new Thread (this,"ISOMeter"); 152 repaintThread.setPriority (Thread.NORM_PRIORITY-1); 153 repaintThread.start(); 154 } 155 } 156 157 public void showLogList() { 158 JFrame f = new JFrame(parent.getSymbolicName()); 159 f.getContentPane().add(createLogList()); 160 f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 161 f.validate(); 162 f.pack(); 163 f.setSize(width,width+50); 164 f.show(); 165 } 166 167 public JComponent createLogList() { 168 final JList logList = new JList(parent.getLog()); 169 JPanel A = new JPanel(); 170 A.setLayout(new BorderLayout()); 171 172 MouseListener mouseListener = new MouseAdapter() { 173 public void mouseClicked(MouseEvent e) { 174 ISOMsg m = (ISOMsg) logList.getSelectedValue(); 175 if (m != null) { 176 JFrame f = new JFrame( 177 parent.getSymbolicName()+":"+m.toString()); 178 ISOMsgPanel p = new ISOMsgPanel(m); 179 f.getContentPane().add(p); 180 f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 181 f.pack(); 182 f.show(); 183 } 184 } 185 }; 186 logList.addMouseListener(mouseListener); 187 188 logList.setPrototypeCellValue("9999 99999999 999999"); 189 JScrollPane scrollPane = new JScrollPane(logList); 190 A.add(scrollPane, BorderLayout.CENTER); 191 return A; 192 } 193 194 public void setValue(int val) { 195 int y = mass - val%1000 * height / 2000; 196 yPoints[width-1] = y; 197 continueScroll = width; 198 scroll(); 199 } 200 201 public void setScroll (boolean scroll) { 202 this.scroll = scroll; 203 } 204 public void setRefresh (int refreshPanel) { 205 if (refreshPanel > 0) 206 this.refreshPanel = refreshPanel; 207 } 208 public void setConnected(boolean connected) { 209 if (this.connected != connected) { 210 if (!scroll) 211 if (connected) 212 continueScroll = width; 213 else 214 continueScroll = 1; 215 repaint(); 216 } 217 this.connected = connected; 218 } 219 public void setPositiveCounter(String s) { 220 positiveCounter = s; 221 } 222 public void setNegativeCounter(String s){ 223 negativeCounter = s; 224 } 225 public void setValue(int val, String textString) { 226 setValue(val); 227 if (val < 0) { 228 negativeText = textString; 229 lastNegative = 0; 230 } 231 else { 232 positiveText = textString; 233 lastPositive = 0; 234 } 235 } 236 public void paint (Graphics g) { 237 if (repaintThread == null) 238 start(); 239 plot(); 240 g.drawImage (im, 0, 0, null); 241 } 242 public Dimension getPreferredSize() { 243 return new Dimension(width, height); 244 } 245 private void scroll() { 246 System.arraycopy(yPoints, 1, yPoints, 0, width - 1); 247 if (continueScroll > 0) 248 continueScroll--; 249 } 250 public void plot() { 251 if (im == null) { 252 im = createImage(width, height); 253 img = im.getGraphics (); 254 img.setColor (Color.black); 255 img.fillRoundRect (0, 0, width, height, 10, 10); 256 img.clipRect (0, 0, width, height); 257 plotGrid(); 258 259 /* save a copy of the image */ 260 imb = createImage(width, height); 261 Graphics imbCopy = imb.getGraphics(); 262 imbCopy.drawImage (im, 0, 0, this); 263 } 264 img.drawImage (imb, 0, 0, this); 265 if (continueScroll > 0) 266 scroll(); 267 plotText(positiveText, lastPositive++, 3, mass-3); 268 plotText(negativeText, lastNegative++, 3, height-3); 269 plotCounters(positiveCounter, negativeCounter); 270 img.setColor (connected ? Color.green : Color.red); 271 img.drawPolyline(xPoints, yPoints, width); 272 } 273 private void plotGrid() { 274 img.setColor(Color.blue); 275 for (int i=0; i<width; i++) 276 if (i % 20 == 0) 277 img.drawLine(i,0,i,height); 278 for (int i=-1000; i<1000; i+= 200) { 279 int y = mass + i*height/2000; 280 img.drawLine(0,y,width,y); 281 } 282 } 283 private void plotText(String t, int l, int x, int y) { 284 if (t != null && l < 20) { 285 img.setColor(Color.lightGray); 286 img.setFont(fontBig); 287 img.drawString (t, x, y); 288 } 289 } 290 private void plotCounters(String p, String n) { 291 img.setColor(Color.lightGray); 292 img.setFont(fontSmall); 293 img.drawString (p, width-55, 13); 294 img.drawString (n, width-55, height-3); 295 } 296 public void run () { 297 while (isShowing()) { 298 if (continueScroll > 0) 299 repaint(); 300 try { 301 Thread.sleep(refreshPanel); 302 } catch (InterruptedException e) { 303 // OK to ignore 304 } 305 } 306 repaintThread = null; 307 } 308 public void update (Graphics g) { 309 paint (g); 310 } 311}