001package jmri.jmrit.display.palette; 002 003import java.awt.BorderLayout; 004import java.awt.datatransfer.DataFlavor; 005import java.awt.datatransfer.UnsupportedFlavorException; 006import java.io.IOException; 007import java.util.HashMap; 008import java.util.Map.Entry; 009 010import javax.swing.JButton; 011import javax.swing.JLabel; 012import javax.swing.JPanel; 013import javax.swing.JScrollPane; 014import javax.swing.SwingConstants; 015import javax.swing.event.ListSelectionEvent; 016 017import jmri.SignalHead; 018import jmri.jmrit.catalog.DragJLabel; 019import jmri.jmrit.catalog.NamedIcon; 020import jmri.jmrit.display.DisplayFrame; 021import jmri.jmrit.display.Editor; 022import jmri.jmrit.display.SignalHeadIcon; 023import jmri.jmrit.picker.PickListModel; 024import jmri.util.swing.JmriJOptionPane; 025 026public class SignalHeadItemPanel extends TableItemPanel<SignalHead> { 027 028 public SignalHeadItemPanel(DisplayFrame parentFrame, String type, String family, PickListModel<SignalHead> model) { 029 super(parentFrame, type, family, model); 030 } 031 032 @Override 033 protected JPanel initTablePanel(PickListModel<SignalHead> model) { 034 _table = model.makePickTable(); 035 JPanel topPanel = new JPanel(); 036 topPanel.setLayout(new BorderLayout()); 037 topPanel.add(new JLabel(model.getName(), SwingConstants.CENTER), BorderLayout.NORTH); 038 _scrollPane = new JScrollPane(_table); 039 topPanel.add(_scrollPane, BorderLayout.CENTER); 040 _table.getSelectionModel().addListSelectionListener(this); 041 _table.setToolTipText(Bundle.getMessage("ToolTipDragTableRow")); 042 _scrollPane.setToolTipText(Bundle.getMessage("ToolTipDragTableRow")); 043 topPanel.setToolTipText(Bundle.getMessage("ToolTipDragTableRow")); 044 JPanel panel = new JPanel(); 045 JButton clearSelectionButton = new JButton(Bundle.getMessage("ClearSelection")); 046 clearSelectionButton.addActionListener(a -> _table.clearSelection()); 047 clearSelectionButton.setToolTipText(Bundle.getMessage("ToolTipClearSelection")); 048 panel.add(clearSelectionButton); 049 topPanel.add(panel, BorderLayout.SOUTH); 050 return topPanel; 051 } 052 053 @Override 054 protected String getDisplayKey() { 055 return "SignalHeadStateGreen"; 056 } 057 058 /** 059 * ListSelectionListener action. 060 */ 061 @Override 062 public void valueChanged(ListSelectionEvent e) { 063 if (_table == null || _updateButton == null) { 064 return; 065 } 066 int row = _table.getSelectedRow(); 067 // Index error if only one row 068 if (_table.getRowCount() < 2) { 069 log.debug("Table valueChanged: row= {}, {}({})", 070 row, _table.getValueAt(row, 0), _table.getValueAt(row, 1)); 071 } 072 if (row >= 0) { 073 _updateButton.setEnabled(true); 074 _updateButton.setToolTipText(null); 075 if (_family != null) { 076 // get raw map of all appearances for row's head type. 077 HashMap<String, NamedIcon> fullmap = getFilteredIconMap(makeNewIconMap(_itemType)); 078 // icon map of appearances for type of current bean. 079 HashMap<String, NamedIcon> currentmap = (getIconMap()); 080 log.debug("currentmap keys = {}", currentmap.keySet().toString()); 081 // use current images for as many of the fullMap's members as possible 082 HashMap<String, NamedIcon> iconMap = new HashMap<>(); 083 for (Entry<String, NamedIcon> entry : fullmap.entrySet()) { 084 String key = entry.getKey(); 085 String newKey = ItemPalette.convertText(key); 086 log.debug("fullmap key = {}, converts to {}", key, newKey); 087 NamedIcon icon = currentmap.get(newKey); 088 if (icon != null) { 089 iconMap.put(newKey, icon); 090 } else { 091 iconMap.put(newKey, entry.getValue()); 092 } 093 } 094 log.debug("set Signal Head {} map size= {}", _table.getValueAt(row, 0), iconMap.size()); 095// _currentIconMap = iconMap; 096 updateFamiliesPanel(); 097 } 098 } else { 099 _updateButton.setEnabled(false); 100 _updateButton.setToolTipText(Bundle.getMessage("ToolTipPickFromTable")); 101 } 102 if (_iconPanel.isVisible()) { 103 showIcons(); 104 } 105 } 106 107 protected HashMap<String, NamedIcon> getFilteredIconMap(HashMap<String, NamedIcon> allIconsMap) { 108 if (allIconsMap == null) { 109 JmriJOptionPane.showMessageDialog(_frame, 110 Bundle.getMessage("FamilyNotFound", _itemType, _family), 111 Bundle.getMessage("WarningTitle"), JmriJOptionPane.WARNING_MESSAGE); 112 return null; 113 } 114 if (_table == null || _table.getSelectedRow() < 0) { 115 return allIconsMap; 116 } 117 118 SignalHead sh = getDeviceNamedBean(); 119 if (sh != null) { 120 String[] states = sh.getValidStateNames(); 121 if (states.length == 0) { 122 return allIconsMap; 123 } 124 HashMap<String, NamedIcon> iconMap = new HashMap<>(); 125 for (Entry<String, NamedIcon> entry : allIconsMap.entrySet()) { 126 String name = entry.getKey(); 127 String borderName = ItemPalette.convertText(name); 128 for (String state : states) { 129 if (borderName.equals(state) || name.equals("SignalHeadStateDark") 130 || name.equals(ItemPalette.convertText("SignalHeadStateDark")) 131 || name.equals("SignalHeadStateHeld") 132 || name.equals(ItemPalette.convertText("SignalHeadStateHeld"))) { 133 iconMap.put(name, entry.getValue()); 134 break; 135 } 136 } 137 } 138 log.debug("filteredMap size= {}", iconMap.size()); 139 return iconMap; 140 } 141 log.debug("Map NOT filtered, size= {}", allIconsMap.size()); 142 return allIconsMap; 143 } 144 145 @Override 146 protected JLabel getDragger(DataFlavor flavor, HashMap<String, 147 NamedIcon> map, NamedIcon icon) { 148 return new IconDragJLabel(flavor, map, icon); 149 } 150 151 protected class IconDragJLabel extends DragJLabel { 152 153 HashMap<String, NamedIcon> iMap; 154 155 public IconDragJLabel(DataFlavor flavor, HashMap<String, NamedIcon> map, 156 NamedIcon icon) { 157 super(flavor, icon); 158 iMap = map; 159 } 160 161 @Override 162 protected boolean okToDrag() { 163 SignalHead bean = getDeviceNamedBean(); 164 if (bean == null) { 165 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("noRowSelected"), 166 Bundle.getMessage("WarningTitle"), JmriJOptionPane.WARNING_MESSAGE); 167 return false; 168 } 169 return true; 170 } 171 172 @Override 173 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 174 if (!isDataFlavorSupported(flavor)) { 175 return null; 176 } 177 SignalHead bean = getDeviceNamedBean(); 178 if (bean == null) { 179 return null; 180 } 181 182 if (flavor.isMimeTypeEqual(Editor.POSITIONABLE_FLAVOR)) { 183 SignalHeadIcon sh = new SignalHeadIcon(_frame.getEditor()); 184 sh.setSignalHead(bean.getDisplayName()); 185 HashMap<String, NamedIcon> map = getFilteredIconMap(iMap); 186 for (Entry<String, NamedIcon> ent : map.entrySet()) { 187 sh.setIcon(ent.getKey(), new NamedIcon(ent.getValue())); 188 } 189 sh.setFamily(_family); 190 sh.setLevel(Editor.SIGNALS); 191 return sh; 192 } else if (DataFlavor.stringFlavor.equals(flavor)) { 193 return _itemType + " icons for \"" + bean.getDisplayName() + "\""; 194 } 195 return null; 196 } 197 } 198 199 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SignalHeadItemPanel.class); 200 201}