# HG changeset patch # Parent 5c234cebc6044f7a7373ac8ff77e53f07362bc1d Bug #223810 - org.netbeans.modules.cnd.utils.ui.ModalMessageDlg.runLongTaskImpl: LowPerformance took 6612 ms. diff --git a/cnd.utils/nbproject/project.xml b/cnd.utils/nbproject/project.xml --- a/cnd.utils/nbproject/project.xml +++ b/cnd.utils/nbproject/project.xml @@ -6,6 +6,15 @@ org.netbeans.modules.cnd.utils + org.netbeans.api.progress + + + + 1 + 1.32 + + + org.netbeans.modules.dlight.libs.common diff --git a/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlg.java b/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlg.java --- a/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlg.java +++ b/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlg.java @@ -44,231 +44,206 @@ package org.netbeans.modules.cnd.utils.ui; import java.awt.Dialog; -import java.awt.Dimension; import java.awt.Frame; -import java.awt.Rectangle; -import java.awt.Toolkit; import java.awt.Window; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; -import javax.swing.JDialog; -import javax.swing.JPanel; import javax.swing.SwingUtilities; +import org.netbeans.api.progress.ProgressHandle; +import org.netbeans.api.progress.ProgressRunnable; +import org.netbeans.api.progress.ProgressUtils; import org.netbeans.modules.cnd.utils.CndUtils; import org.netbeans.modules.cnd.utils.NamedRunnable; import org.openide.util.Cancellable; +import org.openide.util.Exceptions; import org.openide.util.RequestProcessor; -import org.openide.util.RequestProcessor.Task; /** + * Utility class for displaying a modal Dialog (effectively blocking (but not + * freezing) UI) while running a task in background. + * + * Current implementation uses org.netbeans.api.progress.ProgressUtils. + * + * @Deprecated - Use org.netbeans.api.progress.ProgressUtils. * * @author Vladimir Voskresensky */ -public class ModalMessageDlg extends javax.swing.JPanel { - private static final RequestProcessor RP = new RequestProcessor(ModalMessageDlg.class.getName(), 4); +@Deprecated +public final class ModalMessageDlg { - /** - * allows to display modal dialog with title and message for the period of - * long task run - * @param parent parent frame or dialog - * @param workTask non EDT task to run - * @param postEDTTask EDT task to run after closing modal dialog (can be null) - * @param title title of dialog - * @param message message in dialog - * @return - */ - public static void runLongTask(Dialog parent, - final Runnable workTask, final Runnable postEDTTask, final Cancellable canceller, - String title, String message) { - runLongTaskImpl(parent, workTask, postEDTTask, title, message, canceller); + public interface LongWorker { + + void doWork(); + + void doPostRunInEDT(); } - public static void runLongTask(Frame parent, - final Runnable workTask, final Runnable postEDTTask, final Cancellable canceller, - String title, String message) { - runLongTaskImpl(parent, workTask, postEDTTask, title, message, canceller); + private ModalMessageDlg() { } /** + * Show a modal progress dialog that blocks the main window, while running + * the passed runnable on a background thread. * - * @param parent - * @param title - * @param message - * @param workTask if workTask is Cancellable => dialog will have Cancel button - * if not => no Cancel button is shown + *

This method is thread-safe, and will block until the operation has + * completed, regardless of what thread calls this method.

+ * + * @param parent Not used + * @param workTask a Runnable to start in non-EDT thread. Unlike + * {@link ProgressUtils}'s operation this argument is never tested for the + * {@link Cancellable} interface. Use canceller for the task + * interruption facility. + * @param postEDTTask a task to run in the EDT after the workTask is + * processed. null is allowed. NB: The postEDTTask is + * called either if this method is invoked from tests or if workTask + * was not cancelled by pressing the cancel button. + * @param canceller if not null a cancel button is displayed + * while workTask is running.
Note that once the cancel button + * is pressed, no postEDTTask will be called. + * @param title title of a dialog. If message is not null, + * title is not used. + * @param message message to display. Could be null. In this + * case title is used. + * */ - public static void runLongTask(Window parent, String title, String message, + public static void runLongTask(Dialog parent, final Runnable workTask, + final Runnable postEDTTask, final Cancellable canceller, + String title, String message) { + run(workTask, postEDTTask, canceller, title, message); + } + + /** + * Show a modal progress dialog that blocks the main window, while running + * the passed runnable on a background thread. + * + * @see #runLongTask(Dialog, Runnable, Runnable, Cancellable, String, + * String) + */ + public static void runLongTask(final Frame parent, final Runnable workTask, + final Runnable postEDTTask, final Cancellable canceller, + String title, String message) { + run(workTask, postEDTTask, canceller, title, message); + } + + /** + * Show a modal progress dialog that blocks the main window, while running + * the passed runnable on a background thread. + * + *

This is almost the same as runLongTask(Dialog, Runnable, Runnable, + * Cancellable, String, String), but has one significant difference!

+ * + *

Not only it uses a {@link LongWorker} instead of two + * {@link Runnable}s, but also the {@link LongWorker#doPostRunInEDT()} is + * invoked disregarding the cancellation status.

+ * + * @see #runLongTask(Dialog, Runnable, Runnable, Cancellable, String, + * String) + */ + public static void runLongTask(final Window parent, final String title, final String message, final LongWorker workTask, final Cancellable canceller) { - final JDialog dialog = createDialog(parent, title); - - final Runnable finalizer = new Runnable() { + run(new Runnable() { @Override public void run() { - // hide dialog and run action if successfully connected - dialog.setVisible(false); - dialog.dispose(); + workTask.doWork(); + } + }, null, canceller, title, message); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { workTask.doPostRunInEDT(); } - }; + }); + } - JPanel panel; - if (canceller == null) { - panel = new ModalMessageDlgPane(message); + private static void run(final Runnable workTask, final Runnable postEDTTask, + final Cancellable canceller, final String title, String message) { + + if (invokedFromTests()) { + // The code below is just to preserve the behaviour as it was + // before switchig to the ProgressUtils... + Future task = RequestProcessor.getDefault().submit(new NamedRunnable(title) { + @Override + protected void runImpl() { + workTask.run(); + } + }); + try { + task.get(); + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); + } catch (ExecutionException ex) { + Exceptions.printStackTrace(ex); + } + if (postEDTTask != null) { + SwingUtilities.invokeLater(postEDTTask); + } } else { - Cancellable wrapper = new Cancellable() { - /** is invoked from a separate cancellation thread */ - @Override - public boolean cancel() { - if (canceller.cancel()) { - // remember for return value - return true; - } else { - return false; - } - } - }; - panel = new ModalMessageDlgCancellablePane(message, wrapper); - } - addPanel(parent, dialog, panel); + final MyRP r; - RP.post(new NamedRunnable(title) { - @Override - public void runImpl() { - try { - workTask.doWork(); - } finally { - SwingUtilities.invokeLater(finalizer); - } + if (canceller != null) { + r = new MyCRP(workTask, canceller, message); + } else { + r = new MyRP(workTask, message); } - }); - if (!CndUtils.isStandalone()) { // this means we run in tests - dialog.setVisible(true); + + ProgressUtils.showProgressDialogAndRun(r, title, true); + + if (postEDTTask != null && !r.wasCancelled()) { + SwingUtilities.invokeLater(workTask); + } } } - private static boolean runLongTaskImpl(Window parent, final Runnable workTask, final Runnable postEDTTask, - final String title, String message, final Cancellable canceller) { - - final JDialog dialog = createDialog(parent, title); - final AtomicBoolean cancelled = new AtomicBoolean(false); - - final Runnable finalizer = new Runnable() { - @Override - public void run() { - // hide dialog and run action if successfully connected - dialog.setVisible(false); - dialog.dispose(); - if (postEDTTask != null && ! cancelled.get()) { - postEDTTask.run(); - } - } - }; - - JPanel panel; - if (canceller == null) { - panel = new ModalMessageDlgPane(message); - } else { - Cancellable wrapper = new Cancellable() { - /** is invoked from a separate cancellation thread */ - @Override - public boolean cancel() { - if (canceller.cancel()) { - cancelled.set(true); - SwingUtilities.invokeLater(finalizer); - return true; - } else { - return false; - } - } - }; - panel = new ModalMessageDlgCancellablePane(message, wrapper); - } - addPanel(parent, dialog, panel); - - final WindowAdapterImpl windowAdapterImpl = new WindowAdapterImpl(dialog, title, workTask, finalizer); - - if (CndUtils.isStandalone()) { // this means we run in tests - Task task = windowAdapterImpl.submitJob(); - task.waitFinished(); - } else { - dialog.addWindowListener(windowAdapterImpl); - dialog.setVisible(true); - } - - return !cancelled.get(); + private static boolean invokedFromTests() { + return CndUtils.isStandalone(); } - private static JDialog createDialog(Window parent, String title) { - JDialog dialog; - if (parent == null) { - dialog = new JDialog(); - } else if (parent instanceof Frame) { - dialog = new JDialog((Frame)parent); - } else { - assert (parent instanceof Dialog); - dialog = new JDialog((Dialog)parent); - } - dialog.setTitle(title); - dialog.setModal(true); - return dialog; - } + private static class MyRP implements ProgressRunnable { - private static void addPanel(Window parent, JDialog dialog, JPanel panel){ - dialog.getContentPane().add(panel); - dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); //make sure the dialog is not closed during the project open - dialog.pack(); + private final Runnable task; + private final String message; - Rectangle bounds = (parent == null) ? - new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()) : parent.getBounds(); - - int middleX = bounds.x + bounds.width / 2; - int middleY = bounds.y + bounds.height / 2; - - Dimension size = dialog.getPreferredSize(); - - dialog.setBounds(middleX - size.width / 2, middleY - size.height / 2, size.width, size.height); - } - - public interface LongWorker { - void doWork(); - void doPostRunInEDT(); - } - - private static class WindowAdapterImpl extends WindowAdapter { - - private final String title; - private final Runnable workTask; - private final Runnable finalizer; - private final JDialog dialog; - - public WindowAdapterImpl(JDialog dialog, String title, Runnable workTask, Runnable finalizer) { - this.title = title; - this.workTask = workTask; - this.finalizer = finalizer; - this.dialog = dialog; + public MyRP(final Runnable task, final String message) { + this.task = task; + this.message = message; } @Override - public void windowOpened(WindowEvent e) { - dialog.removeWindowListener(this); - submitJob(); + public Void run(final ProgressHandle handle) { + if (message != null) { + handle.setDisplayName(message); + } + task.run(); + return null; } - private Task submitJob() { - Task task = RP.post(new NamedRunnable(title) { + public boolean wasCancelled() { + return false; + } + } - @Override - public void runImpl() { - try { - workTask.run(); - } finally { - SwingUtilities.invokeLater(finalizer); - } - } - }); - return task; + private static class MyCRP extends MyRP implements Cancellable { + + private final Cancellable canceller; + private final AtomicBoolean wasCancelled = new AtomicBoolean(false); + + public MyCRP(final Runnable task, final Cancellable canceller, final String message) { + super(task, message); + this.canceller = canceller; + } + + @Override + public boolean cancel() { + wasCancelled.set(true); + return canceller.cancel(); + } + + @Override + public boolean wasCancelled() { + return wasCancelled.get(); } } } diff --git a/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlgCancellablePane.form b/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlgCancellablePane.form deleted file mode 100644 --- a/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlgCancellablePane.form +++ /dev/null @@ -1,60 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlgCancellablePane.java b/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlgCancellablePane.java deleted file mode 100644 --- a/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlgCancellablePane.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2010 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]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun - * Microsystems, Inc. All Rights Reserved. - * - * 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. - */ -package org.netbeans.modules.cnd.utils.ui; - -import javax.swing.SwingUtilities; -import org.openide.util.Cancellable; -import org.openide.util.NbBundle; - -/** - * - * @author Vladimir Voskresensky - */ -/* package-local */ -class ModalMessageDlgCancellablePane extends javax.swing.JPanel { - - private final Cancellable cancellable; - private final String message; - - /** Creates new form ModalMessageDlg */ - /* package-local*/ - ModalMessageDlgCancellablePane(String message, Cancellable cancellable) { - this.cancellable = cancellable; - this.message = message; - initComponents(); - lblMessage.setText(message); - } - - /** This method is called from within the constructor to - * initialize the form. - * WARNING: Do NOT modify this code. The content of this method is - * always regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - private void initComponents() { - - lblMessage = new javax.swing.JLabel(); - btnCancel = new javax.swing.JButton(); - - btnCancel.setText(org.openide.util.NbBundle.getMessage(ModalMessageDlgCancellablePane.class, "ModalMessageDlgCancellablePane.btnCancel.text")); // NOI18N - btnCancel.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnCancelActionPerformed(evt); - } - }); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(lblMessage, javax.swing.GroupLayout.DEFAULT_SIZE, 350, Short.MAX_VALUE) - .addContainerGap()) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(btnCancel) - .addGap(136, 136, 136)))) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(20, Short.MAX_VALUE) - .addComponent(lblMessage) - .addGap(18, 18, 18) - .addComponent(btnCancel) - .addGap(6, 6, 6)) - ); - }// //GEN-END:initComponents - - private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed - lblMessage.setText(NbBundle.getMessage(getClass(), "MSG_Cancelling")); - btnCancel.setEnabled(false); - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - if (!cancellable.cancel()) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - if (ModalMessageDlgCancellablePane.this.isVisible()) { - lblMessage.setText(NbBundle.getMessage(getClass(), "MSG_CancelFailed", message)); - } - } - }); - } - } - }, ModalMessageDlg.class.getSimpleName() + " cancellation thread"); //NOI18N - thread.start(); -}//GEN-LAST:event_btnCancelActionPerformed - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton btnCancel; - private javax.swing.JLabel lblMessage; - // End of variables declaration//GEN-END:variables -} diff --git a/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlgPane.form b/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlgPane.form deleted file mode 100644 --- a/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlgPane.form +++ /dev/null @@ -1,40 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlgPane.java b/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlgPane.java deleted file mode 100644 --- a/cnd.utils/src/org/netbeans/modules/cnd/utils/ui/ModalMessageDlgPane.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2010 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]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun - * Microsystems, Inc. All Rights Reserved. - * - * 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. - */ -package org.netbeans.modules.cnd.utils.ui; - -/** - * - * @author Vladimir Voskresensky - */ -/* package-local */ -class ModalMessageDlgPane extends javax.swing.JPanel { - - /** Creates new form ModalMessageDlg */ - /* package-local*/ - ModalMessageDlgPane(String message) { - initComponents(); - lblMessage.setText(message); - } - - /** This method is called from within the constructor to - * initialize the form. - * WARNING: Do NOT modify this code. The content of this method is - * always regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - private void initComponents() { - - lblMessage = new javax.swing.JLabel(); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(lblMessage, javax.swing.GroupLayout.DEFAULT_SIZE, 350, Short.MAX_VALUE) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(28, Short.MAX_VALUE) - .addComponent(lblMessage) - .addContainerGap()) - ); - }// //GEN-END:initComponents - - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JLabel lblMessage; - // End of variables declaration//GEN-END:variables - -}