001package jmri.jmrit.display.controlPanelEditor; 002 003import java.awt.Component; 004import java.awt.Dimension; 005import java.beans.PropertyChangeEvent; 006import java.beans.PropertyChangeListener; 007import java.util.ArrayList; 008import java.util.List; 009import javax.swing.AbstractListModel; 010import javax.swing.JLabel; 011import javax.swing.JList; 012import javax.swing.ListCellRenderer; 013 014import org.slf4j.Logger; 015import org.slf4j.LoggerFactory; 016 017import jmri.NamedBean; 018import jmri.jmrit.logix.OBlock; 019import jmri.jmrit.logix.Portal; 020 021/** 022 * 023 * @author Pete Cressman Copyright: Copyright (c) 2020 024 * 025 */ 026public class SignalList extends JList<SignalPair> { 027 028 private final SignalListModel _signalListModel; 029 030 SignalList(OBlock block, EditFrame parent) { 031 super(); 032 _signalListModel = new SignalListModel(block, parent); 033 setModel(_signalListModel); 034 setCellRenderer(new SignalCellRenderer()); 035 setPreferredSize(new Dimension(300, 120)); 036 setVisibleRowCount(5); 037 } 038 039 void dataChange() { 040 _signalListModel.dataChange(); 041 } 042 043 void setSelected(Portal portal) { 044 for (SignalPair sp : _signalListModel._list) { 045 if (sp._portal.equals(portal)) { 046 setSelectedValue(sp, true); 047 return; 048 } 049 } 050 clearSelection(); 051 } 052 053 private static class SignalCellRenderer extends JLabel implements ListCellRenderer<SignalPair>{ 054 055 @Override 056 public Component getListCellRendererComponent( 057 JList<? extends SignalPair> list, // the list 058 SignalPair value, // value to display 059 int index, // cell index 060 boolean isSelected, // is the cell selected 061 boolean cellHasFocus) // does the cell have focus 062 { 063 setText(value.getDiscription()); 064 if (isSelected) { 065 setBackground(list.getSelectionBackground()); 066 setForeground(list.getSelectionForeground()); 067 } else { 068 setBackground(list.getBackground()); 069 setForeground(list.getForeground()); 070 } 071 setEnabled(list.isEnabled()); 072 setFont(list.getFont()); 073 setOpaque(true); 074 return this; 075 } 076 } 077 078 static class SignalListModel extends AbstractListModel<SignalPair> implements PropertyChangeListener { 079 080 OBlock _homeBlock; 081 private final EditFrame _parent; 082 List<SignalPair> _list = new ArrayList<>(); 083 084 SignalListModel(OBlock block, EditFrame parent) { 085 _homeBlock = block; 086 _parent = parent; 087 _homeBlock.addPropertyChangeListener(this); 088 makeList(); 089 } 090 091 private void makeList() { 092 for (SignalPair sp : _list) { 093 sp._portal.removePropertyChangeListener(this); 094 } 095 _list.clear(); 096 for (Portal portal : _homeBlock.getPortals()) { 097 NamedBean signal = portal.getSignalProtectingBlock(_homeBlock); 098 if (signal != null) { 099 _list.add(new SignalPair(signal, portal)); 100 } 101 } 102 for (SignalPair sp : _list) { 103 sp._portal.addPropertyChangeListener(this); 104 } 105 } 106 107 @Override 108 public int getSize() { 109 return _list.size(); 110 } 111 112 @Override 113 public SignalPair getElementAt(int index) { 114 if (index < getSize()) { 115 return _list.get(index); 116 } 117 return null; 118 } 119 120 public void dataChange() { 121 fireContentsChanged(this, 0, 0); 122 } 123 124 @Override 125 public void propertyChange(PropertyChangeEvent e) { 126 Object source = e.getSource(); 127 String property = e.getPropertyName(); 128 if (log.isDebugEnabled()) { 129 log.debug("property = {} source= {}", property, source.getClass().getName()); 130 } 131 if (source instanceof OBlock && property.equals("deleted")) { 132 _homeBlock.removePropertyChangeListener(this); 133 _parent.closingEvent(true); 134 } else { 135 makeList(); 136 fireContentsChanged(this, 0, 0); 137 if (property.equals("signalChange") || property.equals("NameChange")) { 138 _parent.clearListSelection(); 139 } 140 } 141 } 142 } 143 private final static Logger log = LoggerFactory.getLogger(SignalList.class); 144}