I have a (somewhat philosophical) question relatively to Swing, or to GUI programming in general. Are there recognized best practices on where to locate the JFrame
instances used in the application?
setLocationRelativeTo(null)
)?JFrame
be located? Relatively to its parent JFrame
, at the center of the screen, wherever we want? I have always assumed there were some best practices, kind of a "GUI bible" about this, am I wrong and should I (gasp) arbitrarily decide what to do?
Here is an example that incorporates the advice of:
Hovercraft Full Of Eels - set location by platform.
Aardvocate Akintayo Olu - serialize the location.
But goes on to add 2 tweaks:
The 4 points combined offer the best user experience!
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Properties;
import java.io.*;
class RestoreMe {
/** This will end up in the current directory
A more sensible location is a sub-directory of user.home.
(left as an exercise for the reader) */
public static final String fileName = "options.prop";
/** Store location & size of UI */
public static void storeOptions(Frame f) throws Exception {
File file = new File(fileName);
Properties p = new Properties();
// restore the frame from 'full screen' first!
f.setExtendedState(Frame.NORMAL);
Rectangle r = f.getBounds();
int x = (int)r.getX();
int y = (int)r.getY();
int w = (int)r.getWidth();
int h = (int)r.getHeight();
p.setProperty("x", "" + x);
p.setProperty("y", "" + y);
p.setProperty("w", "" + w);
p.setProperty("h", "" + h);
BufferedWriter br = new BufferedWriter(new FileWriter(file));
p.store(br, "Properties of the user frame");
}
/** Restore location & size of UI */
public static void restoreOptions(Frame f) throws IOException {
File file = new File(fileName);
Properties p = new Properties();
BufferedReader br = new BufferedReader(new FileReader(file));
p.load(br);
int x = Integer.parseInt(p.getProperty("x"));
int y = Integer.parseInt(p.getProperty("y"));
int w = Integer.parseInt(p.getProperty("w"));
int h = Integer.parseInt(p.getProperty("h"));
Rectangle r = new Rectangle(x,y,w,h);
f.setBounds(r);
}
public static void main(String[] args) {
final JFrame f = new JFrame("Good Location & Size");
f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
f.addWindowListener( new WindowAdapter() {
public void windowClosing(WindowEvent we) {
try {
storeOptions(f);
} catch(Exception e) {
e.printStackTrace();
}
System.exit(0);
}
});
JTextArea ta = new JTextArea(20,50);
f.add(ta);
f.pack();
File optionsFile = new File(fileName);
if (optionsFile.exists()) {
try {
restoreOptions(f);
} catch(IOException ioe) {
ioe.printStackTrace();
}
} else {
f.setLocationByPlatform(true);
}
f.setVisible(true);
}
}