001package apps; 002 003import java.awt.event.ActionEvent; 004import java.beans.PropertyChangeEvent; 005import java.util.List; 006import java.util.ResourceBundle; 007import javax.swing.BoxLayout; 008import javax.swing.ButtonGroup; 009import javax.swing.JComponent; 010import javax.swing.JLabel; 011import javax.swing.JPanel; 012import javax.swing.JRadioButton; 013import jmri.InstanceManager; 014import jmri.SystemConnectionMemo; 015import jmri.managers.ManagerDefaultSelector; 016import jmri.profile.Profile; 017import jmri.profile.ProfileManager; 018import jmri.swing.PreferencesPanel; 019import jmri.util.javaworld.GridLayout2; 020import jmri.util.swing.JmriPanel; 021import org.openide.util.lookup.ServiceProvider; 022 023/** 024 * Provide GUI to configure InstanceManager defaults. 025 * 026 * @author Bob Jacobsen Copyright (C) 2010 027 * @since 2.9.5 028 */ 029@ServiceProvider(service = PreferencesPanel.class) 030public final class ManagerDefaultsConfigPane extends JmriPanel implements PreferencesPanel { 031 032 private static final ResourceBundle rb = ResourceBundle.getBundle("apps.AppsConfigBundle"); 033 private boolean dirty = false; 034 035 public ManagerDefaultsConfigPane() { 036 037 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 038 039 matrix = new JPanel(); 040 add(matrix); 041 InstanceManager.getDefault(ManagerDefaultSelector.class).addPropertyChangeListener((PropertyChangeEvent e) -> { 042 if (e.getPropertyName().equals("Updated")) { 043 update(); 044 } 045 }); 046 update(); 047 } 048 049 JPanel matrix; 050 051 /** 052 * Invoke when first displayed to load and present options. 053 */ 054 public void update() { 055 log.debug(" update start"); 056 matrix.removeAll(); 057 058 // this doesn't find non-migrated systems, how do we handle that eventually? 059 List<SystemConnectionMemo> connList = InstanceManager.getList(SystemConnectionMemo.class); 060 if (!connList.isEmpty()) { 061 log.debug(" update of {} connections", connList.size()); 062 reloadConnections(connList); 063 } else { 064 log.debug(" update with no new-form system connections configured"); 065 matrix.add(new JLabel("No new-form system connections configured")); 066 } 067 log.debug(" update end"); 068 } 069 070 void reloadConnections(List<SystemConnectionMemo> connList) { 071 log.debug(" reloadConnections start"); 072 ManagerDefaultSelector manager = InstanceManager.getDefault(ManagerDefaultSelector.class); 073 matrix.setLayout(new GridLayout2(connList.size() + 1, manager.knownManagers.length + 1)); 074 matrix.add(new JLabel("")); 075 076 for (ManagerDefaultSelector.Item item : manager.knownManagers) { 077 log.trace(" Add typeName {}", item.typeName); 078 matrix.add(new JLabel(item.typeName)); 079 } 080 groups = new ButtonGroup[manager.knownManagers.length]; 081 for (int i = 0; i < manager.knownManagers.length; i++) { 082 groups[i] = new ButtonGroup(); 083 } 084 boolean[] selected = new boolean[manager.knownManagers.length]; 085 for (int x = 0; x < connList.size(); x++) { // up to down 086 SystemConnectionMemo memo = connList.get(x); 087 String connectionName = memo.getUserName(); 088 log.trace(" Connection name {}", connectionName); 089 matrix.add(new JLabel(connectionName)); 090 int i = 0; 091 for (ManagerDefaultSelector.Item item : manager.knownManagers) { // left to right 092 log.trace(" item {}", item.typeName); 093 if (memo.provides(item.managerClass)) { 094 JRadioButton r = new SelectionButton(connectionName, item.typeName, item.managerClass, this); 095 matrix.add(r); 096 groups[i].add(r); 097 if (!selected[i] && manager.getDefault(item.managerClass) == null) { 098 log.trace(" setting selected based on default"); 099 r.setSelected(true); 100 selected[i] = true; 101 } 102 } else { 103 // leave a blank 104 JRadioButton r = new JRadioButton(); 105 r.setToolTipText(Bundle.getMessage("TooltipDefaultnotValid", connectionName, dropTags(item.typeName))); 106 r.setEnabled(false); 107 matrix.add(r); 108 } 109 i++; //we need to increment 'i' as we are going onto the next group even if we added a blank button 110 } 111 } 112 revalidate(); 113 log.debug(" reloadConnections end"); 114 } 115 116 ButtonGroup[] groups; 117 118 @Override 119 public String getPreferencesItem() { 120 return "DEFAULTS"; // NOI18N 121 } 122 123 @Override 124 public String getPreferencesItemText() { 125 return rb.getString("MenuDefaults"); // NOI18N 126 } 127 128 @Override 129 public String getTabbedPreferencesTitle() { 130 return rb.getString("TabbedLayoutDefaults"); // NOI18N 131 } 132 133 @Override 134 public String getLabelKey() { 135 return rb.getString("LabelTabbedLayoutDefaults"); // NOI18N 136 } 137 138 @Override 139 public JComponent getPreferencesComponent() { 140 return this; 141 } 142 143 @Override 144 public boolean isPersistant() { 145 return true; 146 } 147 148 @Override 149 public String getPreferencesTooltip() { 150 return null; 151 } 152 153 @Override 154 public void savePreferences() { 155 Profile profile = ProfileManager.getDefault().getActiveProfile(); 156 if (profile != null) { 157 InstanceManager.getDefault(ManagerDefaultSelector.class).savePreferences(profile); 158 } 159 } 160 161 @Override 162 public boolean isDirty() { 163 return this.dirty; 164 } 165 166 @Override 167 public boolean isRestartRequired() { 168 return this.isDirty(); 169 } 170 171 @Override 172 public boolean isPreferencesValid() { 173 return InstanceManager.getDefault(ManagerDefaultSelector.class).isPreferencesValid(ProfileManager.getDefault().getActiveProfile()); 174 } 175 176 private static String dropTags(String s) { 177 //while (s.contains("<")) { 178 return s.replaceAll("</?[a-zA-Z]*>"," "); 179 //} 180 } 181 182 /** 183 * Captive class to track changes. 184 */ 185 static final class SelectionButton extends JRadioButton { 186 187 SelectionButton(String connectionName, String managerName, Class<?> managerClass, ManagerDefaultsConfigPane pane) { 188 super(); 189 this.managerClass = managerClass; 190 this.connectionName = connectionName; 191 // we want to remove tags from the manager name 192 this.managerName = dropTags(managerName); 193 194 // for screen readers 195 setToolTipText(makeToolTipText()); 196 197 log.trace(" SelectionButton ctor for {} as {}", connectionName, managerName); 198 if (connectionName.equals(InstanceManager.getDefault(ManagerDefaultSelector.class).getDefault(managerClass))) { 199 this.setSelected(true); 200 } 201 202 addActionListener((ActionEvent e) -> { 203 if (isSelected()) { 204 InstanceManager.getDefault(ManagerDefaultSelector.class).setDefault(SelectionButton.this.managerClass, SelectionButton.this.connectionName); 205 pane.dirty = true; 206 setToolTipText(Bundle.getMessage("TooltipDefaultSelectedRestart", this.connectionName, this.managerName)); // update the tooltip when selected 207 } 208 }); 209 210 } 211 String connectionName; 212 String managerName; 213 Class<?> managerClass; 214 215 private String makeToolTipText() { 216 return (isSelected()? Bundle.getMessage("TooltipDefaultSelected", connectionName, managerName): 217 Bundle.getMessage("TooltipDefaultNotSelected", connectionName, managerName)); 218 } 219 220 @Override 221 public void setSelected(boolean t) { 222 super.setSelected(t); 223 log.debug("SelectionButton setSelected called with {}", t); 224 setToolTipText(makeToolTipText()); 225 if (t) { 226 InstanceManager.getDefault(ManagerDefaultSelector.class).setDefault(this.managerClass, this.connectionName); 227 } 228 } 229 } 230 231 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ManagerDefaultsConfigPane.class); 232 233}