[#1100] Fix menu bar when app is idle for macOS
This commit is contained in:
parent
fa10dcd019
commit
919d89dd20
@ -61,6 +61,7 @@ import net.sf.openrocket.gui.help.tours.GuidedTourSelectionDialog;
|
||||
import net.sf.openrocket.gui.main.componenttree.ComponentTree;
|
||||
import net.sf.openrocket.gui.main.flightconfigpanel.FlightConfigurationPanel;
|
||||
import net.sf.openrocket.gui.scalefigure.RocketPanel;
|
||||
import net.sf.openrocket.gui.util.DummyFrameMenuOSX;
|
||||
import net.sf.openrocket.gui.util.FileHelper;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.gui.util.Icons;
|
||||
@ -100,9 +101,9 @@ public class BasicFrame extends JFrame {
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
private static final Preferences prefs = Application.getPreferences();
|
||||
|
||||
private static final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();
|
||||
public static final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();
|
||||
|
||||
private static final int SHIFT_SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() |
|
||||
public static final int SHIFT_SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() |
|
||||
SHIFT_DOWN_MASK;
|
||||
|
||||
public static final int COMPONENT_TAB = 0;
|
||||
@ -1189,6 +1190,10 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
|
||||
private void openAction() {
|
||||
openAction(this);
|
||||
}
|
||||
|
||||
public static void openAction(Window parent) {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
|
||||
chooser.addChoosableFileFilter(FileHelper.ALL_DESIGNS_FILTER);
|
||||
@ -1198,7 +1203,7 @@ public class BasicFrame extends JFrame {
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
chooser.setMultiSelectionEnabled(true);
|
||||
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
||||
int option = chooser.showOpenDialog(this);
|
||||
int option = chooser.showOpenDialog(parent);
|
||||
if (option != JFileChooser.APPROVE_OPTION) {
|
||||
log.info(Markers.USER_MARKER, "Decided not to open files, option=" + option);
|
||||
return;
|
||||
@ -1211,7 +1216,7 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
for (File file : files) {
|
||||
log.info("Opening file: " + file);
|
||||
if (open(file, this)) {
|
||||
if (open(file, parent)) {
|
||||
MRUDesignFile opts = MRUDesignFile.getInstance();
|
||||
opts.addFile(file.getAbsolutePath());
|
||||
}
|
||||
@ -1688,10 +1693,14 @@ public class BasicFrame extends JFrame {
|
||||
ComponentAnalysisDialog.hideDialog();
|
||||
|
||||
frames.remove(this);
|
||||
// Don't quit the application on macOS
|
||||
if (frames.isEmpty() && (SystemInfo.getPlatform() != SystemInfo.Platform.MAC_OS)) {
|
||||
log.info("Last frame closed, exiting");
|
||||
System.exit(0);
|
||||
if (frames.isEmpty()) {
|
||||
// Don't quit the application on macOS, but keep the application open
|
||||
if (SystemInfo.getPlatform() == SystemInfo.Platform.MAC_OS) {
|
||||
DummyFrameMenuOSX.createDummyDialog();
|
||||
} else {
|
||||
log.info("Last frame closed, exiting");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1803,6 +1812,14 @@ public class BasicFrame extends JFrame {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether all the BasicFrames are closed.
|
||||
* @return true if all the BasicFrames are closed, false if not
|
||||
*/
|
||||
public static boolean isFramesEmpty() {
|
||||
return frames.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a currently open document by the rocket object. This method can be used
|
||||
* to map a Rocket to OpenRocketDocument from GUI methods.
|
||||
|
185
swing/src/net/sf/openrocket/gui/util/DummyFrameMenuOSX.java
Normal file
185
swing/src/net/sf/openrocket/gui/util/DummyFrameMenuOSX.java
Normal file
@ -0,0 +1,185 @@
|
||||
package net.sf.openrocket.gui.util;
|
||||
|
||||
import net.sf.openrocket.gui.dialogs.AboutDialog;
|
||||
import net.sf.openrocket.gui.dialogs.LicenseDialog;
|
||||
import net.sf.openrocket.gui.help.tours.GuidedTourSelectionDialog;
|
||||
import net.sf.openrocket.gui.main.BasicFrame;
|
||||
import net.sf.openrocket.gui.main.ExampleDesignFileAction;
|
||||
import net.sf.openrocket.gui.main.MRUDesignFileAction;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.logging.Markers;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.KeyStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
/**
|
||||
* This dummy frame will be generated when all design windows are close on macOS.
|
||||
* It serves to maintain and customize the application menu bar when all the BasicFrame windows are closed.
|
||||
*
|
||||
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
|
||||
*/
|
||||
public class DummyFrameMenuOSX extends JFrame {
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
private static final Logger log = LoggerFactory.getLogger(BasicFrame.class);
|
||||
|
||||
private static DummyFrameMenuOSX dialog;
|
||||
|
||||
private DummyFrameMenuOSX() {
|
||||
createMenu();
|
||||
setUndecorated(true);
|
||||
setBackground(new Color(0, 0, 0, 0));
|
||||
setVisible(true); // this is needed to show the menu bar
|
||||
}
|
||||
|
||||
public static DummyFrameMenuOSX createDummyDialog() {
|
||||
dialog = new DummyFrameMenuOSX();
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static DummyFrameMenuOSX getDummyDialog() {
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static void removeDummyDialog() {
|
||||
if (dialog != null) {
|
||||
dialog.dispose();
|
||||
dialog = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void createMenu() {
|
||||
JMenuBar menubar = new JMenuBar();
|
||||
JMenu menu;
|
||||
JMenuItem item;
|
||||
|
||||
//// File
|
||||
menu = new JMenu(trans.get("main.menu.file"));
|
||||
menu.setMnemonic(KeyEvent.VK_F);
|
||||
//// File-handling related tasks
|
||||
menu.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.desc"));
|
||||
menubar.add(menu);
|
||||
|
||||
//// New
|
||||
item = new JMenuItem(trans.get("main.menu.file.new"), KeyEvent.VK_N);
|
||||
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, BasicFrame.SHORTCUT_KEY));
|
||||
item.setMnemonic(KeyEvent.VK_N);
|
||||
//// Create a new rocket design
|
||||
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.new.desc"));
|
||||
item.setIcon(Icons.FILE_NEW);
|
||||
item.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
DummyFrameMenuOSX.removeDummyDialog();
|
||||
log.info(Markers.USER_MARKER, "New... selected");
|
||||
BasicFrame.newAction();
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
//// Open...
|
||||
item = new JMenuItem(trans.get("main.menu.file.open"), KeyEvent.VK_O);
|
||||
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, BasicFrame.SHORTCUT_KEY));
|
||||
//// Open a rocket design
|
||||
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.open.desc"));
|
||||
item.setIcon(Icons.FILE_OPEN);
|
||||
item.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
DummyFrameMenuOSX.removeDummyDialog();
|
||||
log.info(Markers.USER_MARKER, "Open... selected");
|
||||
BasicFrame.openAction(DummyFrameMenuOSX.this);
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
//// Open Recent...
|
||||
item = new MRUDesignFileAction(trans.get("main.menu.file.openRecent"), this);
|
||||
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.openRecent.desc"));
|
||||
item.setIcon(Icons.FILE_OPEN);
|
||||
menu.add(item);
|
||||
|
||||
//// Open example...
|
||||
item = new ExampleDesignFileAction(trans.get("main.menu.file.openExample"), null);
|
||||
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.openExample.desc"));
|
||||
item.setIcon(Icons.FILE_OPEN_EXAMPLE);
|
||||
menu.add(item);
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
//// Quit
|
||||
item = new JMenuItem(trans.get("main.menu.file.quit"), KeyEvent.VK_Q);
|
||||
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, BasicFrame.SHORTCUT_KEY));
|
||||
//// Quit the program
|
||||
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.quit.desc"));
|
||||
item.setIcon(Icons.FILE_QUIT);
|
||||
item.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
log.info(Markers.USER_MARKER, "Quit selected");
|
||||
BasicFrame.quitAction();
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
|
||||
//// Help
|
||||
menu = new JMenu(trans.get("main.menu.help"));
|
||||
menu.setMnemonic(KeyEvent.VK_H);
|
||||
menu.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.help.desc"));
|
||||
menubar.add(menu);
|
||||
|
||||
//// Guided tours
|
||||
item = new JMenuItem(trans.get("main.menu.help.tours"), KeyEvent.VK_L);
|
||||
item.setIcon(Icons.HELP_TOURS);
|
||||
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.help.tours.desc"));
|
||||
item.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
log.info(Markers.USER_MARKER, "Guided tours selected");
|
||||
GuidedTourSelectionDialog.showDialog(DummyFrameMenuOSX.this);
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
//// License
|
||||
item = new JMenuItem(trans.get("main.menu.help.license"), KeyEvent.VK_L);
|
||||
item.setIcon(Icons.HELP_LICENSE);
|
||||
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.help.license.desc"));
|
||||
item.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
log.info(Markers.USER_MARKER, "License selected");
|
||||
new LicenseDialog(DummyFrameMenuOSX.this).setVisible(true);
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
//// About
|
||||
item = new JMenuItem(trans.get("main.menu.help.about"), KeyEvent.VK_A);
|
||||
item.setIcon(Icons.HELP_ABOUT);
|
||||
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.help.about.desc"));
|
||||
item.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
log.info(Markers.USER_MARKER, "About selected");
|
||||
new AboutDialog(DummyFrameMenuOSX.this).setVisible(true);
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
|
||||
this.setJMenuBar(menubar);
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ import java.awt.desktop.PreferencesHandler;
|
||||
import java.awt.desktop.QuitHandler;
|
||||
import java.awt.desktop.AppReopenedListener;
|
||||
|
||||
import net.sf.openrocket.gui.util.DummyFrameMenuOSX;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -52,8 +53,10 @@ final class OSXSetup {
|
||||
};
|
||||
|
||||
private static final AppReopenedListener APP_REOPENED_HANDLER = (e) -> {
|
||||
log.info("App re-opened");
|
||||
BasicFrame.reopen();
|
||||
if (BasicFrame.isFramesEmpty()) {
|
||||
log.info("App re-opened");
|
||||
BasicFrame.reopen();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user