001package jmri.jmrix.can.cbus.swing.nodeconfig; 002 003import java.awt.BorderLayout; 004import java.beans.PropertyChangeEvent; 005import java.beans.PropertyChangeListener; 006 007import javax.annotation.Nonnull; 008import javax.annotation.OverridingMethodsMustInvokeSuper; 009 010import jmri.jmrix.can.cbus.node.CbusNode; 011import jmri.util.swing.JmriJOptionPane; 012 013/** 014 * 015 * @author Steve Young Copyright (C) 2019, 2020 016 */ 017abstract public class CbusNodeConfigTab extends jmri.jmrix.can.swing.CanPanel implements PropertyChangeListener { 018 019 protected CbusNode nodeOfInterest; 020 private final NodeConfigToolPane mainpane; 021 private boolean _activeDialogue; 022 023 /** 024 * Create a new instance of CbusNodeSetupPane. 025 * @param main the main NodeConfigToolPane this is a pane of. 026 */ 027 protected CbusNodeConfigTab( NodeConfigToolPane main ) { 028 super(); 029 mainpane = main; 030 if (main != null ){ 031 super.initComponents(main.getMemo()); 032 } 033 super.setLayout(new BorderLayout() ); 034 _activeDialogue = false; 035 } 036 037 /** 038 * Get the Main Node Manager Pane. 039 * @return Manager Pane 040 */ 041 protected NodeConfigToolPane getMainPane(){ 042 return mainpane; 043 } 044 045 /** 046 * Set the Node displayed in the Pane. 047 * Checks for node unchanged and 048 * disposes listeners on previous node. 049 * @param node New CbusNode to display 050 */ 051 public final void setNode(CbusNode node){ 052 if ( nodeOfInterest != null ) { 053 if (nodeOfInterest.equals(node)){ 054 return; 055 } 056 disposeOfNode(nodeOfInterest); 057 } 058 if ( node != null ) { 059 nodeOfInterest = node; 060 nodeOfInterest.addPropertyChangeListener(this); 061 changedNode(node); 062 this.setVisible(true); 063 validate(); 064 repaint(); 065 } 066 } 067 068 /** 069 * Stop the tab or Node selection switching from the Pane. 070 * Defaults to false 071 * @return true to veto, false to not veto 072 */ 073 protected boolean getVetoBeingChanged(){ 074 return false; 075 } 076 077 /** 078 * Set that a Dialog box is open within the Pane. 079 * @param newVal true if being displayed, else false 080 */ 081 protected void setActiveDialog(boolean newVal){ 082 _activeDialogue = newVal; 083 } 084 085 /** 086 * Get if a Dialog box is open within the Pane. 087 * @return true if displaying dialog, else false 088 */ 089 protected boolean getActiveDialog(){ 090 return _activeDialogue; 091 } 092 093 /** 094 * Get the Tab Index within the Main Node Manager Pane 095 * @return index for this pane 096 */ 097 protected final int getTabIndex(){ 098 return getMainPane().getTabs().indexOf(this); 099 } 100 101 /** 102 * Extending classes must implement this for changed node notifications 103 * @param node The new Node 104 */ 105 protected abstract void changedNode(@Nonnull CbusNode node); 106 107 /** 108 * Remove any update listeners for the node. 109 * @param node Node to remove listeners for 110 */ 111 @OverridingMethodsMustInvokeSuper // to remove Node Property Change Listener 112 protected void disposeOfNode(@Nonnull CbusNode node){ 113 node.removePropertyChangeListener(this); 114 } 115 116 /** 117 * Get the index of the node in the main Node Table 118 * @return Row Number for the CbusNode nodeOfInterest 119 */ 120 protected int getNodeRow(){ 121 return getMainPane().nodeTable.convertRowIndexToView(getMainPane(). 122 getNodeModel().getNodeRowFromNodeNum(nodeOfInterest.getNodeNumber())); 123 } 124 125 /** 126 * Reset the Main Node Manager pane to that of the vetoing Pane. 127 */ 128 protected void resetViewToVeto(){ 129 getMainPane().nodeTable.getSelectionModel().clearSelection(); 130 getMainPane().nodeTable.getSelectionModel().setSelectionInterval(getNodeRow(),getNodeRow()); 131 getMainPane().tabbedPane.setSelectedIndex(getTabIndex()); 132 } 133 134 /** 135 * Get a Cancel Edit / Save Edit / Continue Edit Dialog. 136 * @param adviceString Extra text to display in box without opening / closing html tag. 137 * @return true to veto, else false to proceed and continue. 138 */ 139 protected boolean getCancelSaveEditDialog(String adviceString){ 140 setActiveDialog(true); 141 resetViewToVeto(); 142 int selectedValue = JmriJOptionPane.showOptionDialog(this.getParent(), 143 "<html>" + adviceString + "<br>" + Bundle.getMessage("ContinueEditQuestion")+"</html>" 144 ,Bundle.getMessage("WarningTitle") + " " + nodeOfInterest, 145 JmriJOptionPane.DEFAULT_OPTION,JmriJOptionPane.QUESTION_MESSAGE, null, 146 new String[]{Bundle.getMessage("CancelEdit"), Bundle.getMessage("SaveEdit"), Bundle.getMessage("ContinueEdit")}, 147 Bundle.getMessage("ContinueEdit")); // default choice 148 149 setActiveDialog(false); 150 switch (selectedValue) { 151 case -1: // Dialog Closed 152 case 0: // array position 0, CancelEdit 153 cancelOption(); 154 return false; 155 case 1: // array position 1, SaveEdit 156 saveOption(); 157 return false; 158 default: // array position 2, ContinueEdit 159 return true; 160 } 161 } 162 163 /** 164 * Custom Cancel action for getCancelSaveEditDialog. 165 */ 166 protected void cancelOption() {} 167 168 /** 169 * Custom Save action for getCancelSaveEditDialog. 170 */ 171 protected void saveOption() {} 172 173 /** 174 * {@inheritDoc} 175 * Get updates from the CbusNode nodeOfInterest 176 */ 177 @Override 178 public void propertyChange(PropertyChangeEvent ev){ 179 } 180 181 /** 182 * {@inheritDoc} 183 */ 184 @Override 185 public void dispose(){ 186 if (nodeOfInterest!=null){ 187 disposeOfNode(nodeOfInterest); 188 } 189 super.dispose(); 190 } 191 192 // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CbusNodeConfigTab.class); 193 194}