From 905d68cf289221e7d5b8875d5f862fd35a3a2e60 Mon Sep 17 00:00:00 2001 From: Vladlen Date: Thu, 1 Oct 2026 11:10:50 +0200 Subject: [PATCH 1/5] Added exit confirmation windows --- .../defaults/mf-layer-eclipse-keybinding.xml | 2 +- .../netbeans/modules/defaults/mf-layer.xml | 2 +- .../src/org/netbeans/core/Bundle.properties | 6 +++++ .../src/org/netbeans/core/ExitDialog.java | 23 +++++++++++++++++-- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/ide/defaults/src/org/netbeans/modules/defaults/mf-layer-eclipse-keybinding.xml b/ide/defaults/src/org/netbeans/modules/defaults/mf-layer-eclipse-keybinding.xml index f6f9f7f8f4db..9bf78dd2b08c 100644 --- a/ide/defaults/src/org/netbeans/modules/defaults/mf-layer-eclipse-keybinding.xml +++ b/ide/defaults/src/org/netbeans/modules/defaults/mf-layer-eclipse-keybinding.xml @@ -153,7 +153,7 @@ - + diff --git a/ide/defaults/src/org/netbeans/modules/defaults/mf-layer.xml b/ide/defaults/src/org/netbeans/modules/defaults/mf-layer.xml index cc62b71a7224..1f4554c898c5 100644 --- a/ide/defaults/src/org/netbeans/modules/defaults/mf-layer.xml +++ b/ide/defaults/src/org/netbeans/modules/defaults/mf-layer.xml @@ -947,7 +947,7 @@ - + diff --git a/platform/o.n.core/src/org/netbeans/core/Bundle.properties b/platform/o.n.core/src/org/netbeans/core/Bundle.properties index 18db39811fee..539d2e010b4d 100644 --- a/platform/o.n.core/src/org/netbeans/core/Bundle.properties +++ b/platform/o.n.core/src/org/netbeans/core/Bundle.properties @@ -49,6 +49,12 @@ MSG_AllSaved=Save All finished. CTL_Cannot_save=Cannot save {0} +# Exit confirmation shown when there are no open files with unsaved changes +TTL_ExitConfirmation=Exit NetBeans +MSG_ExitConfirmation=Do you want to exit NetBeans? +CTL_ExitConfirmationExit=Exit +CTL_ExitConfirmationSaveAll=Save All and Exit +CTL_ExitConfirmationCancel=Cancel #NbAuthenticator CTL_PasswordProtected=Password Protected Site diff --git a/platform/o.n.core/src/org/netbeans/core/ExitDialog.java b/platform/o.n.core/src/org/netbeans/core/ExitDialog.java index 3c09c2f0ccde..6e840bd6a6e9 100644 --- a/platform/o.n.core/src/org/netbeans/core/ExitDialog.java +++ b/platform/o.n.core/src/org/netbeans/core/ExitDialog.java @@ -39,6 +39,8 @@ import javax.swing.border.LineBorder; import org.netbeans.api.actions.Savable; import org.openide.DialogDescriptor; +import org.openide.DialogDisplayer; +import org.openide.LifecycleManager; import org.openide.NotifyDescriptor; import org.openide.awt.Mnemonics; import org.openide.nodes.Node; @@ -252,8 +254,25 @@ private static boolean innerShowDialog() { return result; } - else - return true; + + else { + ResourceBundle bundle = NbBundle.getBundle(ExitDialog.class); + Object exit = bundle.getString("CTL_ExitConfirmationExit"); + Object saveAndExit = bundle.getString("CTL_ExitConfirmationSaveAll"); + Object cancel = bundle.getString("CTL_ExitConfirmationCancel"); + NotifyDescriptor descriptor = new NotifyDescriptor( + bundle.getString("MSG_ExitConfirmation"), + bundle.getString("TTL_ExitConfirmation"), + NotifyDescriptor.YES_NO_CANCEL_OPTION, + NotifyDescriptor.QUESTION_MESSAGE, + new Object[] { exit, saveAndExit, cancel }, + cancel); + Object choice = DialogDisplayer.getDefault().notify(descriptor); + if (saveAndExit.equals(choice)) { + LifecycleManager.getDefault().saveAll(); + } + return exit.equals(choice) || saveAndExit.equals(choice); + } } /** Renderer used in list box of exit dialog From c29277b7ff9583cface107f4ffb4537c85c33467 Mon Sep 17 00:00:00 2001 From: Vladlen Date: Thu, 1 Oct 2026 14:07:59 +0200 Subject: [PATCH 2/5] Added checkbox to general settings in order to turn on/off the exit dialog --- .../core/ui/options/general/Bundle.properties | 3 +++ .../ui/options/general/GeneralOptionsPanel.form | 10 ++++++++++ .../ui/options/general/GeneralOptionsPanel.java | 15 ++++++++++++++- .../src/org/netbeans/core/ExitDialog.java | 14 ++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/platform/core.ui/src/org/netbeans/core/ui/options/general/Bundle.properties b/platform/core.ui/src/org/netbeans/core/ui/options/general/Bundle.properties index 6ee765b30a9a..c1b26db18555 100644 --- a/platform/core.ui/src/org/netbeans/core/ui/options/general/Bundle.properties +++ b/platform/core.ui/src/org/netbeans/core/ui/options/general/Bundle.properties @@ -37,6 +37,9 @@ AD_Usage_Statistics=Usage Statistics CTL_Usage_Check=Hel&p us improve the NetBeans IDE by providing anonymous usage data AN_Usage_Check=Help us improve the NetBeans IDE by providing anonymous usage data AD_Usage_Check=Help us improve the NetBeans IDE by providing anonymous usage data +CTL_Exit_Confirmation=&Show confirmation when exiting with no unsaved files +AN_Exit_Confirmation=Show exit confirmation +AD_Exit_Confirmation=Show a confirmation dialog when exiting with no unsaved files CTL_Usage_Info=The usage statistics help us better understand user \ requirements and prioritize improvements in future releases. We will never \ reverse-engineer the collected data to find specific details about your projects. diff --git a/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.form b/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.form index a589573aa14b..86cbb73ecc0d 100644 --- a/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.form +++ b/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.form @@ -103,6 +103,7 @@ + @@ -152,6 +153,8 @@ + + @@ -350,6 +353,13 @@ + + + + + + + diff --git a/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.java b/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.java index 363cc72ba22b..7f89ca3c0f86 100644 --- a/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.java +++ b/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.java @@ -39,6 +39,7 @@ import javax.swing.event.DocumentListener; import org.netbeans.api.options.OptionsDisplayer; import org.netbeans.beaninfo.editors.HtmlBrowser; +import org.netbeans.core.ExitDialog; import org.netbeans.core.ProxySettings; import org.netbeans.spi.options.OptionsPanelController; import org.openide.DialogDescriptor; @@ -127,6 +128,7 @@ public void changedUpdate(DocumentEvent e) { loc (rbNoProxy, "No_Proxy"); loc (rbUseSystemProxy, "Use_System_Proxy_Settings"); loc (rbHTTPProxy, "Use_HTTP_Proxy"); + loc (cbExitConfirmation, "Exit_Confirmation"); loc (lUsage, "Usage_Statistics"); lUsage.getAccessibleContext ().setAccessibleDescription (loc ("AD_Usage_Statistics")); @@ -186,6 +188,7 @@ private void initComponents() { lblLearnMore = new javax.swing.JLabel(); lblUsageInfo = new javax.swing.JLabel(); jUsageCheck = new javax.swing.JCheckBox(); + cbExitConfirmation = new javax.swing.JCheckBox(); lUsage = new javax.swing.JLabel(); bReloadProxy = new javax.swing.JButton(); bTestConnection = new javax.swing.JButton(); @@ -291,6 +294,7 @@ public void mousePressed(java.awt.event.MouseEvent evt) { gridBagConstraints.insets = new java.awt.Insets(0, 15, 5, 0); jPanel1.add(jUsageCheck, gridBagConstraints); + org.openide.awt.Mnemonics.setLocalizedText(cbExitConfirmation, org.openide.util.NbBundle.getMessage(GeneralOptionsPanel.class, "CTL_Exit_Confirmation")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(lUsage, "Usage Statistics:"); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; @@ -373,7 +377,8 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addComponent(jSeparator3, javax.swing.GroupLayout.DEFAULT_SIZE, 1495, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addContainerGap()))) + .addContainerGap()) + .addComponent(cbExitConfirmation, javax.swing.GroupLayout.Alignment.LEADING))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -413,6 +418,8 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cbExitConfirmation) .addContainerGap()) ); @@ -535,6 +542,7 @@ private void bTestConnectionActionPerformed(java.awt.event.ActionEvent evt) {//G private javax.swing.JButton bReloadProxy; private javax.swing.JButton bTestConnection; private javax.swing.JComboBox cbWebBrowser; + private javax.swing.JCheckBox cbExitConfirmation; private javax.swing.JButton editBrowserButton; private javax.swing.JLabel errorLabel; private javax.swing.JPanel jPanel1; @@ -684,6 +692,7 @@ void update () { rbUseSystemProxy.setToolTipText (getUseSystemProxyToolTip ()); jUsageCheck.setSelected(model.getUsageStatistics()); + cbExitConfirmation.setSelected(ExitDialog.isExitConfirmationEnabled()); updateWebBrowsers(); } @@ -761,6 +770,7 @@ void applyChanges () { editor.setAsText ((String) cbWebBrowser.getSelectedItem ()); model.setUsageStatistics(jUsageCheck.isSelected()); + ExitDialog.setExitConfirmationEnabled(cbExitConfirmation.isSelected()); } void cancel () { @@ -774,6 +784,9 @@ boolean isChanged () { if (model == null) { return false; } + if (cbExitConfirmation.isSelected() != ExitDialog.isExitConfirmationEnabled()) { + return true; + } // web browser settings if (editor == null) { editor = Lookup.getDefault().lookup(HtmlBrowser.FactoryEditor.class); diff --git a/platform/o.n.core/src/org/netbeans/core/ExitDialog.java b/platform/o.n.core/src/org/netbeans/core/ExitDialog.java index 6e840bd6a6e9..052adffe03b8 100644 --- a/platform/o.n.core/src/org/netbeans/core/ExitDialog.java +++ b/platform/o.n.core/src/org/netbeans/core/ExitDialog.java @@ -55,6 +55,7 @@ */ public class ExitDialog extends JPanel implements java.awt.event.ActionListener { + private static final String CONFIRM_EXIT_PREFERENCE = "confirmExit"; // NOI18N private static final boolean isAqua = "Aqua".equals(UIManager.getLookAndFeel().getID()); private static Object[] exitOptions; @@ -199,6 +200,16 @@ public static boolean showDialog() { return innerShowDialog(); } + public static boolean isExitConfirmationEnabled() { + return org.openide.util.NbPreferences.forModule(ExitDialog.class) + .getBoolean(CONFIRM_EXIT_PREFERENCE, true); + } + + public static void setExitConfirmationEnabled(boolean enabled) { + org.openide.util.NbPreferences.forModule(ExitDialog.class) + .putBoolean(CONFIRM_EXIT_PREFERENCE, enabled); + } + /** * Opens the ExitDialog. */ @@ -256,6 +267,9 @@ private static boolean innerShowDialog() { } else { + if (!isExitConfirmationEnabled()) { + return true; + } ResourceBundle bundle = NbBundle.getBundle(ExitDialog.class); Object exit = bundle.getString("CTL_ExitConfirmationExit"); Object saveAndExit = bundle.getString("CTL_ExitConfirmationSaveAll"); From 726f2290cc1162a9e5bad41ace92a6c18d901de5 Mon Sep 17 00:00:00 2001 From: Vladlen Date: Fri, 2 Oct 2026 13:09:40 +0200 Subject: [PATCH 3/5] Removed "Save All and Exit" button --- .../o.n.core/src/org/netbeans/core/Bundle.properties | 1 - .../o.n.core/src/org/netbeans/core/ExitDialog.java | 11 +++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/platform/o.n.core/src/org/netbeans/core/Bundle.properties b/platform/o.n.core/src/org/netbeans/core/Bundle.properties index 539d2e010b4d..9cb88ceb097b 100644 --- a/platform/o.n.core/src/org/netbeans/core/Bundle.properties +++ b/platform/o.n.core/src/org/netbeans/core/Bundle.properties @@ -53,7 +53,6 @@ CTL_Cannot_save=Cannot save {0} TTL_ExitConfirmation=Exit NetBeans MSG_ExitConfirmation=Do you want to exit NetBeans? CTL_ExitConfirmationExit=Exit -CTL_ExitConfirmationSaveAll=Save All and Exit CTL_ExitConfirmationCancel=Cancel #NbAuthenticator diff --git a/platform/o.n.core/src/org/netbeans/core/ExitDialog.java b/platform/o.n.core/src/org/netbeans/core/ExitDialog.java index 052adffe03b8..fe3d57624260 100644 --- a/platform/o.n.core/src/org/netbeans/core/ExitDialog.java +++ b/platform/o.n.core/src/org/netbeans/core/ExitDialog.java @@ -40,7 +40,6 @@ import org.netbeans.api.actions.Savable; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; -import org.openide.LifecycleManager; import org.openide.NotifyDescriptor; import org.openide.awt.Mnemonics; import org.openide.nodes.Node; @@ -272,20 +271,16 @@ private static boolean innerShowDialog() { } ResourceBundle bundle = NbBundle.getBundle(ExitDialog.class); Object exit = bundle.getString("CTL_ExitConfirmationExit"); - Object saveAndExit = bundle.getString("CTL_ExitConfirmationSaveAll"); Object cancel = bundle.getString("CTL_ExitConfirmationCancel"); NotifyDescriptor descriptor = new NotifyDescriptor( bundle.getString("MSG_ExitConfirmation"), bundle.getString("TTL_ExitConfirmation"), - NotifyDescriptor.YES_NO_CANCEL_OPTION, + NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.QUESTION_MESSAGE, - new Object[] { exit, saveAndExit, cancel }, + new Object[] { exit, cancel }, cancel); Object choice = DialogDisplayer.getDefault().notify(descriptor); - if (saveAndExit.equals(choice)) { - LifecycleManager.getDefault().saveAll(); - } - return exit.equals(choice) || saveAndExit.equals(choice); + return exit.equals(choice); } } From c2209a16bea257fd13eca8d594da409157f85210 Mon Sep 17 00:00:00 2001 From: Vladlen Date: Fri, 2 Oct 2026 13:26:12 +0200 Subject: [PATCH 4/5] Reverted mf-layer.xml and mf-layer-eclipse-keybinding.xml for PR --- .../netbeans/modules/defaults/mf-layer-eclipse-keybinding.xml | 2 +- ide/defaults/src/org/netbeans/modules/defaults/mf-layer.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ide/defaults/src/org/netbeans/modules/defaults/mf-layer-eclipse-keybinding.xml b/ide/defaults/src/org/netbeans/modules/defaults/mf-layer-eclipse-keybinding.xml index 9bf78dd2b08c..f6f9f7f8f4db 100644 --- a/ide/defaults/src/org/netbeans/modules/defaults/mf-layer-eclipse-keybinding.xml +++ b/ide/defaults/src/org/netbeans/modules/defaults/mf-layer-eclipse-keybinding.xml @@ -153,7 +153,7 @@ - + diff --git a/ide/defaults/src/org/netbeans/modules/defaults/mf-layer.xml b/ide/defaults/src/org/netbeans/modules/defaults/mf-layer.xml index 1f4554c898c5..cc62b71a7224 100644 --- a/ide/defaults/src/org/netbeans/modules/defaults/mf-layer.xml +++ b/ide/defaults/src/org/netbeans/modules/defaults/mf-layer.xml @@ -947,7 +947,7 @@ - + From 332d5b5db0d05d481c071792b773962da37ca558 Mon Sep 17 00:00:00 2001 From: Vladlen Date: Fri, 2 Oct 2026 13:35:48 +0200 Subject: [PATCH 5/5] Changed "NetBeans" in exit window to more generic one for PR --- platform/o.n.core/src/org/netbeans/core/Bundle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/o.n.core/src/org/netbeans/core/Bundle.properties b/platform/o.n.core/src/org/netbeans/core/Bundle.properties index 9cb88ceb097b..bd88107cbb4c 100644 --- a/platform/o.n.core/src/org/netbeans/core/Bundle.properties +++ b/platform/o.n.core/src/org/netbeans/core/Bundle.properties @@ -50,8 +50,8 @@ MSG_AllSaved=Save All finished. CTL_Cannot_save=Cannot save {0} # Exit confirmation shown when there are no open files with unsaved changes -TTL_ExitConfirmation=Exit NetBeans -MSG_ExitConfirmation=Do you want to exit NetBeans? +TTL_ExitConfirmation=Exit IDE +MSG_ExitConfirmation=Do you want to exit the IDE? CTL_ExitConfirmationExit=Exit CTL_ExitConfirmationCancel=Cancel