--- a/cnd.debugger.common2/src/org/netbeans/modules/cnd/debugger/common2/debugger/actions/AttachPanel.java +++ a/cnd.debugger.common2/src/org/netbeans/modules/cnd/debugger/common2/debugger/actions/AttachPanel.java @@ -98,6 +98,7 @@ import org.netbeans.modules.cnd.debugger.common2.debugger.debugtarget.DebugTarget; import org.netbeans.modules.cnd.debugger.common2.debugger.spi.UserAttachAction; import org.netbeans.modules.cnd.utils.ui.ModalMessageDlg; +import org.netbeans.spi.debugger.ui.PersistentController; import org.openide.util.Cancellable; import org.openide.util.Lookup; import org.openide.util.NbBundle; @@ -911,7 +912,7 @@ // This class is made public, to support attach history // see org.netbeans.modules.debugger.ui.actions.ConnectorPanel.ok() method implementation - public class AttachController implements Controller { + public class AttachController implements PersistentController { private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); @@ -1028,6 +1029,7 @@ private static final String HOST_NAME_PROP = "host_name"; //NOI18N private static final String NO_EXISTING_PROCESS = "qwdq123svdfv"; //NOI18N + @Override public boolean load(Properties props) { Vector> processes = psData.processes(Pattern.compile(props.getString(COMMAND_PROP, NO_EXISTING_PROCESS))); if (processes.isEmpty()) { @@ -1053,6 +1055,7 @@ return true; } + @Override public void save(Properties props) { String selectedCommand = getSelectedProcessCommand(); if (selectedCommand != null) { @@ -1064,6 +1067,7 @@ } } + @Override public String getDisplayName() { String selectedCommand = getSelectedProcessCommand(); if (selectedCommand != null) { --- a/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/ConnectPanel.java +++ a/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/ConnectPanel.java @@ -46,9 +46,9 @@ import com.sun.jdi.Bootstrap; import com.sun.jdi.VirtualMachineManager; -import com.sun.jdi.connect.Connector.Argument; import com.sun.jdi.connect.*; +import com.sun.jdi.connect.Connector.Argument; import java.awt.Cursor; import java.awt.Dimension; import java.awt.GridBagConstraints; @@ -82,17 +82,17 @@ import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.netbeans.api.debugger.DebuggerEngine; - +import org.netbeans.api.debugger.DebuggerInfo; import org.netbeans.api.debugger.DebuggerManager; -import org.netbeans.api.debugger.DebuggerInfo; import org.netbeans.api.debugger.Properties; +import org.netbeans.api.debugger.jpda.AttachingDICookie; import org.netbeans.api.debugger.jpda.DebuggerStartException; import org.netbeans.api.debugger.jpda.JPDADebugger; -import org.netbeans.api.debugger.jpda.AttachingDICookie; import org.netbeans.api.debugger.jpda.ListeningDICookie; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; import org.netbeans.spi.debugger.ui.Controller; +import org.netbeans.spi.debugger.ui.PersistentController; import org.openide.DialogDisplayer; import org.openide.ErrorManager; import org.openide.NotifyDescriptor; @@ -647,7 +647,7 @@ } } - public class ConnectController implements Controller { + public class ConnectController implements PersistentController { PropertyChangeSupport pcs = new PropertyChangeSupport(this); private boolean valid = true; @@ -751,6 +751,7 @@ return true; } + @Override public boolean load(final Properties props) { assert !SwingUtilities.isEventDispatchThread(); waitForConnectorsLoad(); @@ -784,6 +785,7 @@ return true; } + @Override public void save(Properties props) { assert connectorsLoaded.get(); final Connector[] connectorPtr = new Connector[] { null }; @@ -832,6 +834,7 @@ props.setString ("attaching_connector", connector.name()); } + @Override public String getDisplayName() { assert connectorsLoaded.get(); final Connector connector = selectedConnector; --- a/spi.debugger.ui/apichanges.xml +++ a/spi.debugger.ui/apichanges.xml @@ -192,6 +192,25 @@ + + + PersistentController interface added. + + + + + +

+ PersistentController interface introduced + to provide persistence mechanism to attach controllers. + Debug action provides access to history of customized attach + controllers. +

+
+ + +
+ --- a/spi.debugger.ui/manifest.mf +++ a/spi.debugger.ui/manifest.mf @@ -2,6 +2,6 @@ OpenIDE-Module: org.netbeans.spi.debugger.ui/1 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/debugger/ui/Bundle.properties OpenIDE-Module-Layer: org/netbeans/modules/debugger/resources/mf-layer.xml -OpenIDE-Module-Specification-Version: 2.44 +OpenIDE-Module-Specification-Version: 2.45 OpenIDE-Module-Provides: org.netbeans.spi.debugger.ui OpenIDE-Module-Install: org/netbeans/modules/debugger/ui/DebuggerModule.class --- a/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/actions/ConnectorPanel.java +++ a/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/actions/ConnectorPanel.java @@ -71,6 +71,7 @@ import org.netbeans.spi.debugger.ui.AttachType; import org.netbeans.spi.debugger.ui.Controller; +import org.netbeans.spi.debugger.ui.PersistentController; import org.openide.awt.Mnemonics; import org.openide.util.Exceptions; @@ -268,30 +269,15 @@ } } // for } - Method saveMethod = null; - Method displayNameMethod = null; - try { - saveMethod = controller.getClass().getMethod("save", Properties.class); - displayNameMethod = controller.getClass().getMethod("getDisplayName"); - } catch (NoSuchMethodException ex) { - } catch (SecurityException ex) { - } String dispName = null; - if (saveMethod != null && displayNameMethod != null) { + if (controller instanceof PersistentController) { + PersistentController pController = (PersistentController) controller; Properties slot = props.getProperties("slot_" + freeSlot); - try { - dispName = (String) displayNameMethod.invoke(controller); - if (dispName != null && dispName.trim().length() > 0) { - slot.setString("display_name", dispName); - saveMethod.invoke(controller, slot.getProperties("values")); - slot.setString("attach_type", defaultAttachTypeName); - } - } catch (IllegalAccessException ex) { - Exceptions.printStackTrace(ex); // [TODO] - } catch (IllegalArgumentException ex) { - Exceptions.printStackTrace(ex); // [TODO] - } catch (InvocationTargetException ex) { - Exceptions.printStackTrace(ex); // [TODO] + dispName = pController.getDisplayName(); + if (dispName != null && dispName.trim().length() > 0) { + slot.setString("display_name", dispName); + pController.save(slot.getProperties("values")); + slot.setString("attach_type", defaultAttachTypeName); } } --- a/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/actions/DebugMainProjectAction.java +++ a/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/actions/DebugMainProjectAction.java @@ -69,6 +69,7 @@ import org.netbeans.api.project.ui.OpenProjects; import org.netbeans.spi.debugger.ui.AttachType; import org.netbeans.spi.debugger.ui.Controller; +import org.netbeans.spi.debugger.ui.PersistentController; import org.netbeans.spi.project.ActionProvider; import org.netbeans.spi.project.ui.support.MainProjectSensitiveActions; import org.openide.awt.Actions; @@ -266,7 +267,7 @@ } // for if (att != null) { final AttachType attachType = att; - final Controller[] controllerPtr = new Controller[] { null }; + final PersistentController[] controllerPtr = new PersistentController[] { null }; try { SwingUtilities.invokeAndWait(new Runnable() { @Override @@ -277,7 +278,9 @@ Exceptions.printStackTrace(new IllegalStateException("FIXME: JComponent "+customizer+" must not implement Controller interface!")); controller = (Controller) customizer; } - controllerPtr[0] = controller; + if (controller instanceof PersistentController) { + controllerPtr[0] = (PersistentController) controller; + } } }); } catch (InterruptedException ex) { @@ -287,22 +290,13 @@ Exceptions.printStackTrace(ex); return ; } - final Controller controller = controllerPtr[0]; - Method loadMethod = null; - try { - loadMethod = controller.getClass().getMethod("load", Properties.class); - } catch (NoSuchMethodException ex) { - } catch (SecurityException ex) { + final PersistentController controller = controllerPtr[0]; + if (controller == null) { + return ; } - if (loadMethod == null) { return; } - try { - Boolean result = (Boolean)loadMethod.invoke(controller, props.getProperties("slot_" + usedSlots[index]).getProperties("values")); - if (!result) { - return; // [TODO] not loaded, cannot be used to attach - } - } catch (IllegalAccessException ex) { - } catch (IllegalArgumentException ex) { - } catch (InvocationTargetException ex) { + boolean result = controller.load(props.getProperties("slot_" + usedSlots[index]).getProperties("values")); + if (!result) { + return; // [TODO] not loaded, cannot be used to attach } final boolean[] passedPtr = new boolean[] { false }; try { --- a/spi.debugger.ui/src/org/netbeans/spi/debugger/ui/PersistentController.java +++ a/spi.debugger.ui/src/org/netbeans/spi/debugger/ui/PersistentController.java @@ -0,0 +1,73 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2014 Sun Microsystems, Inc. + */ + +package org.netbeans.spi.debugger.ui; + +import org.netbeans.api.debugger.Properties; + +/** + * Controller, that is able to persist it's customized state. + * + * @author Martin Entlicher + * @since 2.45 + */ +public interface PersistentController extends Controller { + + /** + * Display name, that characterizes the current customized state of this controller. + * @return The display name + */ + String getDisplayName(); + + /** + * Load customized state from properties. + * @param props The properties to load the state from. + * @return true if the properties were successfully loaded, false otherwise. + */ + boolean load(Properties props); + + /** + * Save customized state into properties. + * @param props The properties to save the state to. + */ + void save(Properties props); +}