package org.pollux3d.app;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import com.jme3.system.AppSettings;
public class PolluxSettingsDialog extends JDialog implements ActionListener, WindowListener {
private static final long serialVersionUID = 1L;
private AppSettings settings;
private AtomicBoolean done;
private DisplayMode[] modes = null;
private JComboBox resolutions;
private JComboBox input;
private JComboBox quality;
private Image logo = null;;
private Object lock;
private PolluxSettingsDialog(AppSettings settings, Object lock, AtomicBoolean done) {
this.settings = settings;
this.lock = lock;
this.done = done;
GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
modes = device.getDisplayModes();
Arrays.sort(modes, new DisplayModeSorter());
setupDialog();
loadLogo();
}
public void loadLogo() {
String name = "logo.jpg";
MediaTracker tracker = new MediaTracker(this);
URL url = this.getClass().getResource(name);
if (url == null) return;
logo = Toolkit.getDefaultToolkit().getImage(url);
if (logo == null) return;
tracker.addImage(logo, System.identityHashCode(logo));
try {
tracker.waitForAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
if (logo != null) {
g2.drawImage(logo,10,10,360,147, null);
}
}
/**
* draws the gui
*/
private void setupDialog() {
this.setSize(400, 330);
this.setLayout(new BorderLayout());
this.setBackground(Color.WHITE);
this.setTitle("Pollux - www.pollux3d.org");
this.setResizable(false);
this.addWindowListener(this);
Font labelFont = new Font("Arial", Font.PLAIN, 18);
JPanel center = new JPanel();
center.setLayout(new BoxLayout(center, BoxLayout.PAGE_AXIS));
center.add(Box.createVerticalStrut(10));
JPanel firstLine = new JPanel();
firstLine.setLayout(new BoxLayout(firstLine, BoxLayout.LINE_AXIS));
firstLine.add(Box.createHorizontalStrut(30));
firstLine.setMaximumSize(new Dimension(400,60));
JLabel pollux = new JLabel("Pollux");
Font polluxFont = new Font("Arial", Font.PLAIN, 48);
pollux.setFont(polluxFont);
firstLine.add(pollux);
JLabel version = new JLabel(" v0.1 solexori");
Font versionFont = new Font("Arial", Font.PLAIN, 22);
version.setFont(versionFont);
firstLine.add(version);
center.add(firstLine);
center.add(Box.createVerticalStrut(70));
JPanel secLine = new JPanel();
secLine.setLayout(new BoxLayout(secLine, BoxLayout.LINE_AXIS));
secLine.add(Box.createHorizontalStrut(30));
secLine.setMaximumSize(new Dimension(400,30));
JLabel resolutionsLabel = new JLabel("Resolution: ");
resolutionsLabel.setFont(labelFont);
secLine.add(resolutionsLabel);
resolutions = setUpResolutionChooser();
secLine.add(resolutions);
secLine.add(Box.createHorizontalStrut(30));
center.add(secLine);
center.add(Box.createVerticalStrut(10));
JPanel tuioLine = new JPanel();
tuioLine.setLayout(new BoxLayout(tuioLine, BoxLayout.LINE_AXIS));
tuioLine.add(Box.createHorizontalStrut(30));
tuioLine.setMaximumSize(new Dimension(400,30));
JLabel inputLabel = new JLabel("Input: ");
inputLabel.setFont(labelFont);
tuioLine.add(inputLabel);
input = setUpInputChooser();
tuioLine.add(input);
tuioLine.add(Box.createHorizontalStrut(30));
center.add(tuioLine);
center.add(Box.createVerticalStrut(10));
JPanel texLine = new JPanel();
texLine.setLayout(new BoxLayout(texLine, BoxLayout.LINE_AXIS));
texLine.add(Box.createHorizontalStrut(30));
texLine.setMaximumSize(new Dimension(400,30));
JLabel texLabel = new JLabel("Quality: ");
texLabel.setFont(labelFont);
texLine.add(texLabel);
quality = setUpQualityChooser();
texLine.add(quality);
texLine.add(Box.createHorizontalStrut(30));
center.add(texLine);
center.add(Box.createVerticalStrut(10));
JPanel bottomLine = new JPanel();
bottomLine.setLayout(new BoxLayout(bottomLine, BoxLayout.LINE_AXIS));
bottomLine.add(Box.createHorizontalStrut(30));
bottomLine.setMaximumSize(new Dimension(400,30));
bottomLine.add(getLink());
bottomLine.add(Box.createHorizontalGlue());
JButton debug = new JButton("Debug");
debug.setActionCommand("Debug");
debug.addActionListener(this);
bottomLine.add(debug);
bottomLine.add(Box.createHorizontalStrut(10));
JButton okButton = new JButton("OK");
okButton.setActionCommand("Done");
okButton.addActionListener(this);
bottomLine.add(okButton);
bottomLine.add(Box.createHorizontalStrut(30));
center.add(bottomLine);
this.add(center, BorderLayout.CENTER);
}
private void showDialog() {
setLocationRelativeTo(null);
setVisible(true);
}
/**
* saves the selection into settings
*/
private void save() {
// defaults
settings.setFullscreen(true);
settings.setUseJoysticks(false);
if (!System.getProperty("os.name").equals("Windows 7")) {
settings.setBitsPerPixel(16);
settings.setFrequency(0);
}
// save resolution
String display = (String) resolutions.getSelectedItem();
int width = Integer.parseInt(display.substring(0, display.indexOf(" x ")));
display = display.substring(display.indexOf(" x ") + 3);
int height = Integer.parseInt(display);
settings.setResolution(width, height);
// save inputSystem
settings.putString("inputSystem", (String) input.getSelectedItem());
settings.putString("quality", (String) quality.getSelectedItem());
}
public void actionPerformed(ActionEvent ev) {
if (ev.getActionCommand().equals("Done")) {
save();
quit();
}
if (ev.getActionCommand().equals("Debug")) {
save();
settings.setFullscreen(false);
settings.setResolution(1024, 768);
quit();
}
}
private void quit() {
synchronized (lock){
this.dispose();
done.set(true);
lock.notifyAll();
}
}
/**
* <code>setUpResolutionChooser</code> retrieves all available display modes and
* places them in a <code>JComboBox</code>. The highest resolution
* is used as the default value.
*
* @return the combo box of display modes.
*/
private JComboBox setUpResolutionChooser() {
String[] res = getResolutions(modes);
JComboBox resolutionBox = new JComboBox(res);
//resolutionBox.setSelectedItem(settings.getWidth() + " x " + settings.getHeight());
resolutionBox.setSelectedItem(res[0]);
return resolutionBox;
}
public static class InputSystems {
public static final String Network = "Network TUIO Listener (UDP 3333)";
public static final String Win7 = "Windows7 Touch to TUIO Bridge";
public static final String Mouse = "Mouse to TUIO Bridge";
}
private JLabel getLink() {
JLabel link = new JLabel("<html><u>www.pollux3d.org</u></html>");
link.setForeground(Color.BLUE);
try {
if (Desktop.isDesktopSupported()) {
link.addMouseListener(new MouseListener(){
public void mouseClicked(MouseEvent arg0) {}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {
Desktop desktop = Desktop.getDesktop();
try {
desktop.browse(new URI("http://www.pollux3d.org"));
} catch (Exception e) {}
}
});
}
} catch (Exception e) {}
return link;
}
/**
* <code>setUpInputChooser</code> retrieves all available input modes and
* places them in a <code>JComboBox</code>.
*
* @return the combo box of display modes.
*/
private JComboBox setUpInputChooser() {
String[] inputs = new String[]{
InputSystems.Network,
InputSystems.Mouse,
};
if (System.getProperty("os.name").equals("Windows 7")) {
inputs = new String[]{
InputSystems.Network,
InputSystems.Win7,
InputSystems.Mouse,
};
}
JComboBox resolutionBox = new JComboBox(inputs);
//resolutionBox.setSelectedItem(settings.getWidth() + " x " + settings.getHeight());
resolutionBox.setSelectedItem(inputs[0]);
return resolutionBox;
}
private JComboBox setUpQualityChooser() {
String[] inputs = new String[]{
"high",
"normal",
"low"
};
JComboBox texBox = new JComboBox(inputs);
texBox.setSelectedItem(inputs[1]);
return texBox;
}
/**
* Returns every unique resolution from an array of <code>DisplayMode</code>s.
*/
private static String[] getResolutions(DisplayMode[] modes) {
ArrayList<String> resolutions = new ArrayList<String>(modes.length);
for (int i = 0; i < modes.length; i++) {
String res = modes[i].getWidth() + " x " + modes[i].getHeight();
if (!resolutions.contains(res)) {
resolutions.add(res);
}
}
String[] res = new String[resolutions.size()];
resolutions.toArray(res);
return res;
}
/**
* 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> {
/**
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(DisplayMode a, DisplayMode b) {
// Width
if (a.getWidth() != b.getWidth()) {
return (a.getWidth() > b.getWidth()) ? -1 : 1;
}
// Height
if (a.getHeight() != b.getHeight()) {
return (a.getHeight() > b.getHeight()) ? -1 : 1;
}
// Bit depth
if (a.getBitDepth() != b.getBitDepth()) {
return (a.getBitDepth() > b.getBitDepth()) ? -1 : 1;
}
// Refresh rate
if (a.getRefreshRate() != b.getRefreshRate()) {
return (a.getRefreshRate() > b.getRefreshRate()) ? -1 : 1;
}
// All fields are equal
return 0;
}
}
/**
* shows the Dialog and waits until user press OK
*
* @param settings AppSettings to use
* @return modified settings
*/
public static AppSettings show(final AppSettings settings) {
final AtomicBoolean done = new AtomicBoolean();
final Object lock = new Object();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
synchronized (lock) {
PolluxSettingsDialog dialog = new PolluxSettingsDialog(settings, lock, done);
dialog.showDialog();
}
}
});
synchronized (lock){
while (!done.get())
try {
lock.wait();
} catch (InterruptedException ex) {}
}
if (settings.getString("inputSystem") == null) System.exit(0);
return settings;
}
/**
* main for testing
*
* @param args
*/
public static void main(String[] args) {
AppSettings settings = new AppSettings(true);
PolluxSettingsDialog.show(settings);
System.out.println(settings.toString());
System.exit(0);
}
public void windowActivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowClosing(WindowEvent e) {
quit();
}
public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
}