#270133: Adding Suppend I/O button into Performance toolbar SuspendIOChecks270133
authorJaroslav Tulach <jtulach@netbeans.org>
Mon, 20 Mar 2017 14:51:43 +0100
branchSuspendIOChecks270133
changeset 3148471097bed01dfd
parent 314679 02d5c30cca9f
child 314848 f1602d54bbc9
#270133: Adding Suppend I/O button into Performance toolbar
masterfs.ui/nbproject/project.xml
masterfs.ui/src/org/netbeans/modules/masterfs/ui/suspend/Bundle.properties
masterfs.ui/src/org/netbeans/modules/masterfs/ui/suspend/PauseAction.java
masterfs.ui/src/org/netbeans/modules/masterfs/ui/suspend/pause.png
masterfs.ui/src/org/netbeans/modules/masterfs/ui/suspend/pause24.png
     1.1 --- a/masterfs.ui/nbproject/project.xml	Sun Mar 19 17:34:22 2017 +0100
     1.2 +++ b/masterfs.ui/nbproject/project.xml	Mon Mar 20 14:51:43 2017 +0100
     1.3 @@ -54,6 +54,14 @@
     1.4                      </run-dependency>
     1.5                  </dependency>
     1.6                  <dependency>
     1.7 +                    <code-name-base>org.openide.awt</code-name-base>
     1.8 +                    <build-prerequisite/>
     1.9 +                    <compile-dependency/>
    1.10 +                    <run-dependency>
    1.11 +                        <specification-version>7.68</specification-version>
    1.12 +                    </run-dependency>
    1.13 +                </dependency>
    1.14 +                <dependency>
    1.15                      <code-name-base>org.openide.filesystems</code-name-base>
    1.16                      <build-prerequisite/>
    1.17                      <compile-dependency/>
    1.18 @@ -85,6 +93,14 @@
    1.19                          <specification-version>8.26</specification-version>
    1.20                      </run-dependency>
    1.21                  </dependency>
    1.22 +                <dependency>
    1.23 +                    <code-name-base>org.openide.util.ui</code-name-base>
    1.24 +                    <build-prerequisite/>
    1.25 +                    <compile-dependency/>
    1.26 +                    <run-dependency>
    1.27 +                        <specification-version>9.7</specification-version>
    1.28 +                    </run-dependency>
    1.29 +                </dependency>
    1.30              </module-dependencies>
    1.31              <public-packages>
    1.32                  <package>org.netbeans.modules.masterfs.providers</package>
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/masterfs.ui/src/org/netbeans/modules/masterfs/ui/suspend/Bundle.properties	Mon Mar 20 14:51:43 2017 +0100
     2.3 @@ -0,0 +1,8 @@
     2.4 +OpenIDE-Module-Display-Category=Infrastructure
     2.5 +OpenIDE-Module-Long-Description=\
     2.6 +    Sometimes one needs to perform extensive changes to one's sources from a command line (or other external tool) and wants to prevent the IDE from reacting to them. \
     2.7 +    This module provides "Suspend I/O" action into a Performance toolbar. \
     2.8 +    Once pressed, the IDE switches into "pause" mode. \
     2.9 +    Processing of external changes is delayed (until the IDE is resumed).
    2.10 +OpenIDE-Module-Name=Suspend I/O
    2.11 +OpenIDE-Module-Short-Description=Provides action in Performance toolbar to suspend the IDE
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/masterfs.ui/src/org/netbeans/modules/masterfs/ui/suspend/PauseAction.java	Mon Mar 20 14:51:43 2017 +0100
     3.3 @@ -0,0 +1,177 @@
     3.4 +/*
     3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 + *
     3.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
     3.8 + *
     3.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    3.10 + * Other names may be trademarks of their respective owners.
    3.11 + *
    3.12 + * The contents of this file are subject to the terms of either the GNU
    3.13 + * General Public License Version 2 only ("GPL") or the Common
    3.14 + * Development and Distribution License("CDDL") (collectively, the
    3.15 + * "License"). You may not use this file except in compliance with the
    3.16 + * License. You can obtain a copy of the License at
    3.17 + * http://www.netbeans.org/cddl-gplv2.html
    3.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    3.19 + * specific language governing permissions and limitations under the
    3.20 + * License.  When distributing the software, include this License Header
    3.21 + * Notice in each file and include the License file at
    3.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    3.23 + * particular file as subject to the "Classpath" exception as provided
    3.24 + * by Oracle in the GPL Version 2 section of the License file that
    3.25 + * accompanied this code. If applicable, add the following below the
    3.26 + * License Header, with the fields enclosed by brackets [] replaced by
    3.27 + * your own identifying information:
    3.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    3.29 + *
    3.30 + * If you wish your version of this file to be governed by only the CDDL
    3.31 + * or only the GPL Version 2, indicate your decision by adding
    3.32 + * "[Contributor] elects to include this software in this distribution
    3.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    3.34 + * single choice of license, a recipient has the option to distribute
    3.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    3.36 + * to extend the choice of license to its licensees as provided above.
    3.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    3.38 + * Version 2 license, then the option applies only if the new code is
    3.39 + * made subject to such option by the copyright holder.
    3.40 + *
    3.41 + * Contributor(s):
    3.42 + *
    3.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
    3.44 + */
    3.45 +package org.netbeans.modules.masterfs.ui.suspend;
    3.46 +
    3.47 +import java.awt.Component;
    3.48 +import java.awt.EventQueue;
    3.49 +import java.awt.event.ActionEvent;
    3.50 +import java.awt.event.ActionListener;
    3.51 +import java.util.prefs.Preferences;
    3.52 +import javax.swing.AbstractAction;
    3.53 +import javax.swing.AbstractButton;
    3.54 +import javax.swing.JToggleButton;
    3.55 +import org.openide.awt.ActionID;
    3.56 +import org.openide.awt.ActionReference;
    3.57 +import org.openide.awt.ActionRegistration;
    3.58 +import org.openide.awt.Actions;
    3.59 +import org.openide.util.*;
    3.60 +import org.openide.util.NbBundle.Messages;
    3.61 +import org.openide.util.actions.Presenter;
    3.62 +
    3.63 +@ActionID(
    3.64 +    category = "System",
    3.65 +    id = "org.netbeans.modules.masterfs.ui.suspend.PauseAction"
    3.66 +)
    3.67 +@ActionRegistration(
    3.68 +    displayName = "#CTL_PauseAction",
    3.69 +    lazy = false
    3.70 +)
    3.71 +@ActionReference(path = "Toolbars/Memory", position = 15000)
    3.72 +@Messages({
    3.73 +    "CTL_PauseAction=Pause I/O Checks",
    3.74 +    "# {0} - number of pending events",
    3.75 +    "MSG_Resume=Resume (pending events: {0})"
    3.76 +})
    3.77 +public final class PauseAction extends AbstractAction implements Presenter.Toolbar {
    3.78 +    private static final RequestProcessor RP = new RequestProcessor("Pause Action"); // NOI18N
    3.79 +    private static final String SUSPEND_COUNT_PROPERTY = "org.netbeans.io.suspend".intern(); // NOI18N
    3.80 +    private static final Preferences PREFS = NbPreferences.forModule(PauseAction.class);
    3.81 +
    3.82 +    public PauseAction() {
    3.83 +        putValue("iconBase", "org/netbeans/modules/masterfs/ui/suspend/pause.png"); // NOI18N
    3.84 +        putValue(SHORT_DESCRIPTION, Bundle.CTL_PauseAction());
    3.85 +        putValue(LONG_DESCRIPTION, Bundle.CTL_PauseAction());
    3.86 +        int initialValue = PREFS.getInt(SUSPEND_COUNT_PROPERTY, 0);
    3.87 +        synchronized (SUSPEND_COUNT_PROPERTY) {
    3.88 +            System.setProperty(SUSPEND_COUNT_PROPERTY, "" + initialValue); // NOI18N
    3.89 +        }
    3.90 +    }
    3.91 +
    3.92 +    @Override
    3.93 +    public void actionPerformed(ActionEvent e) {
    3.94 +        if (isSuspended()) {
    3.95 +            resume();
    3.96 +        } else {
    3.97 +            suspend(1);
    3.98 +        }
    3.99 +    }
   3.100 +
   3.101 +    @Override
   3.102 +    public Component getToolbarPresenter() {
   3.103 +        final AbstractButton suspendIOButton = new JToggleButton();
   3.104 +        Actions.connect(suspendIOButton, this);
   3.105 +        updateButton(suspendIOButton);
   3.106 +        final class Controller implements Runnable, ActionListener {
   3.107 +            private RequestProcessor.Task updateTask;
   3.108 +            
   3.109 +            Controller() {
   3.110 +                updateTask = RP.create(this);
   3.111 +                scheduleUpdate(0);
   3.112 +            }
   3.113 +            
   3.114 +            @Override
   3.115 +            public void run() {
   3.116 +                if (!EventQueue.isDispatchThread()) {
   3.117 +                    EventQueue.invokeLater(this);
   3.118 +                    return;
   3.119 +                }
   3.120 +                if (!suspendIOButton.isShowing()) {
   3.121 +                    return;
   3.122 +                }
   3.123 +                updateButton(suspendIOButton);
   3.124 +                scheduleUpdate(0);
   3.125 +            }
   3.126 +
   3.127 +            @Override
   3.128 +            public void actionPerformed(ActionEvent e) {
   3.129 +                updateButton(suspendIOButton);
   3.130 +                run();
   3.131 +                scheduleUpdate(100);
   3.132 +            }
   3.133 +
   3.134 +            private void scheduleUpdate(int time) {
   3.135 +                if (time == 0) {
   3.136 +                    time = 1500;
   3.137 +                }
   3.138 +                updateTask.schedule(time);
   3.139 +            }
   3.140 +        }
   3.141 +        Controller c = new Controller();
   3.142 +        suspendIOButton.addActionListener(c);
   3.143 +        
   3.144 +        return suspendIOButton;
   3.145 +    }
   3.146 +    
   3.147 +    static final void updateButton(AbstractButton btnResume) {
   3.148 +        if (isSuspended()) {
   3.149 +            int pending = Integer.getInteger("org.netbeans.io.pending", 0); // NOI18N
   3.150 +            btnResume.setText(Bundle.MSG_Resume(pending));
   3.151 +            btnResume.setSelected(true);
   3.152 +        } else {
   3.153 +            btnResume.setText(null);
   3.154 +            btnResume.setSelected(false);
   3.155 +        }
   3.156 +    }
   3.157 +
   3.158 +    static boolean isSuspended() {
   3.159 +        return Integer.getInteger(SUSPEND_COUNT_PROPERTY, 0) > 0;
   3.160 +    }
   3.161 +
   3.162 +    static void suspend(int delta) {
   3.163 +        int prev;
   3.164 +        synchronized (SUSPEND_COUNT_PROPERTY) {
   3.165 +            prev = Integer.getInteger(SUSPEND_COUNT_PROPERTY, 0);
   3.166 +            prev += delta;
   3.167 +            System.setProperty(SUSPEND_COUNT_PROPERTY, "" + prev);
   3.168 +            SUSPEND_COUNT_PROPERTY.notifyAll();
   3.169 +        }
   3.170 +        PREFS.putInt(SUSPEND_COUNT_PROPERTY, prev);
   3.171 +    }
   3.172 +
   3.173 +    static void resume() {
   3.174 +        synchronized (SUSPEND_COUNT_PROPERTY) {
   3.175 +            System.setProperty(SUSPEND_COUNT_PROPERTY, "" + 0);
   3.176 +            SUSPEND_COUNT_PROPERTY.notifyAll();
   3.177 +        }
   3.178 +        PREFS.putInt(SUSPEND_COUNT_PROPERTY, 0);
   3.179 +    }
   3.180 +}
     4.1 Binary file masterfs.ui/src/org/netbeans/modules/masterfs/ui/suspend/pause.png has changed
     5.1 Binary file masterfs.ui/src/org/netbeans/modules/masterfs/ui/suspend/pause24.png has changed