001package jmri.jmrix.can.cbus.swing; 002 003import java.awt.datatransfer.DataFlavor; 004import java.awt.datatransfer.Transferable; 005import java.awt.datatransfer.UnsupportedFlavorException; 006import java.awt.event.ActionEvent; 007import java.io.IOException; 008import javax.swing.*; 009 010import jmri.NamedBean; 011import jmri.jmrix.can.cbus.CbusAddress; 012import jmri.jmrix.can.swing.CanPanel; 013import jmri.jmrix.can.cbus.CbusMessage; 014import jmri.jmrix.can.cbus.CbusNameService; 015import jmri.util.swing.JmriJOptionPane; 016 017/** 018 * Panel to Create Turnouts, Sensor and Lights from CBUS event via drop action. 019 * 020 * @author Steve Young Copyright (C) 2020 021 */ 022public class CbusCreateBeanPane extends JPanel { 023 024 private final CanPanel _mainPane; 025 private JLabel beanLabel; 026 private JPanel editPanel; 027 private JTextField beanUsername; 028 private final CbusNameService nameservice; 029 private NamedBean bean; 030 private JButton editUserNameButton; 031 protected CbTransferHandler[] transferArray; 032 033 public CbusCreateBeanPane(CanPanel mainPane){ 034 super(); 035 _mainPane = mainPane; 036 nameservice = new CbusNameService(mainPane.getMemo()); 037 init(); 038 } 039 040 private void init() { 041 042 transferArray = new CbTransferHandler[3]; 043 044 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 045 setBorder(BorderFactory.createTitledBorder( 046 BorderFactory.createEtchedBorder(), Bundle.getMessage("CreateNew"))); // NOI18N 047 048 add(getNewDragPanel()); 049 add(getEditPane()); 050 } 051 052 private JPanel getNewDragPanel(){ 053 054 JPanel dragContainer = new JPanel(); 055 dragContainer.setToolTipText(Bundle.getMessage("DragHereForNew")); // NOI18N 056 dragContainer.setLayout(new BoxLayout(dragContainer, BoxLayout.X_AXIS)); 057 058 for (int i =0; i<3; i++){ 059 StringBuilder sb = new StringBuilder(); 060 sb.append("<html><h2>") 061 .append(getManagerByIndex(i).getBeanTypeHandled() ) 062 .append("</h2></html>"); // NOI18N 063 JLabel newBealLabel = new JLabel(sb.toString()); 064 newBealLabel.setBorder(BorderFactory.createEtchedBorder()); 065 newBealLabel.setHorizontalAlignment(SwingConstants.CENTER); 066 transferArray[i] = new CbTransferHandler(); 067 newBealLabel.setTransferHandler(transferArray[i]); 068 dragContainer.add(newBealLabel); 069 } 070 return dragContainer; 071 } 072 073 private JPanel getEditPane(){ 074 075 editPanel = new JPanel(); 076 editPanel.setLayout(new BoxLayout(editPanel, BoxLayout.X_AXIS)); 077 editPanel.setBorder(BorderFactory.createTitledBorder( 078 BorderFactory.createEtchedBorder(), Bundle.getMessage("TslDetails"))); // NOI18N 079 080 beanUsername = new JTextField(20); 081 beanUsername.setDropTarget(null); 082 beanUsername.setMinimumSize(new java.awt.Dimension(60,16)); 083 084 beanLabel = new JLabel(); 085 086 editUserNameButton = new JButton(Bundle.getMessage("EditUserName")); // NOI18N 087 editUserNameButton.setToolTipText(Bundle.getMessage("EditUNameTip")); // NOI18N 088 editUserNameButton.addActionListener((ActionEvent e) -> { 089 String newUname = beanUsername.getText(); 090 bean.setUserName(newUname); 091 showSaveReminder(); 092 }); 093 094 setEditPaneActive(false); 095 096 editPanel.add(beanLabel); 097 editPanel.add(beanUsername); 098 editPanel.add(editUserNameButton); 099 return editPanel; 100 } 101 102 private void setEditPaneActive( boolean enabled){ 103 editPanel.setEnabled(enabled); 104 beanUsername.setEnabled(enabled); 105 editUserNameButton.setEnabled(enabled); 106 } 107 108 /** 109 * Handles drop actions containing CBUS event. 110 */ 111 protected class CbTransferHandler extends javax.swing.TransferHandler { 112 /** 113 * {@inheritDoc} 114 */ 115 @Override 116 public boolean canImport(JComponent c, DataFlavor[] transferFlavors) { 117 for (DataFlavor flavor : transferFlavors) { 118 if (DataFlavor.stringFlavor.equals(flavor)) { 119 return true; 120 } 121 } 122 return false; 123 } 124 125 /** 126 * {@inheritDoc} 127 */ 128 @Override 129 public boolean importData(JComponent c, Transferable t) { 130 if (canImport(c, t.getTransferDataFlavors())) { 131 132 String validatedAddr; 133 jmri.ProvidingManager<?> mgrClass; 134 135 // do some validation on the input string 136 // processed in the same way as a sensor, turnout or light so less chance of breaking in future 137 // and can also accept the Hex "X9001020304;X9101020304" format 138 try { 139 validatedAddr = CbusAddress.validateSysName( 140 (String) t.getTransferData(DataFlavor.stringFlavor) ); 141 mgrClass = classMgrInString(((JLabel)c).getText()); 142 } catch (UnsupportedFlavorException | IOException | IllegalArgumentException | ClassCastException e) { 143 return false; 144 } 145 146 int nn = CbusMessage.getNodeNumber(new CbusAddress(validatedAddr).makeMessage(0)); 147 int en = CbusMessage.getEvent(new CbusAddress(validatedAddr).makeMessage(0)); 148 149 boolean dirty = false; 150 151 bean = mgrClass.getBySystemName(validatedAddr); 152 if ( bean == null) { 153 dirty = true; 154 bean = mgrClass.provide(validatedAddr); 155 bean.setUserName(nameservice.getEventName(nn, en)); 156 } 157 setEditPaneActive(true); 158 resetBeanText(bean, dirty, nn, en ); 159 return true; 160 } 161 return false; 162 } 163 } 164 165 private jmri.ProvidingManager<?> classMgrInString(String dropLocation){ 166 for (int i =0; i<3; i++){ 167 if (dropLocation.contains( 168 getManagerByIndex(i).getBeanTypeHandled())){ 169 return getManagerByIndex(i); 170 } 171 } 172 throw new IllegalArgumentException("Unable to get Bean Type"); 173 } 174 175 private jmri.ProvidingManager<?> getManagerByIndex(int index){ 176 switch (index) { 177 case 0: 178 return _mainPane.getMemo().get(jmri.TurnoutManager.class); 179 case 1: 180 return _mainPane.getMemo().get(jmri.SensorManager.class); 181 case 2: 182 return _mainPane.getMemo().get(jmri.LightManager.class); 183 default: 184 throw new IllegalArgumentException("Unable to get Manager from Index" + index); 185 } 186 } 187 188 private void resetBeanText(NamedBean bean, boolean tableChanged, int nn, int en ){ 189 190 beanLabel.setText(bean.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME)); 191 editPanel.setBorder(BorderFactory.createTitledBorder( 192 BorderFactory.createEtchedBorder(), nameservice.getEventNodeString(nn,en))); 193 beanUsername.setText(bean.getUserName()); 194 195 if (tableChanged) { 196 showSaveReminder(); 197 } 198 } 199 200 private boolean showReminder = true; 201 private final boolean checkEnabled = jmri.InstanceManager.getDefault(jmri.configurexml.ShutdownPreferences.class).isStoreCheckEnabled(); 202 203 /** 204 * Show reminder to save Bean Table. 205 */ 206 private void showSaveReminder() { 207 if (showReminder && !checkEnabled) { 208 JCheckBox checkbox = new JCheckBox(Bundle.getMessage("HideFurtherDialog")); 209 Object[] params = {Bundle.getMessage("SavePanelReminder"), checkbox}; 210 JmriJOptionPane.showMessageDialog (_mainPane, params, 211 Bundle.getMessage("ReminderTitle"), JmriJOptionPane.INFORMATION_MESSAGE); 212 showReminder=!checkbox.isSelected(); 213 } 214 } 215 216 // private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CbusCreateBeanPane.class); 217}