2 * SpiderCluster - SpiderCluster console plugin.
4 * @verison 1.0 - 20010418.
7 * Copyright (C) 2001 Ian Norton.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public Licence as published by
11 * the Free Software Foundation; either version 2 of the Licence, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public Licence for more details.
19 * You should have received a copy of the GNU General Public Licence
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Contacting the author :
25 * i.norton@lancaster.ac.uk
26 * http://www.lancs.ac.uk/~norton/
30 import javax.swing.text.*;
31 import javax.swing.event.*;
34 import java.awt.event.*;
35 import java.util.Hashtable ;
36 import java.util.Enumeration ;
38 // public class Cluster extends Plugin implements Runnable
39 class SpiderCluster extends Plugin implements Runnable
41 // Name and tip used when creating the tabbed pane.
42 public static final String NAME = "SpiderCluster" ;
43 public static final String TIP = "Spider DX Cluster Console" ;
45 // Number of commands to buffer.
46 public static final int CMDBUFFERLINES = 30 ;
48 // Number of lines of scrollback to buffer.
49 public static final int SCROLLBUFFERLINES = 100 ;
51 public static final boolean DEBUG = false ;
53 // Input and output streams for the plugin.
54 private BufferedReader bir ;
55 private PipedOutputStream pos ;
58 private JTextField tf ;
60 private JTextPane jtp ;
62 private SimpleAttributeSet attr ;
63 private LimitedStyledDocument doc ;
65 // Input line scrollback buffer.
66 private CommandBuffer cbuf ;
68 // Callsign of the connecting user.
71 private static final String encoding = "latin1"; // "ISO8859_1";
76 public SpiderCluster()
83 * @param PipedInputStream i - Stream to read data from
84 * @param PipedOutputStream o - Stream to write data to
86 public void init(PipedInputStream i, PipedOutputStream o)
88 // Initialise the plugin IO.
89 bir = new BufferedReader(new InputStreamReader(i)) ;
92 // Initialise the Scrolling output area.
93 doc = new LimitedStyledDocument(SCROLLBUFFERLINES) ;
94 jtp = new JTextPane(doc) ;
95 jtp.setEditable(false) ;
96 attr = new SimpleAttributeSet() ;
97 StyleConstants.setFontFamily(attr, "Monospaced") ;
98 StyleConstants.setFontSize(attr, 10) ;
99 jtp.setBackground(Color.black) ;
101 doc.addDocumentListener(new DocumentListener() {
102 public void insertUpdate(DocumentEvent e) {
103 jtp.setCaretPosition(doc.getLength()) ;
105 public void removeUpdate(DocumentEvent e) { }
106 public void changedUpdate(DocumentEvent e) { }
109 // Initialise the TextField for user input.
110 tf = new JTextField() ;
111 tf.setFont(new Font("Courier", Font.PLAIN, 10)) ;
112 Insets inset = tf.getMargin() ;
113 inset.top = inset.top + 1 ;
114 inset.bottom = inset.bottom + 1 ;
115 tf.setMargin(inset) ;
116 tf.setForeground(Color.white) ;
117 tf.setBackground(Color.black) ;
118 tf.setCaretColor(Color.white) ;
120 // Set the layout manager.
121 this.setLayout(new BorderLayout()) ;
123 // Scrollbars for scrolling text area.
124 JScrollPane scrollpane = new JScrollPane(jtp);
126 // Add the bits to the panel.
127 this.add(scrollpane, BorderLayout.CENTER);
128 this.add(tf, BorderLayout.SOUTH);
130 // Initialise the command buffer.
131 cbuf = new CommandBuffer(CMDBUFFERLINES) ;
133 // Action listener stuff.
134 tf.addKeyListener(new KeyAdapter()
136 public void keyTyped(KeyEvent e)
139 if((e.getID() == KeyEvent.KEY_TYPED) && (e.getKeyChar() == KeyEvent.VK_ENTER))
141 if(DEBUG) System.out.println("Enter Event") ;
142 send(tf.getText() + '\n') ;
143 cbuf.addCommand(tf.getText()) ;
147 public void keyPressed(KeyEvent e)
150 if((e.getID() == KeyEvent.KEY_PRESSED) && (e.getKeyCode() == KeyEvent.VK_UP))
152 if(DEBUG) System.out.println("UP Event") ;
153 tf.setText(cbuf.getPreviousCommand()) ;
154 tf.setCaretPosition(tf.getText().length()) ;
157 if((e.getID() == KeyEvent.KEY_PRESSED) && (e.getKeyCode() == KeyEvent.VK_DOWN))
159 if(DEBUG) System.out.println("DOWN Event") ;
160 tf.setText(cbuf.getNextCommand()) ;
161 tf.setCaretPosition(tf.getText().length()) ;
164 if((e.getID() == KeyEvent.KEY_PRESSED) && (e.getKeyCode() == KeyEvent.VK_ESCAPE))
166 if(DEBUG) System.out.println("ESCAPE Event") ;
171 // Add component listener to focus text field.
172 this.addComponentListener(new ComponentAdapter() {
173 public void componentShown(ComponentEvent e) {
174 tf.setVisible(true) ;
179 // Init the scrolling thread.
180 t = new Thread(this, "Scrolling thread") ;
183 // Prompt for callsign to connect with.
184 while(call == null || call.indexOf(" ") > -1)
186 call = JOptionPane.showInputDialog("Enter your callsign") ;
189 call = call.toUpperCase() ;
193 * getTabName - Get the name that this component should show on it's tab
194 * @returns String s - Tab name
197 public String getTabName()
202 * getTabTip - Get the tip that this component should show on it's tab
203 * @returns String s - Tab tip
205 public String getTabTip()
211 * getMenu - get the menu to add to the main menu bar.
214 public JMenu getMenu()
219 * send - Helper function to send data out to the PipedOutputMUX
220 * @param String s - data to send.
222 private void send(String s)
224 if(DEBUG) System.out.println("Cluster: send got : " + s) ;
226 // If the input has no | in it, prefix I<CALLSIGN>| and send it.
227 if(s.indexOf("|") == -1)
229 s = "I" + call + "|" + s ;
233 // Write the data to the stream.
234 for(int i=0;i<s.length();i++)
236 pos.write(s.charAt(i)) ;
239 catch(IOException ex)
241 System.out.println("Cluster: IOException on destination stream.") ;
242 System.out.println(ex) ;
247 * Loop continually checking to see if anything has been written to the
248 * file that is being monitored.
252 String output = new String() ;
253 // Loop continually reading from the input stream
259 // Read in a line of data (This screws up prompts with no /n)
260 output = bir.readLine() ;
261 if(output != null) display(output) ;
263 if(DEBUG) System.out.println("After reading a line.") ;
265 catch(IOException ex)
267 System.out.println("SpiderCluster: IOException trying to read.") ;
269 } // End of infinate loop.
272 private void display(String s)
274 // Automatic login - when we see "Conneted to" send the login string.
275 if(s.startsWith("Connected to")) { send("A" + call + "|local\n") ; }
277 // s = s.replace('
\a', ' ') ;
279 // Get rid of Ctrl-G's in UNICODE.
280 while(s.indexOf("%07") > -1)
282 StringBuffer sb = new StringBuffer(s) ;
283 sb.delete(s.indexOf("%07"), s.indexOf("%07") + 3) ;
288 // If the line has a | and starts with D, strip off upto and inc the |.
289 if(s.indexOf("|") != -1 && s.charAt(0) == 'D')
291 s = s.substring(s.indexOf("|") + 1, s.length()) ;
294 // Find out what colour this needs to be.
295 attr = getAttributes(s) ;
297 // Display it in the doc.
298 doc.append(s + "\n", attr) ;
302 * getAttributes(String s) - get attributes (i.e. colour) given a string.
305 private SimpleAttributeSet getAttributes(String s)
307 SimpleAttributeSet sas = attr ;
310 # 0 - $foreground, $background
311 # 1 - RED, $background
312 # 2 - BROWN, $background
313 # 3 - GREEN, $background
314 # 4 - CYAN, $background
315 # 5 - BLUE, $background
316 # 6 - MAGENTA, $background
319 [ '^DX de [\-A-Z0-9]+:\s+([57][01]\d\d\d\.|\d\d\d\d\d\d+.)', COLOR_PAIR(1) ],
321 [ '^G0VGS de GB7MBC', COLOR_PAIR(6) ],
323 [ '^G0VGS de', A_BOLD|COLOR_PAIR(2) ],
325 [ '^DX', COLOR_PAIR(5) ],
327 [ '^To', COLOR_PAIR(3) ],
329 [ '^WWV', COLOR_PAIR(4) ],
331 [ '^[-A-Z0-9]+ de [-A-Z0-9]+ \d\d-\w\w\w-\d\d\d\d \d\d\d\dZ', COLOR_PAIR(0) ],
332 DUNNO! - PROBABLY A TALK
333 [ '^[-A-Z0-9]+ de [-A-Z0-9]+ ', COLOR_PAIR(6) ],
335 [ '^WX', COLOR_PAIR(3) ],
337 [ '^New mail', A_BOLD|COLOR_PAIR(4) ],
339 [ '^User', COLOR_PAIR(2) ],
341 [ '^Node', COLOR_PAIR(2) ],
344 Hashtable h = new Hashtable() ;
345 h.put("DX de", Color.red) ; // HF DX
346 h.put(call + " de ", Color.magenta) ;
347 // h.put("DX", Color.blue) ; // VHF/UHF DX
348 h.put("To", Color.green) ;
349 h.put("WWV", Color.cyan) ;
350 h.put("WCY", Color.cyan) ;
351 // h.put("", Color.) ;
352 // h.put("", Color.) ;
353 h.put("WX", Color.green) ;
354 h.put("New mail", Color.cyan) ;
355 //h.put("User", Color.brown) ;
356 //h.put("Node", Color.brown) ;
357 h.put("User", Color.yellow) ;
358 h.put("Node", Color.orange) ;
360 Enumeration e = h.keys() ;
362 while(e.hasMoreElements())
364 String prefix = (String)e.nextElement() ;
365 if(s.startsWith(prefix))
367 StyleConstants.setForeground(sas, (Color)h.get(prefix)) ;
372 StyleConstants.setForeground(sas, Color.white) ;