001package jmri.jmrit.logixng.swing; 002 003import java.util.*; 004 005import javax.annotation.CheckForNull; 006import javax.annotation.Nonnull; 007import javax.swing.*; 008 009import jmri.NamedBean; 010import jmri.NamedBean.BadSystemNameException; 011import jmri.NamedBean.BadUserNameException; 012import jmri.jmrit.logixng.*; 013 014/** 015 * The parent interface for configuring classes with Swing. 016 * 017 * @author Daniel Bergqvist Copyright 2018 018 */ 019public interface SwingConfiguratorInterface extends Comparable<SwingConfiguratorInterface> { 020 021 /** 022 * Set the dialog of this SWI. 023 * 024 * @param dialog the dialog 025 */ 026 public void setJDialog(JDialog dialog); 027 028 /** 029 * Set the dialog of this SWI. 030 * 031 * @return the dialog 032 */ 033 public JDialog getJDialog(); 034 035 /** 036 * Get the menu text for execute/evaluate. 037 * @return the menu text 038 */ 039 public String getExecuteEvaluateMenuText(); 040 041 /** 042 * Execute or evaluate an item that this object configures. 043 * @param object the object to execute or evaluate 044 */ 045 public void executeEvaluate(@Nonnull Base object); 046 047 /** 048 * Get the manager that handles the beans for the new object. 049 * This is used for validation of the system name for the bean that this 050 * class creates. 051 * 052 * @return the manager 053 */ 054 public BaseManager<? extends NamedBean> getManager(); 055 056 /** 057 * Get a configuration panel when a new object is to be created and we don't 058 * have it yet. 059 * This method initializes the panel with an empty configuration. 060 * 061 * @param buttonPanel panel with the buttons 062 * @return a panel that configures this object 063 * @throws IllegalArgumentException if this class does not support the class 064 * with the name given in parameter 'className' 065 */ 066 public JPanel getConfigPanel(@Nonnull JPanel buttonPanel) throws IllegalArgumentException; 067 068 /** 069 * Get a configuration panel for an object. 070 * This method initializes the panel with the configuration of the object. 071 * 072 * @param object the object for which to return a configuration panel 073 * @param buttonPanel panel with the buttons 074 * @return a panel that configures this object 075 * @throws IllegalArgumentException when needed 076 */ 077 public JPanel getConfigPanel(@Nonnull Base object, @Nonnull JPanel buttonPanel) throws IllegalArgumentException; 078 079 /** 080 * Validate the form. 081 * <P> 082 * The parameter errorMessage is used to give the error message in case of 083 * an error. If there are errors, the error messages is added to the list 084 * errorMessage. 085 * 086 * @param errorMessages the error messages in case of an error 087 * @return true if data in the form is valid, false otherwise 088 */ 089 public boolean validate(@Nonnull List<String> errorMessages); 090 091 /** 092 * Get an example of a system name 093 * @return the system name 094 */ 095 public String getExampleSystemName(); 096 097 /** 098 * Create a new system name. 099 * @return a new system name 100 */ 101 public String getAutoSystemName(); 102 103 /** 104 * Create a new object with the data entered.This method must also register the object in its manager. 105 * 106 * @param systemName system name 107 * @param userName user name 108 * @return a male socket for the new object 109 * @throws BadUserNameException when needed 110 * @throws BadSystemNameException when needed 111 */ 112 @Nonnull 113 public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) 114 throws BadUserNameException, BadSystemNameException; 115 116 /** 117 * Updates the object with the data in the form. 118 * 119 * @param object the object to update 120 */ 121 public void updateObject(@Nonnull Base object); 122 123 /** 124 * Returns the name of the class that this class configures. 125 * 126 * @return the name of the class this class configures. 127 */ 128 @Override 129 public String toString(); 130 131 /** 132 * Set default values for this dialog. 133 * This method is used by tests to be able to run validation without 134 * knowing which data that needs to be entered for the validation to pass. 135 */ 136 public default void setDefaultValues() { 137 // Do nothing 138 } 139 140 /** 141 * Is the SWI ready to be closed? 142 * @return true if the SWI is ready to be closed, false otherwise. 143 */ 144 public default boolean canClose() { 145 return true; 146 } 147 148 /** 149 * Dispose the panel and remove all the listeners that this class may have 150 * registered. 151 */ 152 public void dispose(); 153 154 155 /** 156 * Parses the message and creates a list of components there the given 157 * components are separated by JLabel components from the message. 158 * @param message the message to be parsed 159 * @param components the components 160 * @return the components separated with JLabel components 161 */ 162 public static List<JComponent> parseMessage(String message, JComponent[] components) { 163 List<JComponent> componentsToReturn = new ArrayList<>(); 164 StringBuilder sb = new StringBuilder(); 165 boolean parseNumber = false; 166 167 for (int index=0; index < message.length(); index++) { 168 int character = message.codePointAt(index); 169 170 if (parseNumber) { 171 if (character == '}') { 172 int number = Integer.parseInt(sb.toString()); 173 componentsToReturn.add(components[number]); 174 sb = new StringBuilder(); 175 parseNumber = false; 176 } else if ((character >= '0') && (character <= '9')) { 177 sb.appendCodePoint(character); 178 } else { 179 throw new IllegalArgumentException( 180 "left curly bracket must be followed by a digit but is followed by " 181 + Arrays.toString(Character.toChars(character))); 182 } 183 } else { 184 if (character == '{') { 185 parseNumber = true; 186 componentsToReturn.add(new JLabel(sb.toString())); 187 sb = new StringBuilder(); 188 } else { 189 sb.appendCodePoint(character); 190 } 191 } 192 } 193 194 if (sb.length() > 0) componentsToReturn.add(new JLabel(sb.toString())); 195 196 return componentsToReturn; 197 } 198 199 /** {@inheritDoc} */ 200 @Override 201 public default int compareTo(SwingConfiguratorInterface swi) { 202 return toString().compareTo(swi.toString()); 203 } 204 205}