001package jmri.jmrix.roco.z21.swing.mon; 002 003import jmri.jmrix.Message; 004import jmri.jmrix.roco.z21.*; 005import org.reflections.Reflections; 006import org.slf4j.Logger; 007import org.slf4j.LoggerFactory; 008 009import java.lang.reflect.Constructor; 010import java.lang.reflect.InvocationTargetException; 011import java.util.ArrayList; 012import java.util.List; 013import java.util.Set; 014 015/** 016 * Panel displaying (and logging) Z21 messages derived from Z21MonFrame. 017 * 018 * @author Bob Jacobsen Copyright (C) 2002 019 * @author Paul Bender Copyright (C) 2004-2024 020 * @author Giorgio Terdina Copyright (C) 2007 021 */ 022public class Z21MonPane extends jmri.jmrix.AbstractMonPane implements Z21Listener { 023 024 protected Z21SystemConnectionMemo memo = null; 025 026 private List<Z21MessageFormatter> formatterList; 027 028 @Override 029 public String getTitle() { 030 return (Bundle.getMessage("Z21TrafficTitle")); 031 } 032 033 @Override 034 public void initContext(Object context) { 035 if (context instanceof Z21SystemConnectionMemo) { 036 memo = (Z21SystemConnectionMemo) context; 037 // connect to the TrafficController 038 memo.getTrafficController().addz21Listener(this); 039 try { 040 formatterList = new ArrayList<>(); 041 042 Reflections reflections = new Reflections("jmri.jmrix.roco.z21"); 043 Set<Class<? extends Z21MessageFormatter>> f = reflections.getSubTypesOf(Z21MessageFormatter.class); 044 for(Class<?> c : f){ 045 log.debug("Found formatter: {}", f.getClass().getName()); 046 Constructor<?> ctor = c.getConstructor(); 047 formatterList.add((Z21MessageFormatter) ctor.newInstance()); 048 } 049 } catch (NoSuchMethodException | SecurityException | InstantiationException | 050 IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 051 log.error("Error instantiating formatter", e); 052 } 053 } 054 } 055 056 /** 057 * Initialize the data source. 058 */ 059 @Override 060 protected void init() { 061 } 062 063 @Override 064 public void dispose() { 065 // disconnect from the TrafficController 066 memo.getTrafficController().removez21Listener(this); 067 // and unwind swing 068 super.dispose(); 069 } 070 071 @Override 072 public void logMessage(String messagePrefix, String rawPrefix, Message message){ 073 // display the raw data if requested 074 StringBuilder raw = new StringBuilder(rawPrefix); 075 if (rawCheckBox.isSelected()) { 076 raw.append(message.toString()); 077 } 078 079 // display the decoded data 080 String text = formatterList.stream() 081 .filter(f -> f.handlesMessage(message)) 082 .findFirst().map(f -> f.formatMessage(message)) 083 .orElse(message.toString()); 084 nextLine(messagePrefix + " " + text + "\n", raw.toString()); 085 } 086 087 @Override 088 public synchronized void reply(Z21Reply l) { // receive an XpressNet message and log it 089 logMessage(l); 090 } 091 092 /** 093 * Listen for the messages to the LI100/LI101 094 */ 095 @Override 096 public synchronized void message(Z21Message l) { 097 logMessage(l); 098 } 099 100 /** 101 * Nested class to create one of these using old-style defaults 102 */ 103 static public class Default extends jmri.util.swing.JmriNamedPaneAction { 104 105 public Default() { 106 super(Bundle.getMessage("Z21TrafficTitle"), 107 Z21MonPane.class.getName()); 108 setContext(jmri.InstanceManager. 109 getDefault(Z21SystemConnectionMemo.class)); 110 } 111 } 112 private static final Logger log = LoggerFactory.getLogger(Z21MonPane.class); 113 114}