From: <ev...@us...> - 2010-12-25 21:12:46
|
Revision: 1466 http://rails.svn.sourceforge.net/rails/?rev=1466&view=rev Author: evos Date: 2010-12-25 21:12:39 +0000 (Sat, 25 Dec 2010) Log Message: ----------- Main windows keep their location and size across program restarts. The bounds per window and per game are saved in a file named like "settings_xxxx.rails_ini", where xxxx is the game name. This file is stored in the save directory (as does ConfigWindow), but I'm open to any other suggestions. For some reason that is beyond me, the ReportWindow refuses to register its bounds, so it doesn't work there yet. Modified Paths: -------------- trunk/18xx/rails/ui/swing/GameUIManager.java trunk/18xx/rails/ui/swing/ORWindow.java trunk/18xx/rails/ui/swing/ReportWindow.java trunk/18xx/rails/ui/swing/StartRoundWindow.java trunk/18xx/rails/ui/swing/StatusWindow.java trunk/18xx/rails/ui/swing/StockChart.java trunk/18xx/tiles/TileDictionary.18t Added Paths: ----------- trunk/18xx/rails/ui/swing/WindowSettings.java Modified: trunk/18xx/rails/ui/swing/GameUIManager.java =================================================================== --- trunk/18xx/rails/ui/swing/GameUIManager.java 2010-12-24 20:24:00 UTC (rev 1465) +++ trunk/18xx/rails/ui/swing/GameUIManager.java 2010-12-25 21:12:39 UTC (rev 1466) @@ -1,12 +1,6 @@ package rails.ui.swing; -import java.awt.Component; -import java.awt.Container; -import java.awt.EventQueue; import java.awt.Font; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; @@ -72,6 +66,8 @@ protected SimpleDateFormat saveDateTimeFormat; protected File lastFile, lastDirectory; + protected WindowSettings windowSettings; + protected boolean configuredStockChartVisibility = false; protected boolean previousStockChartVisibilityHint; @@ -93,13 +89,29 @@ this.gameManager = gameManager; uiHints = gameManager.getUIHints(); + initWindowSettings(); initSaveSettings(); initFontSettings(); - + configuredStockChartVisibility = "yes".equalsIgnoreCase(Config.get("stockchart.window.open")); } - + + private void initWindowSettings () { + + windowSettings = new WindowSettings (gameManager.getGameName()); + windowSettings.load(); + } + + public void terminate () { + getWindowSettings ().save(); + System.exit(0); + } + + public WindowSettings getWindowSettings () { + return windowSettings; + } + private void initSaveSettings() { saveDirectory = Config.get("save.directory"); if (!Util.hasValue(saveDirectory)) { @@ -126,7 +138,7 @@ } private void initFontSettings() { - + // font settings, can be game specific String fontType = Config.getGameSpecific("font.ui.name"); Font font = null; @@ -149,14 +161,14 @@ log.debug("Change text fonts to relative scale " + Scale.getFontScale()); changeGlobalFont(font, Scale.getFontScale()); } - + public void gameUIInit(boolean newGame) { imageLoader = new ImageLoader(); stockChart = new StockChart(this); if (Config.get("report.window.type").equalsIgnoreCase("static")) { - reportWindow = new ReportWindow(gameManager); + reportWindow = new ReportWindow(this); } else { reportWindow = new ReportWindowDynamic(this); } @@ -174,7 +186,7 @@ // GraphicsDevice[] gs = ge.getScreenDevices(); // log.debug("ScreenDevices = " + Arrays.toString(gs)); // statusWindow = statusWindowClass.getConstructor(GraphicsConfiguration.class).newInstance(gs[1].getDefaultConfiguration()); - + statusWindow.init(this); } catch (Exception e) { log.fatal("Cannot instantiate class " + statusWindowClassName, e); @@ -312,7 +324,7 @@ /* close current dialog */ setCurrentDialog(null, null); - + if (StockRound.class.isAssignableFrom(previousRoundType)) { log.debug("UI leaving Stock Round "+previousRoundName); statusWindow.finishRound(); @@ -454,7 +466,7 @@ } updateStatus(activeWindow); - + } /** Stub, to be overridden in subclasses for special round types */ @@ -708,7 +720,7 @@ File proposedFile = new File(filename); jfc.setSelectedFile(proposedFile); - + if (jfc.showSaveDialog(statusWindow) == JFileChooser.APPROVE_OPTION) { File selectedFile = jfc.getSelectedFile(); String filepath = selectedFile.getPath(); @@ -760,7 +772,7 @@ saveAction.setFilepath(filepath); processOnServer(saveAction); } - + } public void setSaveDirectory(String saveDirectory) { @@ -838,14 +850,14 @@ public boolean getGameParameterAsBoolean (GuiDef.Parm key) { return (Boolean) getGameParameter(key); } - + private void setEnabledWindow(boolean enabled, JFrame window, JFrame exceptionWindow) { - + if (window != null && window != exceptionWindow) { window.setEnabled(enabled); } } - /** + /** * deactivate all game windows, except the argument one */ public void setEnabledAllWindows(boolean enabled, JFrame exceptionWindow) { @@ -856,8 +868,8 @@ setEnabledWindow(enabled, startRoundWindow, exceptionWindow); setEnabledWindow(enabled, statusWindow, exceptionWindow); } - - + + private void updateWindowsLookAndFeel() { SwingUtilities.updateComponentTreeUI(statusWindow); statusWindow.pack(); @@ -870,7 +882,7 @@ SwingUtilities.updateComponentTreeUI(stockChart); stockChart.pack(); } - + /** update fonts settings * (after configuration changes) */ Modified: trunk/18xx/rails/ui/swing/ORWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/ORWindow.java 2010-12-24 20:24:00 UTC (rev 1465) +++ trunk/18xx/rails/ui/swing/ORWindow.java 2010-12-25 21:12:39 UTC (rev 1466) @@ -3,8 +3,7 @@ import java.awt.BorderLayout; import java.awt.Rectangle; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; +import java.awt.event.*; import java.util.ArrayList; import java.util.List; @@ -67,7 +66,7 @@ mapPanel = new MapPanel(gameUIManager); getContentPane().add(mapPanel, BorderLayout.CENTER); - + upgradePanel = new UpgradesPanel(orUIManager); getContentPane().add(upgradePanel, BorderLayout.WEST); addMouseListener(upgradePanel); @@ -93,6 +92,7 @@ log.debug("OrWindow size = " + this.getSize()); final JFrame frame = this; + final GameUIManager guiMgr = gameUIManager; addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { @@ -100,7 +100,25 @@ frame.dispose(); } }); + addComponentListener(new ComponentAdapter() { + @Override + public void componentMoved(ComponentEvent e) { + guiMgr.getWindowSettings().set(frame); + } + @Override + public void componentResized(ComponentEvent e) { + guiMgr.getWindowSettings().set(frame); + } + }); + pack(); + + WindowSettings ws = gameUIManager.getWindowSettings(); + Rectangle bounds = ws.getBounds(this); + if (bounds.x != -1 && bounds.y != -1) setLocation(bounds.getLocation()); + if (bounds.width != -1 && bounds.height != -1) setSize(bounds.getSize()); + ws.set(frame); + gameUIManager.reportWindow.updateLog(); } Modified: trunk/18xx/rails/ui/swing/ReportWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/ReportWindow.java 2010-12-24 20:24:00 UTC (rev 1465) +++ trunk/18xx/rails/ui/swing/ReportWindow.java 2010-12-25 21:12:39 UTC (rev 1466) @@ -3,12 +3,7 @@ import java.awt.*; import java.awt.event.*; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; +import java.io.*; import javax.swing.*; @@ -17,9 +12,7 @@ import rails.game.GameManagerI; import rails.game.ReportBuffer; import rails.ui.swing.elements.ActionMenuItem; -import rails.util.Config; -import rails.util.LocalText; -import rails.util.Util; +import rails.util.*; /** * This is the UI for the LogWindow. It displays logged messages to the user @@ -38,11 +31,12 @@ private JMenuItem saveItem, loadItem, printItem; private JMenuItem findItem, findBackItem, findNextItem, findPrevItem; + private GameUIManager gameUIManager; private GameManagerI gameManager; - + private String reportDirectory = Config.get("report.directory"); private String reportFile; - + private boolean editable = "yes".equalsIgnoreCase(Config.get("report.window.editable")); protected static final String SAVE_CMD = "Save"; @@ -52,14 +46,15 @@ protected static final String FIND_BACK_CMD = "FindBack"; protected static final String FIND_NEXT_CMD = "FindNext"; protected static final String FIND_PREV_CMD = "FindPrev"; - + protected static Logger log = Logger.getLogger(ReportWindow.class.getPackage().getName()); - - public ReportWindow(GameManagerI gameManager) { + + public ReportWindow(GameUIManager gameUIManager) { messageWindow = this; - this.gameManager = gameManager; + this.gameUIManager = gameUIManager; + this.gameManager = gameUIManager.getGameManager(); reportText = new JTextArea(); reportText.setEditable(editable); @@ -79,13 +74,13 @@ gbc.weightx = gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; messagePanel.add(messageScroller, gbc); - + menuBar = new JMenuBar(); fileMenu = new JMenu(LocalText.getText("FILE")); fileMenu.setMnemonic(KeyEvent.VK_F); editMenu = new JMenu(LocalText.getText("EDIT")); editMenu.setMnemonic(KeyEvent.VK_E); - + loadItem = new ActionMenuItem(LocalText.getText("LOAD")); loadItem.setActionCommand(LOAD_CMD); loadItem.setMnemonic(KeyEvent.VK_L); @@ -151,20 +146,40 @@ menuBar.add(fileMenu); menuBar.add(editMenu); - + setJMenuBar(menuBar); - + setContentPane(messagePanel); addKeyListener(this); - + // default report window settings super.init(); + + final JFrame frame = this; + final GameUIManager guiMgr = gameUIManager; + addComponentListener(new ComponentAdapter() { + @Override + public void componentMoved(ComponentEvent e) { + guiMgr.getWindowSettings().set(frame); + } + @Override + public void componentResized(ComponentEvent e) { + guiMgr.getWindowSettings().set(frame); + } + }); + + WindowSettings ws = gameUIManager.getWindowSettings(); + Rectangle bounds = ws.getBounds(this); + if (bounds.x != -1 && bounds.y != -1) setLocation(bounds.getLocation()); + if (bounds.width != -1 && bounds.height != -1) setSize(bounds.getSize()); + ws.set(frame); } /* (non-Javadoc) * @see rails.ui.swing.ReportWindowI#updateLog() */ + @Override public void updateLog() { String newText = ReportBuffer.get(); if (newText.length() > 0) { @@ -173,6 +188,7 @@ } } + @Override public void scrollDown () { SwingUtilities.invokeLater(new Runnable() { public void run() { @@ -197,7 +213,7 @@ findNext(true); } } - + private void loadReportFile() { JFileChooser jfc = new JFileChooser(); @@ -212,7 +228,7 @@ } else { return; } - + try { BufferedReader in = new BufferedReader (new FileReader(selectedFile)); String line; @@ -226,9 +242,9 @@ e.getMessage(), "", JOptionPane.ERROR_MESSAGE); } } - + private void saveReportFile () { - + JFileChooser jfc = new JFileChooser(); if (Util.hasValue(reportDirectory)) { jfc.setCurrentDirectory(new File(reportDirectory)); @@ -243,7 +259,7 @@ if (!selectedFile.getName().equalsIgnoreCase(reportFile)) { reportFile = filepath; } - + try { PrintWriter out = new PrintWriter (new FileWriter (new File (reportFile))); out.print(reportText.getText()); @@ -255,40 +271,40 @@ } } } - + private void findText(boolean backwards) { - + String text = reportText.getText(); - String target = JOptionPane.showInputDialog(reportText, + String target = JOptionPane.showInputDialog(reportText, LocalText.getText("EnterSearch")); if (!Util.hasValue(target)) return; - - int startPos = editable - ? reportText.getCaretPosition() + + int startPos = editable + ? reportText.getCaretPosition() : backwards ? text.length() : 0; int foundPos = backwards ? text.lastIndexOf(target, startPos) : text.indexOf(target, startPos); if (foundPos < 0) return; - + reportText.select(foundPos, foundPos + target.length()); } - + private void findNext(boolean backwards) { - + String text = reportText.getText(); String target = reportText.getSelectedText(); if (!Util.hasValue(target)) return; - + int startPos = reportText.getSelectionStart(); int foundPos = backwards ? text.lastIndexOf(target, startPos-1) : text.indexOf(target, startPos+1); if (foundPos < 0) return; - + reportText.select(foundPos, foundPos + target.length()); } - + public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_F1) { HelpWindow.displayHelp(gameManager.getHelp()); Modified: trunk/18xx/rails/ui/swing/StartRoundWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/StartRoundWindow.java 2010-12-24 20:24:00 UTC (rev 1465) +++ trunk/18xx/rails/ui/swing/StartRoundWindow.java 2010-12-25 21:12:39 UTC (rev 1466) @@ -186,8 +186,38 @@ addKeyListener(this); + // set closing behavior and listener + setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE ); + final JFrame thisFrame = this; + final GameUIManager guiMgr = gameUIManager; + addWindowListener(new WindowAdapter () { + @Override + public void windowClosing(WindowEvent e) { + if (JOptionPane.showConfirmDialog(thisFrame, LocalText.getText("CLOSE_WINDOW"), LocalText.getText("Select"), JOptionPane.OK_CANCEL_OPTION) + == JOptionPane.OK_OPTION) { + thisFrame.dispose(); + guiMgr.terminate(); + } + } + }); + addComponentListener(new ComponentAdapter() { + @Override + public void componentMoved(ComponentEvent e) { + guiMgr.getWindowSettings().set(thisFrame); + } + @Override + public void componentResized(ComponentEvent e) { + guiMgr.getWindowSettings().set(thisFrame); + } + }); pack(); + + WindowSettings ws = gameUIManager.getWindowSettings(); + Rectangle bounds = ws.getBounds(this); + if (bounds.x != -1 && bounds.y != -1) setLocation(bounds.getLocation()); + if (bounds.width != -1 && bounds.height != -1) setSize(bounds.getSize()); + ws.set(thisFrame); } private void init() { @@ -321,19 +351,6 @@ dummyButton = new ClickField("", "", "", this, itemGroup); - // set closing behavior and listener - setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE ); - final JFrame thisFrame = this; - addWindowListener(new WindowAdapter () { - @Override - public void windowClosing(WindowEvent e) { - if (JOptionPane.showConfirmDialog(thisFrame, LocalText.getText("CLOSE_WINDOW"), LocalText.getText("Select"), JOptionPane.OK_CANCEL_OPTION) - == JOptionPane.OK_OPTION) { - thisFrame.dispose(); - System.exit(0); - } - } - }); } private void addField(JComponent comp, int x, int y, int width, int height, Modified: trunk/18xx/rails/ui/swing/StatusWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/StatusWindow.java 2010-12-24 20:24:00 UTC (rev 1465) +++ trunk/18xx/rails/ui/swing/StatusWindow.java 2010-12-25 21:12:39 UTC (rev 1466) @@ -1,10 +1,10 @@ /* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/ui/swing/StatusWindow.java,v 1.46 2010/06/15 20:16:54 evos Exp $*/ package rails.ui.swing; -import java.awt.BorderLayout; -import java.awt.Color; +import java.awt.*; import java.awt.event.*; import java.util.*; +import java.util.List; import javax.swing.*; @@ -256,11 +256,11 @@ log.fatal("Cannot instantiate class " + gameStatusClassName, e); System.exit(1); } - + gameStatus.init(this, gameUIManager); // put gameStatus into a JScrollPane JScrollPane gameStatusPane = new JScrollPane(gameStatus); - + buttonPanel = new JPanel(); passButton = new ActionButton(LocalText.getText("PASS")); @@ -299,19 +299,35 @@ setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE ); final JFrame frame = this; + final GameUIManager guiMgr = gameUIManager; addWindowListener(new WindowAdapter () { @Override public void windowClosing(WindowEvent e) { if (JOptionPane.showConfirmDialog(frame, LocalText.getText("CLOSE_WINDOW"), LocalText.getText("Select"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) { frame.dispose(); - System.exit(0); + guiMgr.terminate(); } } }); + addComponentListener(new ComponentAdapter() { + @Override + public void componentMoved(ComponentEvent e) { + guiMgr.getWindowSettings().set(frame); + } + @Override + public void componentResized(ComponentEvent e) { + guiMgr.getWindowSettings().set(frame); + } + }); + pack(); - pack(); + WindowSettings ws = gameUIManager.getWindowSettings(); + Rectangle bounds = ws.getBounds(this); + if (bounds.x != -1 && bounds.y != -1) setLocation(bounds.getLocation()); + if (bounds.width != -1 && bounds.height != -1) setSize(bounds.getSize()); + ws.set(frame); } public void setGameActions() { @@ -596,7 +612,7 @@ process(executedAction); } else if (command.equals(QUIT_CMD)) { - System.exit(0); + gameUIManager.terminate(); } else if (command.equals(REPORT_CMD)) { gameUIManager.reportWindow.setVisible(((JMenuItem) actor.getSource()).isSelected()); gameUIManager.reportWindow.scrollDown(); Modified: trunk/18xx/rails/ui/swing/StockChart.java =================================================================== --- trunk/18xx/rails/ui/swing/StockChart.java 2010-12-24 20:24:00 UTC (rev 1465) +++ trunk/18xx/rails/ui/swing/StockChart.java 2010-12-25 21:12:39 UTC (rev 1466) @@ -33,6 +33,7 @@ stockPanel.setBackground(Color.LIGHT_GRAY); final JFrame frame = this; + final GameUIManager guiMgr = gameUIManager; addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { @@ -40,8 +41,24 @@ frame.dispose(); } }); + addComponentListener(new ComponentAdapter() { + @Override + public void componentMoved(ComponentEvent e) { + guiMgr.getWindowSettings().set(frame); + } + @Override + public void componentResized(ComponentEvent e) { + guiMgr.getWindowSettings().set(frame); + } + }); addKeyListener(this); pack(); + + WindowSettings ws = gameUIManager.getWindowSettings(); + Rectangle bounds = ws.getBounds(this); + if (bounds.x != -1 && bounds.y != -1) setLocation(bounds.getLocation()); + if (bounds.width != -1 && bounds.height != -1) setSize(bounds.getSize()); + ws.set(frame); } private void initialize() { Added: trunk/18xx/rails/ui/swing/WindowSettings.java =================================================================== --- trunk/18xx/rails/ui/swing/WindowSettings.java (rev 0) +++ trunk/18xx/rails/ui/swing/WindowSettings.java 2010-12-25 21:12:39 UTC (rev 1466) @@ -0,0 +1,114 @@ +package rails.ui.swing; + +import java.awt.Rectangle; +import java.io.*; +import java.util.*; + +import javax.swing.JFrame; + +import org.apache.log4j.Logger; + +import rails.util.Config; + +public class WindowSettings { + + private Map<String, Rectangle> settings = new HashMap<String, Rectangle>(); + private String filepath; + + private static final String settingsfilename = "settings_xxxx.rails_ini"; + + protected static Logger log = + Logger.getLogger(WindowSettings.class.getPackage().getName()); + + public WindowSettings (String gameName) { + String directory = Config.get("save.directory"); + filepath = directory + File.separator + settingsfilename.replace("xxxx", gameName); + } + + private Rectangle rectangle (String windowName) { + + if (settings.containsKey(windowName)) { + return settings.get(windowName); + } else { + Rectangle r = new Rectangle(-1, -1, -1, -1); + settings.put(windowName, r); + return r; + } + } + + public Rectangle getBounds (JFrame w) { + return rectangle (w.getClass().getSimpleName()); + } + + public void load () { + + BufferedReader in; + try { + in = new BufferedReader (new FileReader (filepath)); + String line; + String[] fields; + int v; + Rectangle r; + while ((line = in.readLine()) != null) { + fields = line.split("[\\.=]"); + if (fields.length < 3) continue; + v = Integer.parseInt(fields[2]); + r = rectangle(fields[0]); + switch (fields[1].charAt(0)) { + case 'X': r.x = v; break; + case 'Y': r.y = v; break; + case 'W': r.width = v; break; + case 'H': r.height = v; break; + } + } + in.close(); + } catch (FileNotFoundException e) { + // No problem + return; + } catch (Exception e) { + log.error ("Error while loading "+filepath, e); + } + + } + + public void set(JFrame window) { + + if (window != null) { + + // Save one window's settings + String name = window.getClass().getSimpleName(); + Rectangle r = rectangle (name); + r.x = window.getX(); + r.y = window.getY(); + r.width = window.getWidth(); + r.height = window.getHeight(); + log.debug("+++ Set "+name+" bounds to "+r.x+","+r.y+"/"+r.width+","+r.height); + } + return; + } + + public void save () { + + // Save all settings to file + log.debug("=== Saving all window settings"); + try { + PrintWriter out = new PrintWriter (new FileWriter (new File (filepath))); + Rectangle r; + Set<String> keys = new TreeSet<String> (settings.keySet()); + for (String name : keys) { + r = settings.get(name); + out.println(name+".X="+r.x); + out.println(name+".Y="+r.y); + out.println(name+".W="+r.width); + out.println(name+".H="+r.height); + } + out.close(); + } catch (Exception e) { + + } + + } + + +} + Modified: trunk/18xx/tiles/TileDictionary.18t =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |