|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
/*
|
|
|
- * Copyright (c) 2009-2020 jMonkeyEngine
|
|
|
|
|
|
|
+ * Copyright (c) 2009-2022 jMonkeyEngine
|
|
|
* All rights reserved.
|
|
* All rights reserved.
|
|
|
*
|
|
*
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -29,9 +29,12 @@
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
*/
|
|
*/
|
|
|
-package com.jme3.app;
|
|
|
|
|
|
|
+package com.jme3.awt;
|
|
|
|
|
|
|
|
|
|
+import com.jme3.asset.AssetNotFoundException;
|
|
|
import com.jme3.system.AppSettings;
|
|
import com.jme3.system.AppSettings;
|
|
|
|
|
+import com.jme3.system.JmeSystem;
|
|
|
|
|
+
|
|
|
import java.awt.*;
|
|
import java.awt.*;
|
|
|
import java.awt.event.*;
|
|
import java.awt.event.*;
|
|
|
import java.awt.image.BufferedImage;
|
|
import java.awt.image.BufferedImage;
|
|
@@ -42,41 +45,47 @@ import java.text.MessageFormat;
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
import java.util.Arrays;
|
|
|
import java.util.Comparator;
|
|
import java.util.Comparator;
|
|
|
|
|
+import java.util.LinkedHashSet;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.ResourceBundle;
|
|
import java.util.ResourceBundle;
|
|
|
|
|
+import java.util.Set;
|
|
|
|
|
+import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Level;
|
|
|
import java.util.logging.Logger;
|
|
import java.util.logging.Logger;
|
|
|
import java.util.prefs.BackingStoreException;
|
|
import java.util.prefs.BackingStoreException;
|
|
|
import javax.swing.*;
|
|
import javax.swing.*;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * <code>PropertiesDialog</code> provides an interface to make use of the
|
|
|
|
|
- * <code>GameSettings</code> class. The <code>GameSettings</code> object
|
|
|
|
|
- * is still created by the client application, and passed during construction.
|
|
|
|
|
- *
|
|
|
|
|
|
|
+ * <code>SettingsDialog</code> displays a Swing dialog box to interactively
|
|
|
|
|
+ * configure the <code>AppSettings</code> of a desktop application before
|
|
|
|
|
+ * <code>start()</code> is invoked.
|
|
|
|
|
+ *
|
|
|
|
|
+ * The <code>AppSettings</code> instance to be configured is passed to the
|
|
|
|
|
+ * constructor.
|
|
|
|
|
+ *
|
|
|
* @see AppSettings
|
|
* @see AppSettings
|
|
|
* @author Mark Powell
|
|
* @author Mark Powell
|
|
|
* @author Eric Woroshow
|
|
* @author Eric Woroshow
|
|
|
* @author Joshua Slack - reworked for proper use of GL commands.
|
|
* @author Joshua Slack - reworked for proper use of GL commands.
|
|
|
*/
|
|
*/
|
|
|
-public final class SettingsDialog extends JFrame {
|
|
|
|
|
|
|
+public final class AWTSettingsDialog extends JFrame {
|
|
|
|
|
|
|
|
public static interface SelectionListener {
|
|
public static interface SelectionListener {
|
|
|
|
|
|
|
|
public void onSelection(int selection);
|
|
public void onSelection(int selection);
|
|
|
}
|
|
}
|
|
|
- private static final Logger logger = Logger.getLogger(SettingsDialog.class.getName());
|
|
|
|
|
|
|
+
|
|
|
|
|
+ private static final Logger logger = Logger.getLogger(AWTSettingsDialog.class.getName());
|
|
|
private static final long serialVersionUID = 1L;
|
|
private static final long serialVersionUID = 1L;
|
|
|
- public static final int NO_SELECTION = 0,
|
|
|
|
|
- APPROVE_SELECTION = 1,
|
|
|
|
|
- CANCEL_SELECTION = 2;
|
|
|
|
|
-
|
|
|
|
|
|
|
+ public static final int NO_SELECTION = 0, APPROVE_SELECTION = 1, CANCEL_SELECTION = 2;
|
|
|
|
|
+
|
|
|
// Resource bundle for i18n.
|
|
// Resource bundle for i18n.
|
|
|
ResourceBundle resourceBundle = ResourceBundle.getBundle("com.jme3.app/SettingsDialog");
|
|
ResourceBundle resourceBundle = ResourceBundle.getBundle("com.jme3.app/SettingsDialog");
|
|
|
-
|
|
|
|
|
- // connection to properties file.
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // the instance being configured
|
|
|
private final AppSettings source;
|
|
private final AppSettings source;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// Title Image
|
|
// Title Image
|
|
|
private URL imageFile = null;
|
|
private URL imageFile = null;
|
|
|
// Array of supported display modes
|
|
// Array of supported display modes
|
|
@@ -104,72 +113,133 @@ public final class SettingsDialog extends JFrame {
|
|
|
|
|
|
|
|
private int minWidth = 0;
|
|
private int minWidth = 0;
|
|
|
private int minHeight = 0;
|
|
private int minHeight = 0;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ public static boolean showDialog(AppSettings sourceSettings) {
|
|
|
|
|
+ return showDialog(sourceSettings, true);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static boolean showDialog(AppSettings sourceSettings, boolean loadSettings) {
|
|
|
|
|
+ String iconPath = sourceSettings.getSettingsDialogImage();
|
|
|
|
|
+ final URL iconUrl = JmeSystem.class.getResource(iconPath.startsWith("/") ? iconPath : "/" + iconPath);
|
|
|
|
|
+ if (iconUrl == null) {
|
|
|
|
|
+ throw new AssetNotFoundException(sourceSettings.getSettingsDialogImage());
|
|
|
|
|
+ }
|
|
|
|
|
+ return showDialog(sourceSettings, iconUrl, loadSettings);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static boolean showDialog(AppSettings sourceSettings, String imageFile, boolean loadSettings) {
|
|
|
|
|
+ return showDialog(sourceSettings, getURL(imageFile), loadSettings);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static boolean showDialog(AppSettings sourceSettings, URL imageFile, boolean loadSettings) {
|
|
|
|
|
+ if (SwingUtilities.isEventDispatchThread()) {
|
|
|
|
|
+ throw new IllegalStateException("Cannot run from EDT");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (GraphicsEnvironment.isHeadless()) {
|
|
|
|
|
+ throw new IllegalStateException("Cannot show dialog in headless environment");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ AppSettings settings = new AppSettings(false);
|
|
|
|
|
+ settings.copyFrom(sourceSettings);
|
|
|
|
|
+
|
|
|
|
|
+ Object lock = new Object();
|
|
|
|
|
+ AtomicBoolean done = new AtomicBoolean();
|
|
|
|
|
+ AtomicInteger result = new AtomicInteger();
|
|
|
|
|
+ SwingUtilities.invokeLater(new Runnable() {
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void run() {
|
|
|
|
|
+ final SelectionListener selectionListener = new SelectionListener() {
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void onSelection(int selection) {
|
|
|
|
|
+ synchronized (lock) {
|
|
|
|
|
+ done.set(true);
|
|
|
|
|
+ result.set(selection);
|
|
|
|
|
+ lock.notifyAll();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ AWTSettingsDialog dialog = new AWTSettingsDialog(settings, imageFile, loadSettings);
|
|
|
|
|
+ dialog.setSelectionListener(selectionListener);
|
|
|
|
|
+ dialog.showDialog();
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ synchronized (lock) {
|
|
|
|
|
+ while (!done.get()) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ lock.wait();
|
|
|
|
|
+ } catch (InterruptedException ex) {
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ sourceSettings.copyFrom(settings);
|
|
|
|
|
+
|
|
|
|
|
+ return result.get() == AWTSettingsDialog.APPROVE_SELECTION;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
- * Constructor for the <code>PropertiesDialog</code>. Creates a
|
|
|
|
|
- * properties dialog initialized for the primary display.
|
|
|
|
|
|
|
+ * Instantiate a <code>SettingsDialog</code> for the primary display.
|
|
|
*
|
|
*
|
|
|
* @param source
|
|
* @param source
|
|
|
- * the <code>AppSettings</code> object to use for working with
|
|
|
|
|
- * the properties file.
|
|
|
|
|
|
|
+ * the <code>AppSettings</code> (not null)
|
|
|
* @param imageFile
|
|
* @param imageFile
|
|
|
* the image file to use as the title of the dialog;
|
|
* the image file to use as the title of the dialog;
|
|
|
* <code>null</code> will result in to image being displayed
|
|
* <code>null</code> will result in to image being displayed
|
|
|
- * @throws NullPointerException
|
|
|
|
|
|
|
+ * @param loadSettings
|
|
|
|
|
+ * if true, copy the settings, otherwise merge them
|
|
|
|
|
+ * @throws IllegalArgumentException
|
|
|
* if the source is <code>null</code>
|
|
* if the source is <code>null</code>
|
|
|
*/
|
|
*/
|
|
|
- public SettingsDialog(AppSettings source, String imageFile, boolean loadSettings) {
|
|
|
|
|
|
|
+ protected AWTSettingsDialog(AppSettings source, String imageFile, boolean loadSettings) {
|
|
|
this(source, getURL(imageFile), loadSettings);
|
|
this(source, getURL(imageFile), loadSettings);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * Constructor for the <code>PropertiesDialog</code>. Creates a
|
|
|
|
|
- * properties dialog initialized for the primary display.
|
|
|
|
|
- *
|
|
|
|
|
|
|
+ * /** Instantiate a <code>SettingsDialog</code> for the primary display.
|
|
|
|
|
+ *
|
|
|
* @param source
|
|
* @param source
|
|
|
- * the <code>GameSettings</code> object to use for working with
|
|
|
|
|
- * the properties file.
|
|
|
|
|
|
|
+ * the <code>AppSettings</code> object (not null)
|
|
|
* @param imageFile
|
|
* @param imageFile
|
|
|
* the image file to use as the title of the dialog;
|
|
* the image file to use as the title of the dialog;
|
|
|
* <code>null</code> will result in to image being displayed
|
|
* <code>null</code> will result in to image being displayed
|
|
|
- * @param loadSettings
|
|
|
|
|
- * @throws NullPointerException
|
|
|
|
|
|
|
+ * @param loadSettings
|
|
|
|
|
+ * if true, copy the settings, otherwise merge them
|
|
|
|
|
+ * @throws IllegalArgumentException
|
|
|
* if the source is <code>null</code>
|
|
* if the source is <code>null</code>
|
|
|
*/
|
|
*/
|
|
|
- public SettingsDialog(AppSettings source, URL imageFile, boolean loadSettings) {
|
|
|
|
|
|
|
+ protected AWTSettingsDialog(AppSettings source, URL imageFile, boolean loadSettings) {
|
|
|
if (source == null) {
|
|
if (source == null) {
|
|
|
- throw new NullPointerException("Settings source cannot be null");
|
|
|
|
|
|
|
+ throw new IllegalArgumentException("Settings source cannot be null");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
this.source = source;
|
|
this.source = source;
|
|
|
this.imageFile = imageFile;
|
|
this.imageFile = imageFile;
|
|
|
|
|
|
|
|
- //setModal(true);
|
|
|
|
|
|
|
+ // setModal(true);
|
|
|
setAlwaysOnTop(true);
|
|
setAlwaysOnTop(true);
|
|
|
setResizable(false);
|
|
setResizable(false);
|
|
|
|
|
|
|
|
AppSettings registrySettings = new AppSettings(true);
|
|
AppSettings registrySettings = new AppSettings(true);
|
|
|
|
|
|
|
|
String appTitle;
|
|
String appTitle;
|
|
|
- if(source.getTitle()!=null){
|
|
|
|
|
|
|
+ if (source.getTitle() != null) {
|
|
|
appTitle = source.getTitle();
|
|
appTitle = source.getTitle();
|
|
|
- }else{
|
|
|
|
|
- appTitle = registrySettings.getTitle();
|
|
|
|
|
|
|
+ } else {
|
|
|
|
|
+ appTitle = registrySettings.getTitle();
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
minWidth = source.getMinWidth();
|
|
minWidth = source.getMinWidth();
|
|
|
minHeight = source.getMinHeight();
|
|
minHeight = source.getMinHeight();
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
registrySettings.load(appTitle);
|
|
registrySettings.load(appTitle);
|
|
|
} catch (BackingStoreException ex) {
|
|
} catch (BackingStoreException ex) {
|
|
|
- logger.log(Level.WARNING,
|
|
|
|
|
- "Failed to load settings", ex);
|
|
|
|
|
|
|
+ logger.log(Level.WARNING, "Failed to load settings", ex);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (loadSettings) {
|
|
if (loadSettings) {
|
|
|
source.copyFrom(registrySettings);
|
|
source.copyFrom(registrySettings);
|
|
|
- } else if(!registrySettings.isEmpty()) {
|
|
|
|
|
|
|
+ } else if (!registrySettings.isEmpty()) {
|
|
|
source.mergeFrom(registrySettings);
|
|
source.mergeFrom(registrySettings);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -179,17 +249,13 @@ public final class SettingsDialog extends JFrame {
|
|
|
Arrays.sort(modes, new DisplayModeSorter());
|
|
Arrays.sort(modes, new DisplayModeSorter());
|
|
|
|
|
|
|
|
DisplayMode[] merged = new DisplayMode[modes.length + windowDefaults.length];
|
|
DisplayMode[] merged = new DisplayMode[modes.length + windowDefaults.length];
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
int wdIndex = 0;
|
|
int wdIndex = 0;
|
|
|
int dmIndex = 0;
|
|
int dmIndex = 0;
|
|
|
int mergedIndex;
|
|
int mergedIndex;
|
|
|
-
|
|
|
|
|
- for (mergedIndex = 0;
|
|
|
|
|
- mergedIndex<merged.length
|
|
|
|
|
- && (wdIndex < windowDefaults.length
|
|
|
|
|
- || dmIndex < modes.length);
|
|
|
|
|
- mergedIndex++) {
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ for (mergedIndex = 0; mergedIndex < merged.length && (wdIndex < windowDefaults.length || dmIndex < modes.length); mergedIndex++) {
|
|
|
|
|
+
|
|
|
if (dmIndex >= modes.length) {
|
|
if (dmIndex >= modes.length) {
|
|
|
merged[mergedIndex] = windowDefaults[wdIndex++];
|
|
merged[mergedIndex] = windowDefaults[wdIndex++];
|
|
|
} else if (wdIndex >= windowDefaults.length) {
|
|
} else if (wdIndex >= windowDefaults.length) {
|
|
@@ -209,13 +275,13 @@ public final class SettingsDialog extends JFrame {
|
|
|
merged[mergedIndex] = windowDefaults[wdIndex++];
|
|
merged[mergedIndex] = windowDefaults[wdIndex++];
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (merged.length == mergedIndex) {
|
|
if (merged.length == mergedIndex) {
|
|
|
windowModes = merged;
|
|
windowModes = merged;
|
|
|
} else {
|
|
} else {
|
|
|
windowModes = Arrays.copyOfRange(merged, 0, mergedIndex);
|
|
windowModes = Arrays.copyOfRange(merged, 0, mergedIndex);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
createUI();
|
|
createUI();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -248,9 +314,6 @@ public final class SettingsDialog extends JFrame {
|
|
|
this.minHeight = minHeight;
|
|
this.minHeight = minHeight;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
/**
|
|
/**
|
|
|
* <code>setImage</code> sets the background image of the dialog.
|
|
* <code>setImage</code> sets the background image of the dialog.
|
|
|
*
|
|
*
|
|
@@ -262,7 +325,7 @@ public final class SettingsDialog extends JFrame {
|
|
|
URL file = new URL("file:" + image);
|
|
URL file = new URL("file:" + image);
|
|
|
setImage(file);
|
|
setImage(file);
|
|
|
} catch (MalformedURLException e) {
|
|
} catch (MalformedURLException e) {
|
|
|
- logger.log(Level.WARNING, "Couldn’t read from file '" + image + "'", e);
|
|
|
|
|
|
|
+ logger.log(Level.WARNING, "Couldn’t read from file '" + image + "'", e);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -274,33 +337,27 @@ public final class SettingsDialog extends JFrame {
|
|
|
*/
|
|
*/
|
|
|
public void setImage(URL image) {
|
|
public void setImage(URL image) {
|
|
|
icon.setIcon(new ImageIcon(image));
|
|
icon.setIcon(new ImageIcon(image));
|
|
|
- pack(); // Resize to accomodate the new image
|
|
|
|
|
|
|
+ pack(); // Resize to accommodate the new image
|
|
|
setLocationRelativeTo(null); // put in center
|
|
setLocationRelativeTo(null); // put in center
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * <code>showDialog</code> sets this dialog as visble, and brings it to
|
|
|
|
|
- * the front.
|
|
|
|
|
|
|
+ * <code>showDialog</code> sets this dialog as visible, and brings it to the
|
|
|
|
|
+ * front.
|
|
|
*/
|
|
*/
|
|
|
public void showDialog() {
|
|
public void showDialog() {
|
|
|
setLocationRelativeTo(null);
|
|
setLocationRelativeTo(null);
|
|
|
- setVisible(true);
|
|
|
|
|
|
|
+ setVisible(true);
|
|
|
toFront();
|
|
toFront();
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* <code>init</code> creates the components to use the dialog.
|
|
* <code>init</code> creates the components to use the dialog.
|
|
|
*/
|
|
*/
|
|
|
private void createUI() {
|
|
private void createUI() {
|
|
|
GridBagConstraints gbc;
|
|
GridBagConstraints gbc;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
JPanel mainPanel = new JPanel(new GridBagLayout());
|
|
JPanel mainPanel = new JPanel(new GridBagLayout());
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- logger.warning("Could not set native look and feel.");
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
addWindowListener(new WindowAdapter() {
|
|
addWindowListener(new WindowAdapter() {
|
|
|
|
|
|
|
@@ -312,13 +369,13 @@ public final class SettingsDialog extends JFrame {
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
if (source.getIcons() != null) {
|
|
if (source.getIcons() != null) {
|
|
|
- safeSetIconImages( Arrays.asList((BufferedImage[]) source.getIcons()) );
|
|
|
|
|
|
|
+ safeSetIconImages(Arrays.asList((BufferedImage[]) source.getIcons()));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
setTitle(MessageFormat.format(resourceBundle.getString("frame.title"), source.getTitle()));
|
|
setTitle(MessageFormat.format(resourceBundle.getString("frame.title"), source.getTitle()));
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// The buttons...
|
|
// The buttons...
|
|
|
- JButton ok = new JButton(resourceBundle.getString("button.ok"));
|
|
|
|
|
|
|
+ JButton ok = new JButton(resourceBundle.getString("button.ok"));
|
|
|
JButton cancel = new JButton(resourceBundle.getString("button.cancel"));
|
|
JButton cancel = new JButton(resourceBundle.getString("button.cancel"));
|
|
|
|
|
|
|
|
icon = new JLabel(imageFile != null ? new ImageIcon(imageFile) : null);
|
|
icon = new JLabel(imageFile != null ? new ImageIcon(imageFile) : null);
|
|
@@ -332,8 +389,7 @@ public final class SettingsDialog extends JFrame {
|
|
|
setUserSelection(APPROVE_SELECTION);
|
|
setUserSelection(APPROVE_SELECTION);
|
|
|
dispose();
|
|
dispose();
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
|
|
|
|
|
|
+ } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
|
|
setUserSelection(CANCEL_SELECTION);
|
|
setUserSelection(CANCEL_SELECTION);
|
|
|
dispose();
|
|
dispose();
|
|
|
}
|
|
}
|
|
@@ -359,10 +415,10 @@ public final class SettingsDialog extends JFrame {
|
|
|
});
|
|
});
|
|
|
vsyncBox = new JCheckBox(resourceBundle.getString("checkbox.vsync"));
|
|
vsyncBox = new JCheckBox(resourceBundle.getString("checkbox.vsync"));
|
|
|
vsyncBox.setSelected(source.isVSync());
|
|
vsyncBox.setSelected(source.isVSync());
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
gammaBox = new JCheckBox(resourceBundle.getString("checkbox.gamma"));
|
|
gammaBox = new JCheckBox(resourceBundle.getString("checkbox.gamma"));
|
|
|
gammaBox.setSelected(source.isGammaCorrection());
|
|
gammaBox.setSelected(source.isGammaCorrection());
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
gbc = new GridBagConstraints();
|
|
gbc = new GridBagConstraints();
|
|
|
gbc.weightx = 0.5;
|
|
gbc.weightx = 0.5;
|
|
|
gbc.gridx = 0;
|
|
gbc.gridx = 0;
|
|
@@ -372,20 +428,19 @@ public final class SettingsDialog extends JFrame {
|
|
|
mainPanel.add(fullscreenBox, gbc);
|
|
mainPanel.add(fullscreenBox, gbc);
|
|
|
gbc = new GridBagConstraints();
|
|
gbc = new GridBagConstraints();
|
|
|
gbc.weightx = 0.5;
|
|
gbc.weightx = 0.5;
|
|
|
- // gbc.insets = new Insets(4, 16, 0, 4);
|
|
|
|
|
|
|
+ // gbc.insets = new Insets(4, 16, 0, 4);
|
|
|
gbc.gridx = 2;
|
|
gbc.gridx = 2;
|
|
|
- // gbc.gridwidth = 2;
|
|
|
|
|
|
|
+ // gbc.gridwidth = 2;
|
|
|
gbc.gridy = 1;
|
|
gbc.gridy = 1;
|
|
|
gbc.anchor = GridBagConstraints.EAST;
|
|
gbc.anchor = GridBagConstraints.EAST;
|
|
|
mainPanel.add(vsyncBox, gbc);
|
|
mainPanel.add(vsyncBox, gbc);
|
|
|
gbc = new GridBagConstraints();
|
|
gbc = new GridBagConstraints();
|
|
|
gbc.weightx = 0.5;
|
|
gbc.weightx = 0.5;
|
|
|
gbc.gridx = 3;
|
|
gbc.gridx = 3;
|
|
|
- gbc.gridy = 1;
|
|
|
|
|
|
|
+ gbc.gridy = 1;
|
|
|
gbc.anchor = GridBagConstraints.WEST;
|
|
gbc.anchor = GridBagConstraints.WEST;
|
|
|
mainPanel.add(gammaBox, gbc);
|
|
mainPanel.add(gammaBox, gbc);
|
|
|
|
|
|
|
|
-
|
|
|
|
|
gbc = new GridBagConstraints();
|
|
gbc = new GridBagConstraints();
|
|
|
gbc.insets = new Insets(4, 4, 4, 4);
|
|
gbc.insets = new Insets(4, 4, 4, 4);
|
|
|
gbc.gridx = 0;
|
|
gbc.gridx = 0;
|
|
@@ -434,7 +489,7 @@ public final class SettingsDialog extends JFrame {
|
|
|
gbc.gridy = 3;
|
|
gbc.gridy = 3;
|
|
|
gbc.anchor = GridBagConstraints.WEST;
|
|
gbc.anchor = GridBagConstraints.WEST;
|
|
|
mainPanel.add(antialiasCombo, gbc);
|
|
mainPanel.add(antialiasCombo, gbc);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// Set the button action listeners. Cancel disposes without saving, OK
|
|
// Set the button action listeners. Cancel disposes without saving, OK
|
|
|
// saves.
|
|
// saves.
|
|
|
ok.addActionListener(new ActionListener() {
|
|
ok.addActionListener(new ActionListener() {
|
|
@@ -444,10 +499,14 @@ public final class SettingsDialog extends JFrame {
|
|
|
if (verifyAndSaveCurrentSelection()) {
|
|
if (verifyAndSaveCurrentSelection()) {
|
|
|
setUserSelection(APPROVE_SELECTION);
|
|
setUserSelection(APPROVE_SELECTION);
|
|
|
dispose();
|
|
dispose();
|
|
|
-
|
|
|
|
|
- // System.gc() should be called to prevent "X Error of failed request: RenderBadPicture (invalid Picture parameter)"
|
|
|
|
|
- // on Linux when using AWT/Swing + GLFW.
|
|
|
|
|
- // For more info see: https://github.com/LWJGL/lwjgl3/issues/149, https://hub.jmonkeyengine.org/t/experimenting-lwjgl3/37275
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // System.gc() should be called to prevent "X Error of
|
|
|
|
|
+ // failed request: RenderBadPicture (invalid Picture
|
|
|
|
|
+ // parameter)"
|
|
|
|
|
+ // on Linux when using AWT/Swing + GLFW.
|
|
|
|
|
+ // For more info see:
|
|
|
|
|
+ // https://github.com/LWJGL/lwjgl3/issues/149,
|
|
|
|
|
+ // https://hub.jmonkeyengine.org/t/experimenting-lwjgl3/37275
|
|
|
System.gc();
|
|
System.gc();
|
|
|
System.gc();
|
|
System.gc();
|
|
|
}
|
|
}
|
|
@@ -468,7 +527,7 @@ public final class SettingsDialog extends JFrame {
|
|
|
gbc.gridwidth = 2;
|
|
gbc.gridwidth = 2;
|
|
|
gbc.gridy = 4;
|
|
gbc.gridy = 4;
|
|
|
gbc.anchor = GridBagConstraints.EAST;
|
|
gbc.anchor = GridBagConstraints.EAST;
|
|
|
- mainPanel.add(ok, gbc);
|
|
|
|
|
|
|
+ mainPanel.add(ok, gbc);
|
|
|
gbc = new GridBagConstraints();
|
|
gbc = new GridBagConstraints();
|
|
|
gbc.insets = new Insets(4, 16, 4, 4);
|
|
gbc.insets = new Insets(4, 16, 4, 4);
|
|
|
gbc.gridx = 2;
|
|
gbc.gridx = 2;
|
|
@@ -486,35 +545,42 @@ public final class SettingsDialog extends JFrame {
|
|
|
this.getContentPane().add(mainPanel);
|
|
this.getContentPane().add(mainPanel);
|
|
|
|
|
|
|
|
pack();
|
|
pack();
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
mainPanel.getRootPane().setDefaultButton(ok);
|
|
mainPanel.getRootPane().setDefaultButton(ok);
|
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public void run() {
|
|
public void run() {
|
|
|
- // Fill in the combos once the window has opened so that the insets can be read.
|
|
|
|
|
- // The assumption is made that the settings window and the display window will have the
|
|
|
|
|
- // same insets as that is used to resize the "full screen windowed" mode appropriately.
|
|
|
|
|
|
|
+ // Fill in the combos once the window has opened so that the
|
|
|
|
|
+ // insets can be read.
|
|
|
|
|
+ // The assumption is made that the settings window and the
|
|
|
|
|
+ // display window will have the
|
|
|
|
|
+ // same insets as that is used to resize the "full screen
|
|
|
|
|
+ // windowed" mode appropriately.
|
|
|
updateResolutionChoices();
|
|
updateResolutionChoices();
|
|
|
if (source.getWidth() != 0 && source.getHeight() != 0) {
|
|
if (source.getWidth() != 0 && source.getHeight() != 0) {
|
|
|
- displayResCombo.setSelectedItem(source.getWidth() + " x "
|
|
|
|
|
- + source.getHeight());
|
|
|
|
|
|
|
+ displayResCombo.setSelectedItem(source.getWidth() + " x " + source.getHeight());
|
|
|
} else {
|
|
} else {
|
|
|
- displayResCombo.setSelectedIndex(displayResCombo.getItemCount()-1);
|
|
|
|
|
|
|
+ displayResCombo.setSelectedIndex(displayResCombo.getItemCount() - 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
updateAntialiasChoices();
|
|
updateAntialiasChoices();
|
|
|
colorDepthCombo.setSelectedItem(source.getBitsPerPixel() + " bpp");
|
|
colorDepthCombo.setSelectedItem(source.getBitsPerPixel() + " bpp");
|
|
|
}
|
|
}
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /* Access JDialog.setIconImages by reflection in case we're running on JRE < 1.6 */
|
|
|
|
|
|
|
+ /*
|
|
|
|
|
+ * Access JDialog.setIconImages by reflection in case we're running on JRE <
|
|
|
|
|
+ * 1.6
|
|
|
|
|
+ */
|
|
|
private void safeSetIconImages(List<? extends Image> icons) {
|
|
private void safeSetIconImages(List<? extends Image> icons) {
|
|
|
try {
|
|
try {
|
|
|
- // Due to Java bug 6445278, we try to set icon on our shared owner frame first.
|
|
|
|
|
- // Otherwise, our alt-tab icon will be the Java default under Windows.
|
|
|
|
|
|
|
+ // Due to Java bug 6445278, we try to set icon on our shared owner
|
|
|
|
|
+ // frame first.
|
|
|
|
|
+ // Otherwise, our alt-tab icon will be the Java default under
|
|
|
|
|
+ // Windows.
|
|
|
Window owner = getOwner();
|
|
Window owner = getOwner();
|
|
|
if (owner != null) {
|
|
if (owner != null) {
|
|
|
Method setIconImages = owner.getClass().getMethod("setIconImages", List.class);
|
|
Method setIconImages = owner.getClass().getMethod("setIconImages", List.class);
|
|
@@ -532,7 +598,7 @@ public final class SettingsDialog extends JFrame {
|
|
|
/**
|
|
/**
|
|
|
* <code>verifyAndSaveCurrentSelection</code> first verifies that the
|
|
* <code>verifyAndSaveCurrentSelection</code> first verifies that the
|
|
|
* display mode is valid for this system, and then saves the current
|
|
* display mode is valid for this system, and then saves the current
|
|
|
- * selection as a properties.cfg file.
|
|
|
|
|
|
|
+ * selection to the backing store.
|
|
|
*
|
|
*
|
|
|
* @return if the selection is valid
|
|
* @return if the selection is valid
|
|
|
*/
|
|
*/
|
|
@@ -593,7 +659,7 @@ public final class SettingsDialog extends JFrame {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (valid) {
|
|
if (valid) {
|
|
|
- //use the GameSettings class to save it.
|
|
|
|
|
|
|
+ // use the AppSettings class to save it to backing store
|
|
|
source.setWidth(width);
|
|
source.setWidth(width);
|
|
|
source.setHeight(height);
|
|
source.setHeight(height);
|
|
|
source.setBitsPerPixel(depth);
|
|
source.setBitsPerPixel(depth);
|
|
@@ -601,7 +667,7 @@ public final class SettingsDialog extends JFrame {
|
|
|
source.setFullscreen(fullscreen);
|
|
source.setFullscreen(fullscreen);
|
|
|
source.setVSync(vsync);
|
|
source.setVSync(vsync);
|
|
|
source.setGammaCorrection(gamma);
|
|
source.setGammaCorrection(gamma);
|
|
|
- //source.setRenderer(renderer);
|
|
|
|
|
|
|
+ // source.setRenderer(renderer);
|
|
|
source.setSamples(multisample);
|
|
source.setSamples(multisample);
|
|
|
|
|
|
|
|
String appTitle = source.getTitle();
|
|
String appTitle = source.getTitle();
|
|
@@ -609,13 +675,10 @@ public final class SettingsDialog extends JFrame {
|
|
|
try {
|
|
try {
|
|
|
source.save(appTitle);
|
|
source.save(appTitle);
|
|
|
} catch (BackingStoreException ex) {
|
|
} catch (BackingStoreException ex) {
|
|
|
- logger.log(Level.WARNING,
|
|
|
|
|
- "Failed to save setting changes", ex);
|
|
|
|
|
|
|
+ logger.log(Level.WARNING, "Failed to save setting changes", ex);
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- showError(
|
|
|
|
|
- this,
|
|
|
|
|
- resourceBundle.getString("error.unsupportedmode"));
|
|
|
|
|
|
|
+ showError(this, resourceBundle.getString("error.unsupportedmode"));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return valid;
|
|
return valid;
|
|
@@ -624,7 +687,7 @@ public final class SettingsDialog extends JFrame {
|
|
|
/**
|
|
/**
|
|
|
* <code>setUpChooser</code> retrieves all available display modes and
|
|
* <code>setUpChooser</code> retrieves all available display modes and
|
|
|
* places them in a <code>JComboBox</code>. The resolution specified by
|
|
* places them in a <code>JComboBox</code>. The resolution specified by
|
|
|
- * GameSettings is used as the default value.
|
|
|
|
|
|
|
+ * AppSettings is used as the default value.
|
|
|
*
|
|
*
|
|
|
* @return the combo box of display modes.
|
|
* @return the combo box of display modes.
|
|
|
*/
|
|
*/
|
|
@@ -670,7 +733,7 @@ public final class SettingsDialog extends JFrame {
|
|
|
displayFreqCombo.setModel(new DefaultComboBoxModel<>(freqs));
|
|
displayFreqCombo.setModel(new DefaultComboBoxModel<>(freqs));
|
|
|
// Try to reset freq
|
|
// Try to reset freq
|
|
|
displayFreqCombo.setSelectedItem(displayFreq);
|
|
displayFreqCombo.setSelectedItem(displayFreq);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (!displayFreqCombo.getSelectedItem().equals(displayFreq)) {
|
|
if (!displayFreqCombo.getSelectedItem().equals(displayFreq)) {
|
|
|
// Cannot find saved frequency in available frequencies.
|
|
// Cannot find saved frequency in available frequencies.
|
|
|
// Choose the closest one to 60 Hz.
|
|
// Choose the closest one to 60 Hz.
|
|
@@ -686,21 +749,17 @@ public final class SettingsDialog extends JFrame {
|
|
|
*/
|
|
*/
|
|
|
private void updateResolutionChoices() {
|
|
private void updateResolutionChoices() {
|
|
|
if (!fullscreenBox.isSelected()) {
|
|
if (!fullscreenBox.isSelected()) {
|
|
|
- displayResCombo.setModel(new DefaultComboBoxModel<>(
|
|
|
|
|
- getWindowedResolutions(windowModes)));
|
|
|
|
|
|
|
+ displayResCombo.setModel(new DefaultComboBoxModel<>(getWindowedResolutions(windowModes)));
|
|
|
if (displayResCombo.getItemCount() > 0) {
|
|
if (displayResCombo.getItemCount() > 0) {
|
|
|
- displayResCombo.setSelectedIndex(displayResCombo.getItemCount()-1);
|
|
|
|
|
|
|
+ displayResCombo.setSelectedIndex(displayResCombo.getItemCount() - 1);
|
|
|
}
|
|
}
|
|
|
- colorDepthCombo.setModel(new DefaultComboBoxModel<>(new String[]{
|
|
|
|
|
- "24 bpp", "16 bpp"}));
|
|
|
|
|
- displayFreqCombo.setModel(new DefaultComboBoxModel<>(
|
|
|
|
|
- new String[]{resourceBundle.getString("refresh.na")}));
|
|
|
|
|
|
|
+ colorDepthCombo.setModel(new DefaultComboBoxModel<>(new String[] { "24 bpp", "16 bpp" }));
|
|
|
|
|
+ displayFreqCombo.setModel(new DefaultComboBoxModel<>(new String[] { resourceBundle.getString("refresh.na") }));
|
|
|
displayFreqCombo.setEnabled(false);
|
|
displayFreqCombo.setEnabled(false);
|
|
|
} else {
|
|
} else {
|
|
|
- displayResCombo.setModel(new DefaultComboBoxModel<>(
|
|
|
|
|
- getResolutions(modes, Integer.MAX_VALUE, Integer.MAX_VALUE)));
|
|
|
|
|
|
|
+ displayResCombo.setModel(new DefaultComboBoxModel<>(getResolutions(modes, Integer.MAX_VALUE, Integer.MAX_VALUE)));
|
|
|
if (displayResCombo.getItemCount() > 0) {
|
|
if (displayResCombo.getItemCount() > 0) {
|
|
|
- displayResCombo.setSelectedIndex(displayResCombo.getItemCount()-1);
|
|
|
|
|
|
|
+ displayResCombo.setSelectedIndex(displayResCombo.getItemCount() - 1);
|
|
|
}
|
|
}
|
|
|
displayFreqCombo.setEnabled(true);
|
|
displayFreqCombo.setEnabled(true);
|
|
|
updateDisplayChoices();
|
|
updateDisplayChoices();
|
|
@@ -709,10 +768,10 @@ public final class SettingsDialog extends JFrame {
|
|
|
|
|
|
|
|
private void updateAntialiasChoices() {
|
|
private void updateAntialiasChoices() {
|
|
|
// maybe in the future will add support for determining this info
|
|
// maybe in the future will add support for determining this info
|
|
|
- // through pbuffer
|
|
|
|
|
- String[] choices = new String[]{resourceBundle.getString("antialias.disabled"), "2x", "4x", "6x", "8x", "16x"};
|
|
|
|
|
|
|
+ // through PBuffer
|
|
|
|
|
+ String[] choices = new String[] { resourceBundle.getString("antialias.disabled"), "2x", "4x", "6x", "8x", "16x" };
|
|
|
antialiasCombo.setModel(new DefaultComboBoxModel<>(choices));
|
|
antialiasCombo.setModel(new DefaultComboBoxModel<>(choices));
|
|
|
- antialiasCombo.setSelectedItem(choices[Math.min(source.getSamples()/2,5)]);
|
|
|
|
|
|
|
+ antialiasCombo.setSelectedItem(choices[Math.min(source.getSamples() / 2, 5)]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
//
|
|
@@ -734,23 +793,23 @@ public final class SettingsDialog extends JFrame {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private static void showError(java.awt.Component parent, String message) {
|
|
private static void showError(java.awt.Component parent, String message) {
|
|
|
- JOptionPane.showMessageDialog(parent, message, "Error",
|
|
|
|
|
- JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
|
|
+ JOptionPane.showMessageDialog(parent, message, "Error", JOptionPane.ERROR_MESSAGE);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * Returns every unique resolution from an array of <code>DisplayMode</code>s
|
|
|
|
|
- * where the resolution is greater than the configured minimums.
|
|
|
|
|
|
|
+ * Returns every unique resolution from an array of
|
|
|
|
|
+ * <code>DisplayMode</code>s where the resolution is greater than the
|
|
|
|
|
+ * configured minimums.
|
|
|
*/
|
|
*/
|
|
|
private String[] getResolutions(DisplayMode[] modes, int heightLimit, int widthLimit) {
|
|
private String[] getResolutions(DisplayMode[] modes, int heightLimit, int widthLimit) {
|
|
|
Insets insets = getInsets();
|
|
Insets insets = getInsets();
|
|
|
heightLimit -= insets.top + insets.bottom;
|
|
heightLimit -= insets.top + insets.bottom;
|
|
|
widthLimit -= insets.left + insets.right;
|
|
widthLimit -= insets.left + insets.right;
|
|
|
-
|
|
|
|
|
- ArrayList<String> resolutions = new ArrayList<String>(modes.length);
|
|
|
|
|
- for (int i = 0; i < modes.length; i++) {
|
|
|
|
|
- int height = modes[i].getHeight();
|
|
|
|
|
- int width = modes[i].getWidth();
|
|
|
|
|
|
|
+
|
|
|
|
|
+ Set<String> resolutions = new LinkedHashSet<>(modes.length);
|
|
|
|
|
+ for (DisplayMode mode : modes) {
|
|
|
|
|
+ int height = mode.getHeight();
|
|
|
|
|
+ int width = mode.getWidth();
|
|
|
if (width >= minWidth && height >= minHeight) {
|
|
if (width >= minWidth && height >= minHeight) {
|
|
|
if (height >= heightLimit) {
|
|
if (height >= heightLimit) {
|
|
|
height = heightLimit;
|
|
height = heightLimit;
|
|
@@ -758,34 +817,31 @@ public final class SettingsDialog extends JFrame {
|
|
|
if (width >= widthLimit) {
|
|
if (width >= widthLimit) {
|
|
|
width = widthLimit;
|
|
width = widthLimit;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
String res = width + " x " + height;
|
|
String res = width + " x " + height;
|
|
|
- if (!resolutions.contains(res)) {
|
|
|
|
|
- resolutions.add(res);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ resolutions.add(res);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- String[] res = new String[resolutions.size()];
|
|
|
|
|
- resolutions.toArray(res);
|
|
|
|
|
- return res;
|
|
|
|
|
|
|
+ return resolutions.toArray(new String[0]);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
- * Returns every unique resolution from an array of <code>DisplayMode</code>s
|
|
|
|
|
- * where the resolution is greater than the configured minimums and the height
|
|
|
|
|
- * is less than the current screen resolution.
|
|
|
|
|
|
|
+ * Returns every unique resolution from an array of
|
|
|
|
|
+ * <code>DisplayMode</code>s where the resolution is greater than the
|
|
|
|
|
+ * configured minimums and the height is less than the current screen
|
|
|
|
|
+ * resolution.
|
|
|
*/
|
|
*/
|
|
|
private String[] getWindowedResolutions(DisplayMode[] modes) {
|
|
private String[] getWindowedResolutions(DisplayMode[] modes) {
|
|
|
int maxHeight = 0;
|
|
int maxHeight = 0;
|
|
|
int maxWidth = 0;
|
|
int maxWidth = 0;
|
|
|
-
|
|
|
|
|
- for (int i = 0; i < modes.length; i++) {
|
|
|
|
|
- if (maxHeight < modes[i].getHeight()) {
|
|
|
|
|
- maxHeight = modes[i].getHeight();
|
|
|
|
|
|
|
+
|
|
|
|
|
+ for (DisplayMode mode : modes) {
|
|
|
|
|
+ if (maxHeight < mode.getHeight()) {
|
|
|
|
|
+ maxHeight = mode.getHeight();
|
|
|
}
|
|
}
|
|
|
- if (maxWidth < modes[i].getWidth()) {
|
|
|
|
|
- maxWidth = modes[i].getWidth();
|
|
|
|
|
|
|
+ if (maxWidth < mode.getWidth()) {
|
|
|
|
|
+ maxWidth = mode.getWidth();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -796,79 +852,78 @@ public final class SettingsDialog extends JFrame {
|
|
|
* Returns every possible bit depth for the given resolution.
|
|
* Returns every possible bit depth for the given resolution.
|
|
|
*/
|
|
*/
|
|
|
private static String[] getDepths(String resolution, DisplayMode[] modes) {
|
|
private static String[] getDepths(String resolution, DisplayMode[] modes) {
|
|
|
- ArrayList<String> depths = new ArrayList<String>(4);
|
|
|
|
|
- for (int i = 0; i < modes.length; i++) {
|
|
|
|
|
|
|
+ List<String> depths = new ArrayList<>(4);
|
|
|
|
|
+ for (DisplayMode mode : modes) {
|
|
|
|
|
+ int bitDepth = mode.getBitDepth();
|
|
|
|
|
+ if (bitDepth == DisplayMode.BIT_DEPTH_MULTI) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
// Filter out all bit depths lower than 16 - Java incorrectly
|
|
// Filter out all bit depths lower than 16 - Java incorrectly
|
|
|
// reports
|
|
// reports
|
|
|
// them as valid depths though the monitor does not support them
|
|
// them as valid depths though the monitor does not support them
|
|
|
- if (modes[i].getBitDepth() < 16 && modes[i].getBitDepth() > 0) {
|
|
|
|
|
|
|
+ if (bitDepth < 16 && bitDepth > 0) {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- String res = modes[i].getWidth() + " x " + modes[i].getHeight();
|
|
|
|
|
- String depth = modes[i].getBitDepth() + " bpp";
|
|
|
|
|
- if (res.equals(resolution) && !depths.contains(depth)) {
|
|
|
|
|
|
|
+ String res = mode.getWidth() + " x " + mode.getHeight();
|
|
|
|
|
+ if (!res.equals(resolution)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ String depth = bitDepth + " bpp";
|
|
|
|
|
+ if (!depths.contains(depth)) {
|
|
|
depths.add(depth);
|
|
depths.add(depth);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (depths.size() == 1 && depths.contains("-1 bpp")) {
|
|
|
|
|
- // add some default depths, possible system is multi-depth supporting
|
|
|
|
|
- depths.clear();
|
|
|
|
|
|
|
+ if (depths.isEmpty()) {
|
|
|
|
|
+ // add some default depths, possible system is multi-depth
|
|
|
|
|
+ // supporting
|
|
|
depths.add("24 bpp");
|
|
depths.add("24 bpp");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- String[] res = new String[depths.size()];
|
|
|
|
|
- depths.toArray(res);
|
|
|
|
|
- return res;
|
|
|
|
|
|
|
+ return depths.toArray(new String[0]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Returns every possible refresh rate for the given resolution.
|
|
* Returns every possible refresh rate for the given resolution.
|
|
|
*/
|
|
*/
|
|
|
- private static String[] getFrequencies(String resolution,
|
|
|
|
|
- DisplayMode[] modes) {
|
|
|
|
|
- ArrayList<String> freqs = new ArrayList<String>(4);
|
|
|
|
|
- for (int i = 0; i < modes.length; i++) {
|
|
|
|
|
- String res = modes[i].getWidth() + " x " + modes[i].getHeight();
|
|
|
|
|
|
|
+ private static String[] getFrequencies(String resolution, DisplayMode[] modes) {
|
|
|
|
|
+ List<String> freqs = new ArrayList<>(4);
|
|
|
|
|
+ for (DisplayMode mode : modes) {
|
|
|
|
|
+ String res = mode.getWidth() + " x " + mode.getHeight();
|
|
|
String freq;
|
|
String freq;
|
|
|
- if (modes[i].getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN) {
|
|
|
|
|
|
|
+ if (mode.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN) {
|
|
|
freq = "???";
|
|
freq = "???";
|
|
|
} else {
|
|
} else {
|
|
|
- freq = modes[i].getRefreshRate() + " Hz";
|
|
|
|
|
|
|
+ freq = mode.getRefreshRate() + " Hz";
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
if (res.equals(resolution) && !freqs.contains(freq)) {
|
|
if (res.equals(resolution) && !freqs.contains(freq)) {
|
|
|
freqs.add(freq);
|
|
freqs.add(freq);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- String[] res = new String[freqs.size()];
|
|
|
|
|
- freqs.toArray(res);
|
|
|
|
|
- return res;
|
|
|
|
|
|
|
+ return freqs.toArray(new String[0]);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* Chooses the closest frequency to 60 Hz.
|
|
* Chooses the closest frequency to 60 Hz.
|
|
|
*
|
|
*
|
|
|
* @param resolution
|
|
* @param resolution
|
|
|
* @param modes
|
|
* @param modes
|
|
|
- * @return
|
|
|
|
|
|
|
+ * @return
|
|
|
*/
|
|
*/
|
|
|
private static String getBestFrequency(String resolution, DisplayMode[] modes) {
|
|
private static String getBestFrequency(String resolution, DisplayMode[] modes) {
|
|
|
int closest = Integer.MAX_VALUE;
|
|
int closest = Integer.MAX_VALUE;
|
|
|
int desired = 60;
|
|
int desired = 60;
|
|
|
- for (int i = 0; i < modes.length; i++) {
|
|
|
|
|
- String res = modes[i].getWidth() + " x " + modes[i].getHeight();
|
|
|
|
|
- int freq = modes[i].getRefreshRate();
|
|
|
|
|
|
|
+ for (DisplayMode mode : modes) {
|
|
|
|
|
+ String res = mode.getWidth() + " x " + mode.getHeight();
|
|
|
|
|
+ int freq = mode.getRefreshRate();
|
|
|
if (freq != DisplayMode.REFRESH_RATE_UNKNOWN && res.equals(resolution)) {
|
|
if (freq != DisplayMode.REFRESH_RATE_UNKNOWN && res.equals(resolution)) {
|
|
|
- if (Math.abs(freq - desired) <
|
|
|
|
|
- Math.abs(closest - desired)) {
|
|
|
|
|
- closest = modes[i].getRefreshRate();
|
|
|
|
|
|
|
+ if (Math.abs(freq - desired) < Math.abs(closest - desired)) {
|
|
|
|
|
+ closest = mode.getRefreshRate();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (closest != Integer.MAX_VALUE) {
|
|
if (closest != Integer.MAX_VALUE) {
|
|
|
return closest + " Hz";
|
|
return closest + " Hz";
|
|
|
} else {
|
|
} else {
|
|
@@ -877,8 +932,8 @@ public final class SettingsDialog extends JFrame {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * Utility class for sorting <code>DisplayMode</code>s. Sorts by
|
|
|
|
|
- * resolution, then bit depth, and then finally refresh rate.
|
|
|
|
|
|
|
+ * Utility class for sorting <code>DisplayMode</code>s. Sorts by resolution,
|
|
|
|
|
+ * then bit depth, and then finally refresh rate.
|
|
|
*/
|
|
*/
|
|
|
private class DisplayModeSorter implements Comparator<DisplayMode> {
|
|
private class DisplayModeSorter implements Comparator<DisplayMode> {
|
|
|
|
|
|