001package jmri.jmrit.logixng.expressions.swing; 002 003import java.lang.reflect.InvocationTargetException; 004import java.util.List; 005 006import javax.annotation.CheckForNull; 007import javax.annotation.Nonnull; 008import javax.swing.*; 009 010import jmri.InstanceManager; 011import jmri.jmrit.logixng.Base; 012import jmri.jmrit.logixng.DigitalExpressionManager; 013import jmri.jmrit.logixng.MaleSocket; 014import jmri.jmrit.logixng.expressions.ConnectionName; 015import jmri.jmrix.*; 016import static jmri.jmrix.JmrixConfigPane.NONE_SELECTED; 017import jmri.util.swing.JComboBoxUtil; 018 019/** 020 * Configures an ConnectionName object with a Swing JPanel. 021 * 022 * @author Daniel Bergqvist Copyright 2022 023 */ 024public class ConnectionNameSwing extends AbstractDigitalExpressionSwing { 025 026 private final ConnectionConfigManager manager = 027 InstanceManager.getDefault(ConnectionConfigManager.class); 028 029 private JComboBox<String> _manufacturerComboBox; 030 private JComboBox<String> _connectionComboBox; 031 private ConnectionConfig[] _connectionConfigs; 032 033 public ConnectionNameSwing() { 034 } 035 036 public ConnectionNameSwing(JDialog dialog) { 037 super.setJDialog(dialog); 038 } 039 040 @Override 041 protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) { 042 // Create a temporary action if object is null 043 final ConnectionName action = (object != null) 044 ? (ConnectionName) object 045 : new ConnectionName("IQDE1", null); 046 047 String[] manufactureNameList = manager.getConnectionManufacturers(); 048 _connectionConfigs = manager.getConnections(); 049 050 panel = new JPanel(); 051 052 String selectedManufacturer = action.getManufacturer(); 053 if (selectedManufacturer == null 054 || selectedManufacturer.isBlank() 055 || NONE_SELECTED.equals(selectedManufacturer)) { 056 if (_connectionConfigs.length > 0) { 057 selectedManufacturer = _connectionConfigs[0].getManufacturer(); 058 } 059 } 060 061 JPanel manufacturerPanel = new JPanel(); 062 manufacturerPanel.setLayout(new BoxLayout(manufacturerPanel, BoxLayout.Y_AXIS)); 063 064 var mLabel = new JPanel(); 065 mLabel.add(new JLabel(Bundle.getMessage("ExpressionConnection_Manufacturer"))); 066 manufacturerPanel.add(mLabel); 067 068 _manufacturerComboBox = new JComboBox<>(); 069 manufacturerPanel.add(_manufacturerComboBox); 070 071 for (String manuName : manufactureNameList) { 072 _manufacturerComboBox.addItem(manuName); 073 if (manuName.equals(selectedManufacturer)) { 074 _manufacturerComboBox.setSelectedItem(selectedManufacturer); 075 } 076 } 077 if (_manufacturerComboBox.getSelectedIndex() == -1) { 078 _manufacturerComboBox.setSelectedIndex(0); 079 } 080 081 JPanel connectionNamePanel = new JPanel(); 082 connectionNamePanel.setLayout(new BoxLayout(connectionNamePanel, BoxLayout.Y_AXIS)); 083 084 var cLabel = new JPanel(); 085 cLabel.add(new JLabel(Bundle.getMessage("ExpressionConnection_Connection"))); 086 connectionNamePanel.add(cLabel); 087 088 _connectionComboBox = new JComboBox<>(); 089 connectionNamePanel.add(_connectionComboBox); 090 091 _manufacturerComboBox.addActionListener((evt) -> { 092 updateConnectionComboBox(action); 093 }); 094 095 updateConnectionComboBox(action); 096 097 JComboBoxUtil.setupComboBoxMaxRows(_manufacturerComboBox); 098 JComboBoxUtil.setupComboBoxMaxRows(_connectionComboBox); 099 100 101 panel.add(manufacturerPanel); 102 panel.add(connectionNamePanel); 103 } 104 105 private void updateConnectionComboBox(ConnectionName action) { 106 String selectedManufacturer = (String) _manufacturerComboBox.getSelectedItem(); 107 String[] classConnectionNameList = manager.getConnectionTypes(selectedManufacturer); 108 109 String selectedConnectionName = null; 110 111 if (selectedManufacturer.equals(action.getManufacturer())) { 112 selectedConnectionName = action.getConnectionName(); 113 } 114 if (selectedConnectionName == null 115 || selectedConnectionName.isBlank() 116 || NONE_SELECTED.equals(selectedConnectionName)) { 117 for (int i=0; i < _connectionConfigs.length; i++) { 118 if (_connectionConfigs[i].getManufacturer().equals(selectedManufacturer)) { 119 selectedConnectionName = _connectionConfigs[i].name(); 120 } 121 } 122 } 123 124 _connectionComboBox.removeAllItems(); 125 _connectionComboBox.addItem(NONE_SELECTED); 126 127 for (String className : classConnectionNameList) { 128 try { 129 Class<?> cl = Class.forName(className); 130 ConnectionConfig config = (ConnectionConfig) cl.getDeclaredConstructor().newInstance(); 131 if( !(config instanceof StreamConnectionConfig)) { 132 // only include if the connection is not a 133 // StreamConnection. Those connections require 134 // additional context. 135 if (config != null) { 136 _connectionComboBox.addItem(config.name()); 137 if (config.name().equals(selectedConnectionName)) { 138 _connectionComboBox.setSelectedItem(selectedConnectionName); 139 } 140 } 141 } 142 } catch (NullPointerException e) { 143 log.error("Attempt to load {} failed.", className, e); 144 } catch (InvocationTargetException | ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException e) { 145 log.error("Attempt to load {} failed", className, e); 146 } 147 } 148 149 // Resize dialog if needed 150 JDialog dialog = (JDialog) SwingUtilities.getAncestorOfClass(JDialog.class, _manufacturerComboBox); 151 if (dialog != null) dialog.pack(); 152 } 153 154 /** {@inheritDoc} */ 155 @Override 156 public boolean validate(@Nonnull List<String> errorMessages) { 157 return true; 158 } 159 160 /** {@inheritDoc} */ 161 @Override 162 public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) { 163 ConnectionName action = new ConnectionName(systemName, userName); 164 updateObject(action); 165 return InstanceManager.getDefault(DigitalExpressionManager.class).registerExpression(action); 166 } 167 168 /** {@inheritDoc} */ 169 @Override 170 public void updateObject(@Nonnull Base object) { 171 if (! (object instanceof ConnectionName)) { 172 throw new IllegalArgumentException("object must be an ConnectionName but is a: "+object.getClass().getName()); 173 } 174 ConnectionName action = (ConnectionName) object; 175 176 if (_manufacturerComboBox.getSelectedIndex() != -1) { 177 action.setManufacturer(_manufacturerComboBox.getItemAt(_manufacturerComboBox.getSelectedIndex())); 178 } 179 if (_connectionComboBox.getSelectedIndex() != -1) { 180 action.setConnectionName(_connectionComboBox.getItemAt(_connectionComboBox.getSelectedIndex())); 181 } 182 } 183 184 /** {@inheritDoc} */ 185 @Override 186 public String toString() { 187 return Bundle.getMessage("ConnectionName_Short"); 188 } 189 190 @Override 191 public void dispose() { 192 } 193 194 195 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ConnectionNameSwing.class); 196 197}