Merge pull request #1475 from SiboVG/issue-1470

[#1470] Move component config dialog to center if outside parent's monitor
This commit is contained in:
SiboVG 2022-07-14 15:14:19 +02:00 committed by GitHub
commit d78e595532
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 122 additions and 19 deletions

View File

@ -1,18 +1,24 @@
package net.sf.openrocket.gui.configdialog;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
import javax.swing.JDialog;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.main.BasicFrame;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.gui.util.WindowLocationUtil;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
@ -257,6 +263,9 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis
dialog = new ComponentConfigDialog(parent, document, component);
dialog.setVisible(true);
if (parent instanceof BasicFrame && BasicFrame.getStartupFrame() == parent) {
WindowLocationUtil.moveIfOutsideOfParentMonitor(dialog, parent);
}
////Modify
if (includeUndoModify) {

View File

@ -118,6 +118,7 @@ public class BasicFrame extends JFrame {
* it is time to exit the application.
*/
private static final ArrayList<BasicFrame> frames = new ArrayList<BasicFrame>();
private static BasicFrame startupFrame = null; // the frame that was created at startup
/**
@ -1231,6 +1232,19 @@ public class BasicFrame extends JFrame {
return menu;
}
/**
* Return the frame that was created at the application's startup.
*/
public static BasicFrame getStartupFrame() {
return startupFrame;
}
/**
* Set the frame that is created at the application's startup.
*/
public static void setStartupFrame(BasicFrame startupFrame) {
BasicFrame.startupFrame = startupFrame;
}
/**
* Select the tab on the main pane.
@ -1273,7 +1287,7 @@ public class BasicFrame extends JFrame {
for (File file : files) {
log.info("Opening file: " + file);
if (open(file, parent)) {
if (open(file, parent) != null) {
MRUDesignFile opts = MRUDesignFile.getInstance();
opts.addFile(file.getAbsolutePath());
}
@ -1303,7 +1317,7 @@ public class BasicFrame extends JFrame {
for (File file : files) {
log.info("Opening file: " + file);
if (open(file, this)) {
if (open(file, this) != null) {
MRUDesignFile opts = MRUDesignFile.getInstance();
opts.addFile(file.getAbsolutePath());
}
@ -1373,9 +1387,9 @@ public class BasicFrame extends JFrame {
*
* @param file the file to open.
* @param parent the parent component for which a progress dialog is opened.
* @return whether the file was successfully loaded and opened.
* @return the BasicFrame that was created, or null if not created successfully.
*/
public static boolean open(File file, Window parent) {
public static BasicFrame open(File file, Window parent) {
OpenFileWorker worker = new OpenFileWorker(file);
return open(worker, file.getName(), parent, false);
}
@ -1388,15 +1402,15 @@ public class BasicFrame extends JFrame {
* @param displayName the file name to display in dialogs.
* @param parent
* @param openRocketConfigDialog if true, will open the configuration dialog of the rocket. This is useful for examples.
* @return
* @return the BasicFrame that was created, or null if not created successfully.
*/
private static boolean open(OpenFileWorker worker, String displayName, Window parent, boolean openRocketConfigDialog) {
private static BasicFrame open(OpenFileWorker worker, String displayName, Window parent, boolean openRocketConfigDialog) {
//// Open the file in a Swing worker thread
log.info("Starting OpenFileWorker");
if (!SwingWorkerDialog.runWorker(parent, "Opening file", "Reading " + displayName + "...", worker)) {
// // User cancelled the operation
log.info("User cancelled the OpenFileWorker");
return false;
return null;
}
//// Handle the document
@ -1415,7 +1429,7 @@ public class BasicFrame extends JFrame {
JOptionPane.showMessageDialog(parent,
"File not found: " + displayName,
"Error opening file", JOptionPane.ERROR_MESSAGE);
return false;
return null;
} else if (cause instanceof RocketLoadException) {
@ -1424,7 +1438,7 @@ public class BasicFrame extends JFrame {
"Unable to open file '" + displayName + "': "
+ cause.getMessage(),
"Error opening file", JOptionPane.ERROR_MESSAGE);
return false;
return null;
} else {
@ -1468,7 +1482,7 @@ public class BasicFrame extends JFrame {
ComponentConfigDialog.showDialog(frame, doc, doc.getRocket());
}
return true;
return frame;
}
@ -1774,24 +1788,27 @@ public class BasicFrame extends JFrame {
/**
* Opens a new design file or the last design file, if set in the preferences.
* Can be used for reopening the application or opening it the first time.
* @return the BasicFrame that was created
*/
public static void reopen() {
public static BasicFrame reopen() {
if (!Application.getPreferences().isAutoOpenLastDesignOnStartupEnabled()) {
BasicFrame.newAction();
return BasicFrame.newAction();
} else {
String lastFile = MRUDesignFile.getInstance().getLastEditedDesignFile();
if (lastFile != null) {
log.info("Opening last design file: " + lastFile);
if (!BasicFrame.open(new File(lastFile), null)) {
BasicFrame frame = BasicFrame.open(new File(lastFile), null);
if (frame == null) {
MRUDesignFile.getInstance().removeFile(lastFile);
BasicFrame.newAction();
return BasicFrame.newAction();
}
else {
MRUDesignFile.getInstance().addFile(lastFile);
return frame;
}
}
else {
BasicFrame.newAction();
return BasicFrame.newAction();
}
}
}
@ -1799,8 +1816,9 @@ public class BasicFrame extends JFrame {
/**
* Open a new design window with a basic rocket+stage.
* @return the BasicFrame that was created
*/
public static void newAction() {
public static BasicFrame newAction() {
log.info("New action initiated");
OpenRocketDocument doc = OpenRocketDocumentFactory.createNewRocket();
@ -1808,6 +1826,7 @@ public class BasicFrame extends JFrame {
BasicFrame frame = new BasicFrame(doc);
frame.replaceable = true;
frame.setVisible(true);
return frame;
}

View File

@ -73,7 +73,7 @@ public final class MRUDesignFileAction extends JMenu {
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (BasicFrame.open(new File(command), parent)) {
if (BasicFrame.open(new File(command), parent) != null) {
MRUDesignFile.getInstance().addFile(command);
}
else {

View File

@ -0,0 +1,74 @@
package net.sf.openrocket.gui.util;
import java.awt.GraphicsDevice;
import java.awt.Window;
/**
* Helper class for setting the location of a Swing window. E.g. to check when the window is outside the screen and
* recenter it if so.
*
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
*/
public abstract class WindowLocationUtil {
/**
* Sets the location of the window, but don't go outside the screen.
* @param window the window to move
* @param x the target x position on the screen
* @param y the target y position on the screen
*/
public static void setLocationWithinScreen(Window window, int x, int y) {
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
java.awt.Dimension windowSize = window.getSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
int windowWidth = windowSize.width;
int windowHeight = windowSize.height;
int xPos = x;
int yPos = y;
if (xPos + windowWidth > screenWidth) {
xPos = screenWidth - windowWidth;
}
if (yPos + windowHeight > screenHeight) {
yPos = screenHeight - windowHeight;
}
window.setLocation(xPos, yPos);
}
/**
* Moves the window to the center of the screen if its location is outside the boundary of the screen.
* @param window window to move
*/
public static void moveIfOutsideOfMonitor(Window window) {
GraphicsDevice currentDevice = window.getGraphicsConfiguration().getDevice();
if (currentDevice != null && window.isVisible() &&
!currentDevice.getDefaultConfiguration().getBounds().contains(window.getLocationOnScreen())) {
int width = currentDevice.getDefaultConfiguration().getBounds().width;
int height = currentDevice.getDefaultConfiguration().getBounds().height;
window.setLocation(
((width / 2) - (window.getSize().width / 2)) + currentDevice.getDefaultConfiguration().getBounds().x,
((height / 2) - (window.getSize().height / 2)) + currentDevice.getDefaultConfiguration().getBounds().y
);
}
}
/**
* Moves the window to the center of the screen if it is on another monitor as the parent window, or if its location
* is outside the boundary of the parent's monitor screen.
* @param window window to move
* @param parent parent window
*/
public static void moveIfOutsideOfParentMonitor(Window window, Window parent) {
GraphicsDevice parentDevice = parent.getGraphicsConfiguration().getDevice();
GraphicsDevice currentDevice = window.getGraphicsConfiguration().getDevice();
if (parentDevice != null && (currentDevice == null || currentDevice != parentDevice ||
(window.isVisible() && !parentDevice.getDefaultConfiguration().getBounds().contains(
window.getLocationOnScreen())))) {
int width = parentDevice.getDefaultConfiguration().getBounds().width;
int height = parentDevice.getDefaultConfiguration().getBounds().height;
window.setLocation(
((width / 2) - (window.getSize().width / 2)) + parentDevice.getDefaultConfiguration().getBounds().x,
((height / 2) - (window.getSize().height / 2)) + parentDevice.getDefaultConfiguration().getBounds().y
);
}
}
}

View File

@ -223,7 +223,8 @@ public class SwingStartup {
// Starting action (load files or open new document)
log.info("Opening main application window");
if (!handleCommandLine(args)) {
BasicFrame.reopen();
BasicFrame startupFrame = BasicFrame.reopen();
BasicFrame.setStartupFrame(startupFrame);
}
// Check whether update info has been fetched or whether it needs more time
@ -298,7 +299,7 @@ public class SwingStartup {
// Check command-line for files
boolean opened = false;
for (String file : args) {
if (BasicFrame.open(new File(file), null)) {
if (BasicFrame.open(new File(file), null) != null) {
opened = true;
}
}