/*
* JFileSync
* Copyright (C) 2002-2007, Jens Heidrich
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301, USA
*/
package jfs.gui;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import jfs.conf.JFSConfig;
import jfs.conf.JFSConfigObserver;
import jfs.conf.JFSConst;
import jfs.conf.JFSLog;
import jfs.conf.JFSLogObserver;
import jfs.conf.JFSSettings;
import jfs.conf.JFSSyncMode;
import jfs.conf.JFSSyncModes;
import jfs.conf.JFSText;
import jfs.conf.JFSViewMode;
import jfs.conf.JFSViewModes;
import jfs.sync.JFSProgress;
import jfs.sync.JFSSynchronization;
import jfs.sync.JFSTable;
/**
* This class represents the main Java Swing frame of the JFS application.
*
* @author Jens Heidrich
* @version $Id: JFSMainView.java,v 1.39 2007/02/26 18:49:10 heidrich Exp $
*/
public class JFSMainView extends WindowAdapter implements ActionListener, ComponentListener, JFSConfigObserver, JFSLogObserver {
/**
* Stores the corresponding frame.
*/
private final JFrame frame;
/**
* The synchronization table itself in form of a JTable object.
*/
private final JTable syncTable;
/**
* Group with all possible views of the shown files.
*/
private final ButtonGroup viewGroup;
/**
* Group with all possible synchronization modes.
*/
private final ButtonGroup syncGroup;
/**
* Stores the overall size state (displayed at the bottom of the frame).
*/
private final JLabel stateOverallSize;
/**
* Stores the overall size state (displayed at the bottom of the frame).
*/
private final JLabel stateViewSize;
/**
* Stores the overall size state (displayed at the bottom of the frame).
*/
private final JLabel stateDuration;
/**
* Stores the overall synchronization mode (displayed at the bottom of the frame).
*/
private final JLabel stateSyncMode;
/**
* The last opened profiles.
*/
private final JMenuItem[] lastOpenedProfiles;
/**
* Shown if an unread error is available in the error log.
*/
private final JPanel errorLog;
/**
* The progress view.
*/
private final JFSProgressView progressView;
/**
* The used help view.
*/
private JFSHelpView helpView = null;
/**
* The used assistant view.
*/
private JFSAssistantView assistantView = null;
private String getAppTitle(String appName) {
// determine build date
String buildInfo = "";
try {
URL packageUrl = ClassLoader.getSystemResource("jfs");
File jfsFile = null;
// JFS started from JAR:
if (packageUrl.getProtocol().equals("jar")) {
URL jarUrl = new URL(packageUrl.getFile());
String uriString = jarUrl.toURI().getPath();
int idx = uriString.indexOf('!');
if (idx>0) {
uriString = uriString.substring(0, idx);
} // if
jfsFile = new File(uriString);
}
// JFS started from classes directory:
if (packageUrl.getProtocol().equals("file")) {
jfsFile = new File(packageUrl.toURI());
}
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy HH:mm");
buildInfo += " - build date "+formatter.format(new Date(jfsFile.lastModified()))+" ";
} catch (URISyntaxException use) {
;
} catch (MalformedURLException mue) {
;
} // try/catch
String version = JFSConst.getInstance().getString("jfs.version");
JFSConfig config = JFSConfig.getInstance();
return appName+" "+version+" - "+config.getTitle()+buildInfo;
} // getAppTitle()
/**
* Keyboard command actions.
*/
private class CommandAction implements Action {
private final JFSMainView me;
private final String action;
private final int keyCode;
public CommandAction(JFSMainView me, String action, int keyCode) {
this.me = me;
this.action = action;
this.keyCode = keyCode;
}
@Override
public Object getValue(String key) {
return null;
}
@Override
public void putValue(String key, Object value) {
// empty default
}
@Override
public void setEnabled(boolean b) {
// empty default
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
// empty default
}
@Override
public void removePropertyChangeListener(PropertyChangeListener listener) {
// empty default
}
public void register(JComponent component) {
component.getInputMap().put(KeyStroke.getKeyStroke(keyCode, InputEvent.CTRL_DOWN_MASK), action);
component.getActionMap().put(action, this);
} // register()
@Override
public void actionPerformed(ActionEvent e) {
me.actionPerformed(action);
}
} // CommandAction
/**
* Start the application with a certain task object.
*
* @param loadDefaults
* Determine whether the last loaded configuration should be loaded at GUI startup.
*/
public JFSMainView(boolean loadDefaults) {
this.lastOpenedProfiles = new JMenuItem[JFSConst.LAST_OPENED_PROFILES_SIZE];
JFSConfig config = JFSConfig.getInstance();
// Load default configuration if option is specified:
if (loadDefaults) {
config.loadDefaultFile();
}
// Redirect error stream to log file:
JFSLog.getErr().resetLogFile();
JFSLog.getOut().resetLogFile();
// Initialize attributes:
frame = new JFrame();
// Get translation object and set default locale:
JFSText t = JFSText.getInstance();
JComponent.setDefaultLocale(t.getLocale());
// Start main window of application:
frame.setTitle(getAppTitle(t.get("general.appName")));
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(this);
frame.addWindowStateListener(this);
frame.addComponentListener(this);
// Add icon:
ImageIcon jfsIcon = new ImageIcon(JFSConst.getInstance().getIconUrl("jfs.icon.logo"));
frame.setIconImage(jfsIcon.getImage());
Container cp = frame.getContentPane();
// Initialize JTable:
JFSTableView jfsSyncTable = new JFSTableView(frame);
syncTable = jfsSyncTable.getJTable();
// Create main menus:
JMenuBar menubar = new JMenuBar();
JMenu fileMenu = new JMenu(t.get("menu.file"));
JMenu viewMenu = new JMenu(t.get("menu.view"));
JMenu modeMenu = new JMenu(t.get("menu.mode"));
JMenu toolsMenu = new JMenu(t.get("menu.tools"));
JMenu helpMenu = new JMenu(t.get("menu.help"));
// Create file menu:
fileMenu.setMnemonic(KeyEvent.VK_I);
fileMenu.add(JFSSupport.getMenuItem("menu.new", "NEW", this, "jfs.icon.new"));
fileMenu.add(JFSSupport.getMenuItem("menu.open", "OPEN", this, "jfs.icon.open"));
fileMenu.add(JFSSupport.getMenuItem("menu.save", "SAVE", this, "jfs.icon.save"));
fileMenu.add(JFSSupport.getMenuItem("menu.saveAs", "SAVE_AS", this, "jfs.icon.saveAs"));
fileMenu.addSeparator();
fileMenu.add(JFSSupport.getMenuItem("menu.reset", "general.reset", this));
fileMenu.addSeparator();
for (int i = 0; i<JFSConst.LAST_OPENED_PROFILES_SIZE; i++) {
lastOpenedProfiles[i] = JFSSupport.getMenuItem("", "OPEN_"+i, this);
fileMenu.add(lastOpenedProfiles[i]);
}
updateLastOpenedProfiles();
fileMenu.addSeparator();
fileMenu.add(JFSSupport.getMenuItem("menu.exit", "EXIT", this));
// Create view menu:
viewGroup = new ButtonGroup();
byte view = config.getView();
for (JFSViewMode mode : JFSViewModes.getInstance().getModes()) {
viewMenu.add(JFSSupport.getRadioButtonMenuItem(viewGroup, mode.getAlias(), "VIEW_"+mode.getId(), view==mode.getId(), this));
}
// Create mode menu:
syncGroup = new ButtonGroup();
byte sync = config.getSyncMode();
for (JFSSyncMode mode : JFSSyncModes.getInstance().getModes()) {
modeMenu.add(JFSSupport.getRadioButtonMenuItem(syncGroup, mode.getAlias(), "SYNCMODE_"+mode.getId(), sync==mode.getId(),
this));
}
// Create tools menu:
toolsMenu.add(JFSSupport.getMenuItem("menu.assistant", "ASSISTANT", this, "jfs.icon.assistant"));
toolsMenu.addSeparator();
toolsMenu.add(JFSSupport.getMenuItem("menu.options", "OPTIONS", this, "jfs.icon.profile"));
toolsMenu.add(JFSSupport.getMenuItem("menu.compare", "COMPARE", this, "jfs.icon.compare"));
toolsMenu.add(JFSSupport.getMenuItem("menu.synchronize", "SYNCHRONIZE", this, "jfs.icon.synchronize"));
toolsMenu.addSeparator();
toolsMenu.add(JFSSupport.getMenuItem("menu.history", "HISTORY", this));
toolsMenu.addSeparator();
toolsMenu.add(JFSSupport.getMenuItem("menu.outLog", "OUTPUT_LOG", this, "jfs.icon.log"));
toolsMenu.add(JFSSupport.getMenuItem("menu.errLog", "error.log", this, "jfs.icon.log"));
// Create help menu:
helpMenu.add(JFSSupport.getMenuItem("menu.helpTopics", "jfs.help.topics", this, "jfs.icon.help"));
helpMenu.addSeparator();
helpMenu.add(JFSSupport.getMenuItem("menu.info", "INFO", this));
// Add menues to menu bar:
menubar.add(fileMenu);
menubar.add(viewMenu);
menubar.add(modeMenu);
menubar.add(toolsMenu);
menubar.add(helpMenu);
frame.setJMenuBar(menubar);
// Create control panel:
JToolBar bar = new JToolBar();
bar.putClientProperty("JToolBar.isRollover", Boolean.TRUE);
bar.add(JFSSupport.getButton("jfs.icon.new", "NEW", this, "menu.new"));
bar.add(JFSSupport.getButton("jfs.icon.open", "OPEN", this, "menu.open"));
bar.add(JFSSupport.getButton("jfs.icon.save", "SAVE", this, "menu.save"));
bar.add(JFSSupport.getButton("jfs.icon.saveAs", "SAVE_AS", this, "menu.saveAs"));
bar.addSeparator();
bar.add(JFSSupport.getButton("jfs.icon.profile", "OPTIONS", this, "menu.options"));
bar.add(JFSSupport.getButton("jfs.icon.compare", "COMPARE", this, "menu.compare"));
bar.add(JFSSupport.getButton("jfs.icon.synchronize", "SYNCHRONIZE", this, "menu.synchronize"));
bar.addSeparator();
JButton assistant = JFSSupport.getButton("jfs.icon.assistant", "ASSISTANT", this, "menu.assistant");
assistant.setText(t.get("menu.assistant"));
bar.add(assistant);
// Status label:
JPanel statePanel = new JPanel(new GridLayout(1, 4));
stateOverallSize = new JLabel();
statePanel.add(stateOverallSize);
stateViewSize = new JLabel();
statePanel.add(stateViewSize);
stateDuration = new JLabel();
statePanel.add(stateDuration);
stateSyncMode = new JLabel();
statePanel.add(stateSyncMode);
// South panel:
JPanel south = new JPanel(new BorderLayout());
errorLog = new JPanel(new FlowLayout(FlowLayout.RIGHT));
errorLog.add(new JLabel(t.get("error.log")));
errorLog.add(JFSSupport.getButton("jfs.icon.error", "error.log", this, "error.log"));
south.add(errorLog, BorderLayout.NORTH);
south.add(statePanel, BorderLayout.SOUTH);
errorLog.setVisible(false);
// Add elements to content pane:
cp.add(bar, BorderLayout.NORTH);
cp.add(new JScrollPane(syncTable), BorderLayout.CENTER);
cp.add(south, BorderLayout.SOUTH);
// Set some frame attributes:
JFSSettings s = JFSSettings.getInstance();
frame.setBounds(s.getWindowX(), s.getWindowY(), s.getWindowWidth(), s.getWindowHeight());
frame.setVisible(true);
// The state has to be set after making the frame visable
// because otherwise the state change is ignored by some
// window managers:
frame.setExtendedState(s.getWindowState());
new CommandAction(this, "EXIT", KeyEvent.VK_Q).register(fileMenu);
new CommandAction(this, "OPEN", KeyEvent.VK_O).register(fileMenu);
new CommandAction(this, "OPTIONS", KeyEvent.VK_P).register(fileMenu);
new CommandAction(this, "COMPARE", KeyEvent.VK_C).register(fileMenu);
new CommandAction(this, "SYNCHRONIZE", KeyEvent.VK_S).register(fileMenu);
// Create the progress view for the algorithm, which is displayed
// for every comparison and synchronization later:
progressView = new JFSProgressView(this);
JFSProgress.getInstance().attach(progressView);
// Register at configuration object, question view, and error log:
config.attach(this);
JFSSynchronization.getInstance().getQuestion().setOracle(new JFSQuestionView(this));
JFSLog.getErr().attach(this);
}
/**
* Returns the reference of the used frame.
*
* @return The frame of the main view.
*/
public final JFrame getFrame() {
return frame;
}
/**
* @see ActionListener#actionPerformed(ActionEvent)
*/
@Override
public void actionPerformed(ActionEvent event) {
String cmd = event.getActionCommand();
actionPerformed(cmd);
}
/**
* Action Listener of the main frame.
*
* @param cmd
* The transmitted command string.
*/
public void actionPerformed(String cmd) {
// Get translation objects, configuration, settings, and task:
JFSText t = JFSText.getInstance();
JFSConfig config = JFSConfig.getInstance();
JFSSettings s = JFSSettings.getInstance();
if ("NEW".equals(cmd)||"OPEN".equals(cmd)||cmd.startsWith("OPEN_")) {
int result = JOptionPane.OK_OPTION;
// Check whether changes need to be stored:
if (!config.isCurrentProfileStored()) {
JLabel msg = new JLabel(t.get("message.store"));
result = JOptionPane.showConfirmDialog(frame, msg, t.get("general.warning"), JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE);
}
if (result==JOptionPane.OK_OPTION) {
if ("NEW".equals(cmd)) {
// Clean the configuration settings and update the
// observers:
s.setCurrentProfile(null);
config.clean();
config.fireUpdate();
new JFSConfigView(frame);
}
if ("OPEN".equals(cmd)) {
File last = s.getLastProfileDir();
JFileChooser chooser = new JFileChooser(last);
chooser.setPreferredSize(new Dimension(700, 600));
JFSConfigFileFilter filter = new JFSConfigFileFilter();
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(frame);
s.setLastProfileDir(chooser.getCurrentDirectory());
if (returnVal==JFileChooser.APPROVE_OPTION) {
// Show error message if opening failed:
if (!config.load(chooser.getSelectedFile())) {
JLabel label = new JLabel(t.get("error.profile.load"));
JOptionPane.showMessageDialog(frame, label, t.get("error.window.title"), JOptionPane.ERROR_MESSAGE);
actionPerformed("NEW");
}
}
updateLastOpenedProfiles();
}
if (cmd.startsWith("OPEN_")) {
// Cut "OPEN_":
int i = Integer.parseInt(cmd.substring(5));
// Show error message if opening failed:
if (!config.load(s.getLastOpenedProfiles().get(i))) {
JLabel label = new JLabel(t.get("error.profile.load"));
JOptionPane.showMessageDialog(frame, label, t.get("error.window.title"), JOptionPane.ERROR_MESSAGE);
actionPerformed("NEW");
}
updateLastOpenedProfiles();
}
}
}
if ("SAVE".equals(cmd)||"SAVE_AS".equals(cmd)) {
boolean success = true;
// Store the configuration at once only if an appropriate
// configuration file exists and the command equals 'SAVE':
if ("SAVE".equals(cmd)&&(s.getCurrentProfile()!=null)) {
success = config.store(s.getCurrentProfile());
} else {
File last = s.getLastProfileDir();
JFileChooser chooser = new JFileChooser(last);
JFSConfigFileFilter filter = new JFSConfigFileFilter();
chooser.setFileFilter(filter);
int returnVal = chooser.showSaveDialog(frame);
s.setLastProfileDir(chooser.getCurrentDirectory());
if (returnVal==JFileChooser.APPROVE_OPTION) {
int result = JOptionPane.OK_OPTION;
File selectedFile = chooser.getSelectedFile();
// If file has no extension add ".xml":
if (selectedFile.getName().indexOf(".")==-1) {
selectedFile = new File(selectedFile.getParentFile(), selectedFile.getName()+".xml");
}
// If file already exists ask for overwriting:
if (selectedFile.exists()) {
JLabel msg = new JLabel(t.get("message.replace"));
result = JOptionPane.showConfirmDialog(frame, msg, t.get("general.warning"), JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE);
}
if (result==JOptionPane.OK_OPTION) {
success = config.store(selectedFile);
}
}
}
// Show error message if saving failed:
if (!success) {
JLabel label = new JLabel(t.get("error.profile.store"));
JOptionPane.showMessageDialog(frame, label, t.get("error.window.title"), JOptionPane.ERROR_MESSAGE);
}
updateLastOpenedProfiles();
}
if ("OPTIONS".equals(cmd)) {
new JFSConfigView(frame);
}
if (cmd.startsWith("VIEW")) {
// Cut "VIEW_":
String view = cmd.substring(5);
config.setView(Byte.parseByte(view));
config.fireConfigUpdate();
}
if (cmd.startsWith("SYNCMODE")) {
// Cut "SYNCMODE_":
String syncMode = cmd.substring(9);
config.setSyncMode(Byte.parseByte(syncMode));
config.fireConfigUpdate();
}
if ("SYNCHRONIZE".equals(cmd)) {
// Compute synchronization list:
JFSSynchronization.getInstance().computeSynchronizationLists();
// Show list of files to copy and to delete:
JFSConfirmationView cv = new JFSConfirmationView(frame);
// If the user confirms the lists, start synchronization as new
// thread:
if (cv.getResult()==JOptionPane.OK_OPTION) {
progressView.synchronizeInThread();
// Show lists of failed copy and delete statements:
new JFSReportView(frame);
}
}
if ("COMPARE".equals(cmd)) {
// Start comparison as new thread:
progressView.compareInThread();
}
if ("error.log".equals(cmd)) {
new JFSLogView(frame, JFSLogView.ERR);
}
if ("OUTPUT_LOG".equals(cmd)) {
new JFSLogView(frame, JFSLogView.OUT);
}
if ("general.reset".equals(cmd)) {
JLabel msg = new JLabel(t.get("message.reset"));
int result = JOptionPane.showConfirmDialog(frame, msg, t.get("general.warning"), JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE);
if (result==JOptionPane.OK_OPTION) {
s.clean();
config.clean();
config.fireUpdate();
JFSLog.getErr().resetLogFile();
JFSLog.getOut().resetLogFile();
frame.setBounds(s.getWindowX(), s.getWindowY(), s.getWindowWidth(), s.getWindowHeight());
frame.setExtendedState(s.getWindowState());
updateLastOpenedProfiles();
}
}
if ("EXIT".equals(cmd)) {
// Ask for exiting the program:
JLabel msg = new JLabel(t.get("message.exit"));
int result = JFSConfig.getInstance().isDontAskQuestions() ? JOptionPane.OK_OPTION : JOptionPane.showConfirmDialog(frame, msg, t.get("general.warning"), JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE);
if (result==JOptionPane.OK_OPTION) {
// Store last entered profile data:
config.storeDefaultFile();
// Store settings:
s.store();
// Close window and go back to main program:
frame.setVisible(false);
frame.dispose();
// Exit application:
System.exit(0);
}
}
if ("INFO".equals(cmd)) {
new JFSInfoView(this);
}
if ("jfs.help.topics".equals(cmd)) {
if (helpView==null) {
helpView = new JFSHelpView(frame);
} else {
helpView.setVisible(true);
}
}
if ("ASSISTANT".equals(cmd)) {
if (assistantView==null) {
assistantView = new JFSAssistantView(this);
} else {
assistantView.setVisible(true);
}
}
if ("HISTORY".equals(cmd)) {
new JFSHistoryManagerView(this.getFrame());
}
}
/**
* Updates the content of the main frame.
*/
public final void update() {
JFSText t = JFSText.getInstance();
stateOverallSize.setText(t.get("statePanel.overallSize")+" "+JFSTable.getInstance().getTableSize());
stateViewSize.setText(t.get("statePanel.viewSize")+" "+JFSTable.getInstance().getViewSize());
stateDuration.setText(t.get("statePanel.duration")+" "+JFSProgress.getInstance().getDuration());
updateComparisonTable();
}
/**
* Updates the content of the comparison table.
*/
public final void updateComparisonTable() {
syncTable.clearSelection();
syncTable.revalidate();
syncTable.repaint();
}
/**
* Updates the list of last profiles.
*/
public final void updateLastOpenedProfiles() {
List<File> profiles = JFSSettings.getInstance().getLastOpenedProfiles();
int max = Math.min(profiles.size(), JFSConst.LAST_OPENED_PROFILES_SIZE);
for (int i = 0; i<max; i++) {
String name = profiles.get(i).getName();
if (name.length()>30) {
name = name.substring(0, 26)+"...";
}
lastOpenedProfiles[i].setText((i+1)+". "+name);
lastOpenedProfiles[i].setVisible(true);
}
for (int i = max; i<JFSConst.LAST_OPENED_PROFILES_SIZE; i++) {
lastOpenedProfiles[i].setText("");
lastOpenedProfiles[i].setVisible(false);
}
}
/**
* @see JFSConfigObserver#updateConfig(JFSConfig)
*/
@Override
public final void updateConfig(JFSConfig config) {
// Update title:
JFSText t = JFSText.getInstance();
frame.setTitle(getAppTitle(t.get("general.appName")));
// Update view selection:
JRadioButtonMenuItem button;
Enumeration<AbstractButton> views = viewGroup.getElements();
while (views.hasMoreElements()) {
button = (JRadioButtonMenuItem) views.nextElement();
if (button.getActionCommand().equals("VIEW_"+config.getView())) {
button.setSelected(true);
} else {
button.setSelected(false);
}
}
// Update snyc mode selection:
Enumeration<AbstractButton> syncModes = syncGroup.getElements();
JFSSyncMode mode = JFSSyncModes.getInstance().getCurrentMode();
stateSyncMode.setText(t.get("statePanel.syncMode")+" "+JFSText.getInstance().get(mode.getAlias()));
while (syncModes.hasMoreElements()) {
button = (JRadioButtonMenuItem) syncModes.nextElement();
if (button.getActionCommand().equals("SYNCMODE_"+config.getSyncMode())) {
button.setSelected(true);
} else {
button.setSelected(false);
}
}
// Update state panel:
update();
}
/**
* @see JFSConfigObserver#updateComparison(JFSConfig)
*/
@Override
public final void updateComparison(JFSConfig config) {
update();
}
/**
* @see JFSConfigObserver#updateServer(JFSConfig)
*/
@Override
public final void updateServer(JFSConfig config) {
update();
}
/**
* @see java.awt.event.WindowListener#windowClosing(WindowEvent)
*/
@Override
public void windowClosing(WindowEvent arg0) {
super.windowClosing(arg0);
actionPerformed("EXIT");
}
/**
* @see java.awt.event.WindowStateListener#windowStateChanged(WindowEvent)
*/
@Override
public void windowStateChanged(WindowEvent arg0) {
super.windowStateChanged(arg0);
int state = arg0.getNewState();
// If state "iconified" is ignored and not stored in the settings
// object:
if (state!=Frame.ICONIFIED) {
JFSSettings settings = JFSSettings.getInstance();
settings.setWindowState(state);
}
}
/**
* @see ComponentListener#componentHidden(ComponentEvent)
*/
@Override
public void componentHidden(ComponentEvent arg0) {
// empty default
}
/**
* @see ComponentListener#componentMoved(ComponentEvent)
*/
@Override
public void componentMoved(ComponentEvent arg0) {
componentResized(arg0);
}
/**
* @see ComponentListener#componentResized(ComponentEvent)
*/
@Override
public void componentResized(ComponentEvent arg0) {
JFSSettings settings = JFSSettings.getInstance();
int state = frame.getExtendedState();
Rectangle r = frame.getBounds();
if (state==Frame.NORMAL) {
settings.setWindowBounds(r.x, r.y, r.width, r.height);
} else if (state==Frame.MAXIMIZED_VERT) {
settings.setWindowX(r.x);
settings.setWindowWidth(r.width);
} else if (state==Frame.MAXIMIZED_HORIZ) {
settings.setWindowY(r.y);
settings.setWindowHeight(r.height);
}
}
/**
* @see ComponentListener#componentShown(ComponentEvent)
*/
@Override
public void componentShown(ComponentEvent arg0) {
// empty default
}
/**
* @see JFSLogObserver#update(JFSLog)
*/
@Override
public void update(JFSLog log) {
errorLog.setVisible(log.hasUnreadLogMessages());
}
}