# This script displays LocoNet messages. # The frame contains JTextFields, a scroll field, check boxes and a button. # The frame contains Panel arranged such that only the scroll field moves # when the window is resized. # Switch, feedback and sensor messages can be filtered. # # Author: Bill Robinson with help from Bob Jacobsen # # $Revision: 1.0 $ 1/8/07 import java import javax.swing # have the text field enable the button when OK def whenAddressChanged(event) : if (address.text != "") : # address only changed if a value was entered swAddrCheckBox.setEnabled(True) else : swAddrCheckBox.setSelected(False) swAddrCheckBox.setEnabled(False) return # have the 2nd text field enable the button when OK also def whenCommandChanged(event) : if (command.text != "") : snAddrCheckBox.setEnabled(True) else : snAddrCheckBox.setSelected(False) snAddrCheckBox.setEnabled(False) return # define what button does when clicked and attach that routine to the button def whenEnterButtonClicked(event) : # not used return def whenClearButtonClicked(event): print "got to here" scrollArea.setText("") # clear the text area return def whenQuitButtonClicked(event): # not used return # WindowListener is a interface class and therefore all of it's # methods should be implemented even if not used to avoid AttributeErrors class WinListener(java.awt.event.WindowListener): def windowClosing(self,event): # print"window closing" jmri.jmrix.loconet.LnTrafficController.instance().removeLocoNetListener(0xFF,lnListen) fr.dispose() # close the pane (window) def windowActivated(self,event): return def windowDeactivated(self,event): return def windowOpened(self,event): return def windowClosed(self,event): return #create a Llnmon to parse the message parseMsg = jmri.jmrix.loconet.locomon.Llnmon() #class to handle a listener event loconet messages class MsgListener(jmri.jmrix.loconet.LocoNetListener): def message(self, msg): # print "byte 0", java.lang.Integer.toHexString(msg.getElement(0)) # Handle check boxes if swAddrCheckBox.isSelected() or snAddrCheckBox.isSelected() or filterCheckBox.isSelected(): if filterCheckBox.isSelected(): if msg.getOpCode() == 176 or msg.getOpCode() == 177 or msg.getOpCode() == 178: displayMsg(msg) else: if swAddrCheckBox.isSelected(): # msg.turnoutAddr() is an int and address.text is a string if msg.getOpCode() == 176 and msg.turnoutAddr() == java.lang.Integer.decode(address.text): displayMsg(msg) if snAddrCheckBox.isSelected(): if msg.getOpCode() == 178 and msg.sensorAddr()+1 == java.lang.Integer.decode(command.text): displayMsg(msg) else : # if no boxes are check just display the message displayMsg(msg) return # Add the next Loconet messsage to the scroll area test # If the raw box is checked add the HEX message value in front of message def displayMsg(msg): if rawCheckBox.isSelected(): scrollArea.setText(scrollArea.getText()+msg.toString()+" ") scrollArea.setText(scrollArea.getText()+parseMsg.displayMessage(msg)) # displayMessage adds a carriage return return lnListen = MsgListener() jmri.jmrix.loconet.LnTrafficController.instance().addLocoNetListener(0xFF,lnListen) # start to initialise the GUI # create buttons and define action enterButton = javax.swing.JButton("Start the Run") enterButton.setEnabled(False) # button starts as grayed out (disabled) enterButton.actionPerformed = whenEnterButtonClicked clearButton = javax.swing.JButton("Clear") clearButton.actionPerformed = whenClearButtonClicked quitButton = javax.swing.JButton("Quit") quitButton.actionPerformed = whenQuitButtonClicked swAddrCheckBox = javax.swing.JCheckBox("Filter Sw address") swAddrCheckBox.setToolTipText("Display only switch messages with the address") swAddrCheckBox.setEnabled(False) # button starts as grayed out (disabled) snAddrCheckBox = javax.swing.JCheckBox("Filter Sn address") snAddrCheckBox.setToolTipText("Display only sensor messages with the address") snAddrCheckBox.setEnabled(False) # button starts as grayed out (disabled) rawCheckBox = javax.swing.JCheckBox("Show raw data") filterCheckBox = javax.swing.JCheckBox("Filter SW, FB & SN") filterCheckBox.setToolTipText("Display only switch, feedback or sensor messages") address = javax.swing.JTextField(5) # sized to hold 5 characters, initially empty address.actionPerformed = whenAddressChanged # if user hit return or enter address.focusLost = whenAddressChanged # if user tabs away # create the second text field similarly command = javax.swing.JTextField(5) # sized to hold 5 characters command.setToolTipText("Max speed is a number from 1 to 20") command.actionPerformed = whenCommandChanged command.focusLost = whenCommandChanged # create a text area scrollArea = javax.swing.JTextArea(10, 45) # define a text area with it's size # scrollArea.setText("Put any init text here\n") srcollField = javax.swing.JScrollPane(scrollArea) # put text area in scroll field # create a panel to put the scroll area in # a borderlayout causes the scroll area to fill the space as the window is resized midPanel = javax.swing.JPanel() # midPanel.setBorder(javax.swing.BorderFactory.createMatteBorder(1,8,1,8, java.awt.Color.white)) midPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(1,8,1,8)) midPanel.setLayout(java.awt.BorderLayout()) midPanel.add(srcollField) # create a frame to hold the buttons and fields # also create a window listener. This is used mainly to remove the property change listener # when the window is closed by clicking on the window close button w = WinListener() fr = javax.swing.JFrame("LocoNet Monitor") # argument is the frames title fr.contentPane.setLayout(javax.swing.BoxLayout(fr.contentPane, javax.swing.BoxLayout.Y_AXIS)) fr.addWindowListener(w) # put the text field on a line preceded by a label addressPanel = javax.swing.JPanel() addressPanel.setLayout(java.awt.FlowLayout(2)) # 2 is right align for FlowLayout addressPanel.add(javax.swing.JLabel("Sw Address")) addressPanel.add(address) commandPanel = javax.swing.JPanel() commandPanel.setLayout(java.awt.FlowLayout(2)) # 2 is right align for FlowLayout commandPanel.add(javax.swing.JLabel("Sn Address")) commandPanel.add(command) temppanel1 = javax.swing.JPanel() temppanel1.setLayout(javax.swing.BoxLayout(temppanel1, javax.swing.BoxLayout.PAGE_AXIS)) temppanel1.add(addressPanel) temppanel1.add(commandPanel) ckBoxPanel = javax.swing.JPanel() ckBoxPanel.setLayout(javax.swing.BoxLayout(ckBoxPanel, javax.swing.BoxLayout.PAGE_AXIS)) ckBoxPanel.add(swAddrCheckBox) ckBoxPanel.add(filterCheckBox) ckBoxPanel.add(snAddrCheckBox) ckBoxPanel.add(rawCheckBox) butPanel = javax.swing.JPanel() butPanel.setLayout(javax.swing.BoxLayout(butPanel, javax.swing.BoxLayout.PAGE_AXIS)) butPanel.add(clearButton) buttonPanel = javax.swing.JPanel() buttonPanel.add(butPanel) blankPanel = javax.swing.JPanel() blankPanel.setLayout(java.awt.BorderLayout()) entryPanel = javax.swing.JPanel() entryPanel.setLayout(javax.swing.BoxLayout(entryPanel, javax.swing.BoxLayout.LINE_AXIS)) entryPanel.add(temppanel1) entryPanel.add(ckBoxPanel) entryPanel.add(buttonPanel) entryPanel.add(blankPanel) # create the top panel # it is a 1,1 GridLayout used to keep all controls stationary when the window is resized topPanel = javax.swing.JPanel() topPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(1,8,8,8)) topPanel.setLayout(java.awt.GridLayout(1,1)) topPanel.add(entryPanel) # create a ppanel to give some space under the scrolling field bottomPanel = javax.swing.JPanel() # bottomPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(1,8,1,8)) # Put contents in frame and display fr.contentPane.add(topPanel) fr.contentPane.add(midPanel) fr.contentPane.add(bottomPanel) fr.pack() fr.show()