001package jmri.jmrix.swing; 002 003import java.beans.IndexedPropertyChangeEvent; 004import java.beans.PropertyChangeEvent; 005import java.beans.PropertyChangeListener; 006import java.util.List; 007import javax.swing.AbstractListModel; 008import javax.swing.ComboBoxModel; 009import javax.swing.JComboBox; 010import jmri.InstanceManager; 011import jmri.SystemConnectionMemo; 012 013/** 014 * JComboBox that provides a list of SystemConnectionMemos by user name. 015 * 016 * @author Randall Wood Copyright 2017 017 */ 018public class SystemConnectionComboBox extends JComboBox<SystemConnectionMemo> { 019 020 private final SystemConnectionComboBoxModel model = new SystemConnectionComboBoxModel(); 021 022 public SystemConnectionComboBox() { 023 super(); 024 super.setModel(this.model); 025 } 026 027 public void dispose() { 028 this.model.dispose(); 029 } 030 031 private static class SystemConnectionComboBoxModel extends AbstractListModel<SystemConnectionMemo> 032 implements ComboBoxModel<SystemConnectionMemo> { 033 034 SystemConnectionMemo selectedItem = null; 035 PropertyChangeListener memoListener = (PropertyChangeEvent evt) -> { 036 switch (evt.getPropertyName()) { 037 case SystemConnectionMemo.USER_NAME: 038 int index = this.getSource().indexOf(evt.getSource()); 039 this.fireContentsChanged(this, index, index); 040 break; 041 default: 042 // do nothing 043 break; 044 } 045 }; 046 PropertyChangeListener imListener = (PropertyChangeEvent evt) -> { 047 if (evt.getSource().equals(InstanceManager.getDefault())) { 048 if (evt instanceof IndexedPropertyChangeEvent) { 049 IndexedPropertyChangeEvent event = (IndexedPropertyChangeEvent) evt; 050 if (event.getNewValue() != null) { 051 ((SystemConnectionMemo) event.getNewValue()).addPropertyChangeListener(memoListener); 052 this.fireIntervalAdded(this, event.getIndex(), event.getIndex()); 053 } else if (event.getOldValue() != null) { 054 ((SystemConnectionMemo) event.getOldValue()).removePropertyChangeListener(memoListener); 055 this.fireIntervalRemoved(this, event.getIndex(), event.getIndex()); 056 } 057 this.fireContentsChanged(this, event.getIndex(), event.getIndex()); 058 } else { 059 Object item = evt.getNewValue(); 060 if (item == null || item instanceof SystemConnectionMemo) { 061 SystemConnectionMemo memo = (SystemConnectionMemo) item; 062 if (memo == null || this.getSource().contains(memo)) { 063 this.setSelectedItem(memo); 064 } 065 } 066 } 067 } 068 }; 069 070 public SystemConnectionComboBoxModel() { 071 InstanceManager.addPropertyChangeListener(InstanceManager.getListPropertyName(SystemConnectionMemo.class), imListener); 072 InstanceManager.addPropertyChangeListener(InstanceManager.getDefaultsPropertyName(SystemConnectionMemo.class), imListener); 073 this.getSource().forEach((memo) -> { 074 memo.addPropertyChangeListener(memoListener); 075 }); 076 } 077 078 /** {@inheritDoc} */ 079 @Override 080 public void setSelectedItem(Object anItem) { // Object parameter required by interface 081 if ((anItem == null || anItem instanceof SystemConnectionMemo) // anItem is valid in this model 082 && ((selectedItem != null && !selectedItem.equals(anItem)) // anItem is not selectedItem 083 || selectedItem == null && anItem != null)) { 084 this.selectedItem = (SystemConnectionMemo) anItem; 085 this.fireContentsChanged(this, -1, -1); 086 } 087 } 088 089 /** {@inheritDoc} */ 090 @Override 091 public SystemConnectionMemo getSelectedItem() { 092 return this.selectedItem; 093 } 094 095 /** {@inheritDoc} */ 096 @Override 097 public int getSize() { 098 return this.getSource().size(); 099 } 100 101 /** {@inheritDoc} */ 102 @Override 103 public SystemConnectionMemo getElementAt(int index) { 104 return this.getSource().get(index); 105 } 106 107 public void dispose() { 108 InstanceManager.removePropertyChangeListener(InstanceManager.getListPropertyName(SystemConnectionMemo.class), imListener); 109 InstanceManager.removePropertyChangeListener(InstanceManager.getDefaultsPropertyName(SystemConnectionMemo.class), imListener); 110 } 111 112 private List<SystemConnectionMemo> getSource() { 113 return InstanceManager.getList(SystemConnectionMemo.class); 114 } 115 } 116 117}