001package jmri.jmrit.display.palette; 002 003import java.awt.datatransfer.DataFlavor; 004import java.awt.datatransfer.UnsupportedFlavorException; 005import java.io.IOException; 006 007import javax.swing.Box; 008import javax.swing.BoxLayout; 009import javax.swing.JComponent; 010import javax.swing.JLabel; 011import javax.swing.JPanel; 012import javax.swing.JSpinner; 013import javax.swing.JTextField; 014import javax.swing.SpinnerNumberModel; 015import javax.swing.event.ChangeEvent; 016import javax.swing.event.ChangeListener; 017import javax.swing.event.ListSelectionEvent; 018 019import jmri.Memory; 020import jmri.jmrit.catalog.NamedIcon; 021import jmri.jmrit.display.DisplayFrame; 022import jmri.jmrit.display.Editor; 023import jmri.jmrit.display.MemoryComboIcon; 024import jmri.jmrit.display.MemoryIcon; 025import jmri.jmrit.display.MemoryInputIcon; 026import jmri.jmrit.display.MemorySpinnerIcon; 027import jmri.jmrit.display.PreviewPanel; 028import jmri.jmrit.picker.PickListModel; 029import jmri.util.swing.JmriJOptionPane; 030 031public class MemoryItemPanel extends TableItemPanel<Memory> implements ChangeListener { 032 033 enum Type { 034 READONLY, READWRITE, SPINNER, COMBO 035 } 036 JSpinner _spinner; 037 String[] list = {"Item1", "Item2", "Item3"}; 038 039 public MemoryItemPanel(DisplayFrame parentFrame, String type, String family, PickListModel<jmri.Memory> model) { 040 super(parentFrame, type, family, model); 041 } 042 043 @Override 044 public void init() { 045 if (!_initialized) { 046 add(initTablePanel(_model)); 047 initIconFamiliesPanel(); 048 add(_iconFamilyPanel); 049 _previewPanel = new PreviewPanel(_frame, _dragIconPanel, _iconPanel, true); 050 add(_previewPanel); 051 _initialized = true; 052 } 053 } 054 055 @Override 056 protected JPanel instructions() { 057 JPanel blurb = new JPanel(); 058 blurb.setLayout(new BoxLayout(blurb, BoxLayout.Y_AXIS)); 059 blurb.add(Box.createVerticalStrut(ItemPalette.STRUT_SIZE)); 060 blurb.add(new JLabel(Bundle.getMessage("AddMemoryToPanel"))); 061 blurb.add(new JLabel(Bundle.getMessage("MemoryDragStart"))); 062 blurb.add(new JLabel(Bundle.getMessage("MemoryDragFix"))); 063 blurb.add(Box.createVerticalStrut(ItemPalette.STRUT_SIZE)); 064 blurb.add(new JLabel(Bundle.getMessage("DecorateMemory"))); 065 blurb.add(Box.createVerticalStrut(ItemPalette.STRUT_SIZE)); 066 JPanel panel = new JPanel(); 067 panel.add(blurb); 068 return panel; 069 } 070 071 @Override 072 protected void hideIcons() { 073 } 074 075 /** 076 * CENTER Panel 077 */ 078 MemoryIcon _readMem; 079 MemoryInputIcon _writeMem; 080 MemorySpinnerIcon _spinMem; 081 MemoryComboIcon _comboMem; 082 083 @Override 084 protected void initIconFamiliesPanel() { 085 _iconFamilyPanel = new JPanel(); 086 _iconFamilyPanel.setLayout(new BoxLayout(_iconFamilyPanel, BoxLayout.Y_AXIS)); 087 _iconFamilyPanel.setOpaque(true); 088 if (!_update) { 089 _iconFamilyPanel.add(instructions()); 090 } 091 092 makeDragIconPanel(); 093 makeDndIcon(null); 094 log.debug("initIconFamiliesPanel done"); 095 } 096 097 @Override 098 protected void makeDndIcon(java.util.HashMap<String, NamedIcon> iconMap) { 099 if (_update) { 100 return; 101 } 102 JPanel panel = new JPanel(); 103 panel.setOpaque(false); 104 panel.setLayout(new java.awt.GridBagLayout()); 105 Editor editor = _frame.getEditor(); 106 java.awt.GridBagConstraints c = new java.awt.GridBagConstraints(); 107 c.gridwidth = 1; 108 c.gridheight = 1; 109 c.gridx = 0; 110 c.gridy = 0; 111 c.anchor = java.awt.GridBagConstraints.CENTER; 112 c.weightx = 1.0; 113 114 JLabel label = new JLabel(Bundle.getMessage("ReadWriteMemory")); 115 label.setOpaque(false); 116 panel.add(label, c); 117 c.gridy = 1; 118 _writeMem = new MemoryInputIcon(5, editor); 119 panel.add(makeDragIcon(_writeMem, Type.READWRITE), c); 120 121 c.gridx = 1; 122 c.gridy = 0; 123 c.anchor = java.awt.GridBagConstraints.CENTER; 124 label = new JLabel(Bundle.getMessage("ReadMemory")); 125 label.setOpaque(false); 126 panel.add(label, c); 127 c.gridy = 1; 128 _readMem = new MemoryIcon("_____", editor); 129 panel.add(makeDragIcon(_readMem, Type.READONLY), c); 130 131 c.gridx = 2; 132 c.gridy = 0; 133 label = new JLabel(Bundle.getMessage("SpinnerMemory")); 134 label.setOpaque(false); 135 panel.add(label, c); 136 c.gridy = 1; 137 _spinMem = new MemorySpinnerIcon(editor); 138 panel.add(makeDragIcon(_spinMem, Type.SPINNER), c); 139 140 c.gridx = 3; 141 c.gridy = 0; 142 label = new JLabel(Bundle.getMessage("ComboMemory")); 143 label.setOpaque(false); 144 panel.add(label, c); 145 c.gridy = 1; 146 String[] list = {"item1", "Item2", "Item3"}; 147 _comboMem = new MemoryComboIcon(editor, list); 148 panel.add(makeDragIcon(_comboMem, Type.COMBO), c); 149 150 _spinner = new JSpinner(new SpinnerNumberModel(0, 0, 100, 1)); 151 JTextField field = ((JSpinner.DefaultEditor) _spinner.getEditor()).getTextField(); 152 field.setColumns(2); 153 field.setText("5"); 154 _spinner.setMaximumSize(_spinner.getPreferredSize()); 155 _spinner.addChangeListener(this); 156 c.gridx = 1; 157 c.gridy = 2; 158 c.gridwidth = 2; 159 c.anchor = java.awt.GridBagConstraints.CENTER; 160 panel.add(_spinner, c); 161 162 c.gridy = 3; 163 c.anchor = java.awt.GridBagConstraints.NORTH; 164 label = new JLabel(Bundle.getMessage("MemoryWidth")); 165 label.setOpaque(false); 166 panel.add(label, c); 167 168 _dragIconPanel.add(panel); 169 _dragIconPanel.invalidate(); 170 } 171 172 private JPanel makeDragIcon(JComponent mem, Type type) { 173 JPanel panel = new JPanel(); 174 panel.setOpaque(false); 175 JPanel comp; 176 try { 177 comp = getDragger(new DataFlavor(Editor.POSITIONABLE_FLAVOR), type, mem); 178 comp.setOpaque(false); 179 comp.setToolTipText(Bundle.getMessage("ToolTipDragIcon")); 180 } catch (java.lang.ClassNotFoundException cnfe) { 181 log.error("Unable to find class supporting {}", Editor.POSITIONABLE_FLAVOR, cnfe); 182 comp = new JPanel(); 183 } 184 panel.add(comp); 185 return panel; 186 } 187 188 /* 189 * Set column width for InputMemoryIcon. 190 */ 191 @Override 192 public void stateChanged(ChangeEvent e) { 193 if (log.isDebugEnabled()) { 194 log.debug("stateChanged: class= {}, value= {}", _spinner.getValue().getClass().getName(), 195 _spinner.getValue()); 196 } 197 Integer nCols = (Integer) _spinner.getValue(); 198 _writeMem.setNumColumns(nCols); 199 } 200 201 /** 202 * ListSelectionListener action from table. 203 */ 204 @Override 205 public void valueChanged(ListSelectionEvent e) { 206 if (_table == null) { 207 return; 208 } 209 int row = _table.getSelectedRow(); 210 log.debug("Table valueChanged: row= {}", row); 211 if (row >= 0) { 212 if (_updateButton != null) { 213 _updateButton.setEnabled(true); 214 _updateButton.setToolTipText(null); 215 } 216 } else { 217 if (_updateButton != null) { 218 _updateButton.setEnabled(false); 219 _updateButton.setToolTipText(Bundle.getMessage("ToolTipPickFromTable")); 220 } 221 _dragIconPanel.removeAll(); 222 makeDragIconPanel(); 223 makeDndIcon(null); // use override 224 } 225 validate(); 226 } 227 228 protected IconDragJComponent getDragger(DataFlavor flavor, Type type, JComponent comp) { 229 return new IconDragJComponent(flavor, type, comp); 230 } 231 232 protected class IconDragJComponent extends DragJComponent { 233 234 Type _memType; 235 236 public IconDragJComponent(DataFlavor flavor, Type type, JComponent comp) { 237 super(flavor, comp); 238 _memType = type; 239 } 240 241 @Override 242 protected boolean okToDrag() { 243 Memory bean = getDeviceNamedBean(); 244 if (bean == null) { 245 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("noRowSelected"), 246 Bundle.getMessage("WarningTitle"), JmriJOptionPane.WARNING_MESSAGE); 247 return false; 248 } 249 return true; 250 } 251 252 @Override 253 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 254 if (!isDataFlavorSupported(flavor)) { 255 return null; 256 } 257 Memory bean = getDeviceNamedBean(); 258 if (bean == null) { 259 log.error("IconDragJComponent.getTransferData: Memory is null!"); 260 return null; 261 } 262 263 Editor editor = _frame.getEditor(); 264 if (flavor.isMimeTypeEqual(Editor.POSITIONABLE_FLAVOR)) { 265 int numCols = 5; 266 try { 267 ((JSpinner.DefaultEditor) _spinner.getEditor()).commitEdit(); 268 SpinnerNumberModel spinModel = (SpinnerNumberModel) _spinner.getModel(); 269 if (log.isDebugEnabled()) { 270 log.debug("MemoryDnD.createTransferable: spinCols= {}", spinModel.getNumber().intValue()); 271 } 272 numCols = spinModel.getNumber().intValue(); 273 } catch (java.text.ParseException pe) { 274 log.error("MemoryDnD.createTransferable: ", pe); 275 } 276 switch (_memType) { 277 case READONLY: 278 MemoryIcon m = new MemoryIcon("", editor); 279 m.setMemory(bean.getDisplayName()); 280// m.setSize(m.getPreferredSize().width, m.getPreferredSize().height); 281 m.getPopupUtility().setFixedWidth(numCols*10); 282 m.setLevel(Editor.MEMORIES); 283 return m; 284 case READWRITE: 285 MemoryInputIcon mi = new MemoryInputIcon(numCols, editor); 286 mi.setMemory(bean.getDisplayName()); 287 mi.setSize(mi.getPreferredSize().width, mi.getPreferredSize().height); 288 mi.setLevel(Editor.MEMORIES); 289 return mi; 290 case SPINNER: 291 MemorySpinnerIcon ms = new MemorySpinnerIcon(editor); 292 ms.setMemory(bean.getDisplayName()); 293 ms.setSize(ms.getPreferredSize().width, ms.getPreferredSize().height); 294 ms.setLevel(Editor.MEMORIES); 295 return ms; 296 case COMBO: 297 MemoryComboIcon mc = new MemoryComboIcon(editor, list); 298 mc.setMemory(bean.getDisplayName()); 299 mc.setSize(mc.getPreferredSize().width, mc.getPreferredSize().height); 300 mc.setLevel(Editor.MEMORIES); 301 return mc; 302 default: 303 // fall through 304 break; 305 } 306 } else if (DataFlavor.stringFlavor.equals(flavor)) { 307 return _itemType + " icons for \"" + bean.getDisplayName() + "\""; 308 } 309 return null; 310 } 311 } 312 313 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MemoryItemPanel.class); 314 315}