package com.limegroup.gnutella.gui;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Point;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.ResourceBundle;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import com.limegroup.gnutella.ErrorService;
import com.limegroup.gnutella.RouterService;
import com.limegroup.gnutella.bugs.BugManager;
import com.limegroup.gnutella.bugs.FatalBugManager;
import com.limegroup.gnutella.gui.connection.ConnectionMediator;
import com.limegroup.gnutella.gui.download.DownloadMediator;
import com.limegroup.gnutella.gui.library.LibraryMediator;
import com.limegroup.gnutella.gui.menu.MenuMediator;
import com.limegroup.gnutella.gui.mp3.MediaPlayerComponent;
import com.limegroup.gnutella.gui.notify.NotifyUserProxy;
import com.limegroup.gnutella.gui.options.OptionsMediator;
import com.limegroup.gnutella.gui.playlist.PlaylistMediator;
import com.limegroup.gnutella.gui.search.SearchMediator;
import com.limegroup.gnutella.gui.statistics.StatisticsMediator;
import com.limegroup.gnutella.gui.tabs.LibraryPlayListTab;
import com.limegroup.gnutella.gui.themes.ThemeMediator;
import com.limegroup.gnutella.gui.themes.ThemeSettings;
import com.limegroup.gnutella.gui.upload.UploadMediator;
import com.limegroup.gnutella.settings.ApplicationSettings;
import com.limegroup.gnutella.settings.BooleanSetting;
import com.limegroup.gnutella.settings.IntSetting;
import com.limegroup.gnutella.settings.PlayerSettings;
import com.limegroup.gnutella.settings.QuestionsHandler;
import com.limegroup.gnutella.settings.StartupSettings;
import com.limegroup.gnutella.util.CommonUtils;
import com.limegroup.gnutella.util.Launcher;
import com.limegroup.gnutella.util.ManagedThread;
import com.limegroup.gnutella.util.ProcessingQueue;
import com.limegroup.gnutella.util.ThreadFactory;
import com.limegroup.gnutella.version.UpdateInformation;
/**
* This class acts as a central point of access for all gui components, a sort
* of "hub" for the frontend. This should be the only common class that all
* frontend components have access to, reducing the overall dependencies and
* therefore increasing the modularity of the code.
*
* <p>Any functions or services that should be accessible to multiple classes
* should be added to this class. These currently include such functions as
* easily displaying standardly-formatted messages to the user, obtaining
* locale-specific strings, and obtaining image resources, among others.
*
* <p>All of the methods in this class should be called from the event-
* dispatch (Swing) thread.
*/
//2345678|012345678|012345678|012345678|012345678|012345678|012345678|012345678|
public final class GUIMediator {
/**
* The number of messages a connection must have sent before we consider
* it stable for the UI.
*/
private static final int STABLE_THRESHOLD = 5;
/**
* Flag for whether or not a message has been displayed to the user --
* useful in deciding whether or not to display other dialogues.
*/
private static boolean _displayedMessage;
/**
* Message key for the disconnected message
*/
private static final String DISCONNECTED_MESSAGE = "NO_INTERNET_RETRYING";
/**
* Singleton for easy access to the mediator.
*/
private static GUIMediator _instance = null;
/**
* Constant for the index of the search tab in the main application
* window.
*/
public static final int SEARCH_INDEX = 0;
/**
* Constant for the index of the monitor tab in the main application
* window.
*/
public static final int MONITOR_INDEX = 1;
/**
* Constant for the index of the connections tab in the main application
* window.
*/
public static final int CONNECTIONS_INDEX = 2;
/**
* Constant for the index of the library tab in the main application
* window.
*/
public static final int LIBRARY_INDEX = 3;
/**
* Constant for the index of the console tab in the main application
* window.
*/
public static final int CONSOLE_INDEX = 4;
/**
* Constant specifying whether or not the user has donated to the LimeWire
* project.
*/
private static boolean HAS_DONATED = true;
/**
* The main <tt>JFrame</tt> for the application.
*/
private static final JFrame FRAME = new JFrame();
/**
* <tt>List</tt> of <tt>RefreshListener</tt> classes to notify of UI
* refresh events.
*/
private static final List REFRESH_LIST = new ArrayList();
/**
* String to be displayed in title bar of LW client.
*/
private final String APP_TITLE =
GUIMediator.getStringResource("APP_TITLE");
/**
* Constant for when the user selects the yes button
* in a message giving the user a yes and a no option.
*/
public static final int YES_OPTION = MessageService.YES_OPTION;
/**
* Constant for when the user selects the no button
* in a message giving the user a yes and a no option.
*/
public static final int NO_OPTION = MessageService.NO_OPTION;
/**
* Constant for when the user selects the cancel button
* in a message giving the user a cancel option
*/
public static final int CANCEL_OPTION = MessageService.CANCEL_OPTION;
/**
* Handle to the <tt>OptionsMediator</tt> class that is responsible for
* displaying customizable options to the user.
*/
private static OptionsMediator _optionsMediator;
/**
* Constant handle to the <tt>MainFrame</tt> instance that handles
* constructing all of the primary gui components.
*/
private final MainFrame MAIN_FRAME = new MainFrame(FRAME);
/**
* Constant handle to the <tt>DownloadMediator</tt> class that is
* responsible for displaying active downloads to the user.
*/
private final DownloadMediator DOWNLOAD_MEDIATOR =
MAIN_FRAME.getDownloadMediator();
/**
* Constant handle to the <tt>UploadMediator</tt> class that is
* responsible for displaying active uploads to the user.
*/
private final UploadMediator UPLOAD_MEDIATOR =
MAIN_FRAME.getUploadMediator();
/**
* Constant handle to the <tt>ConnectionMediator</tt> class that is
* responsible for displaying current connections to the user.
*/
private final ConnectionMediator CONNECTION_MEDIATOR =
MAIN_FRAME.getConnectionMediator();
/**
* Constant handle to the <tt>LibraryMediator</tt> class that is
* responsible for displaying files in the user's repository.
*/
private final LibraryMediator LIBRARY_MEDIATOR =
MAIN_FRAME.getLibraryMediator();
/**
* Constant handle to the <tt>MenuMediator</tt> class that is responsible
* for displaying and controlling the main menu bar of the program.
*/
private final MenuMediator MENU_MEDIATOR =
MAIN_FRAME.getMenuMediator();
/**
* Constant handle to the <tt>DownloadView</tt> class that is responsible
* for displaying the status of the network and connectivity to the user.
*/
private final StatusLine STATUS_LINE =
MAIN_FRAME.getStatusLine();
/**
* Constant handle to the <tt>StatisticsMediator</tt> class that is
* responsible for displaying statistics to the user.
*/
private final StatisticsMediator STATISTICS_MEDIATOR =
MAIN_FRAME.getStatisticsMediator();
/**
* Handle to <tt>RouterService</tt> to give frontend classes access to the
* backend.
*/
private RouterService _routerService;
/**
* Flag for whether or not the app has ever been made visible during this
* session.
*/
private static boolean _visibleOnce = false;
/**
* Flag for whether or not the app is allowed to become visible.
*/
private static boolean _allowVisible = false;
/**
* Queue for items to be run in the background.
*/
private final ProcessingQueue QUEUE = new ProcessingQueue("DelayedGUI");
/**
* The last recorded idle time.
*/
private long lastIdleTime = 0;
/**
* The number of times that we'll allow a java check to go unheeded.
*/
private int JAVA_CHECK = new Random().nextInt(10) + 5;
/**
* Private constructor to ensure that this class cannot be constructed
* from another class.
*/
private GUIMediator() {
FRAME.setTitle(APP_TITLE);
_optionsMediator = MAIN_FRAME.getOptionsMediator();
addRefreshListener(STATISTICS_MEDIATOR);
}
/**
* Singleton accessor for this class.
*
* @return the <tt>GUIMediator</tt> instance
*/
public static synchronized GUIMediator instance() {
if (_instance == null)
_instance = new GUIMediator();
return _instance;
}
/**
* Accessor for whether or not the GUIMediator has been constructed yet.
*/
public static boolean isConstructed() {
return _instance != null;
}
/**
* Runs the specified runnable in a different thread when it can.
*/
public void schedule(Runnable r) {
QUEUE.add(r);
}
/**
* The host catcher and the statistics view need the backend to be
* initialized for these methods to be called.
*/
public final void startTimer() {
RefreshTimer timer = new RefreshTimer();
timer.startTimer();
}
/**
* Returns a boolean specifying whether or not the wrapped
* <tt>JFrame</tt> is visible or not.
*
* @return <tt>true</tt> if the <tt>JFrame</tt> is visible,
* <tt>false</tt> otherwise
*/
public static final boolean isAppVisible() {
return FRAME.isShowing();
}
/**
* Specifies whether or not the main application window should be visible
* or not.
*
* @param visible specifies whether or not the application should be
* made visible or not
*/
public static final void setAppVisible(final boolean visible) {
safeInvokeLater(new Runnable() {
public void run() {
try {
if (visible)
FRAME.toFront();
FRAME.setVisible(visible);
} catch (NullPointerException npe) {
// NPE being thrown on WinXP sometimes. First try
// reverting to the limewire theme. If NPE still
// thrown, tell user to change LimeWire's Windows
// compatibility mode to Win2k.
// null pointer found
if (CommonUtils.isWindowsXP()) {
try {
if (ThemeSettings.isWindowsTheme()) {
ThemeMediator.changeTheme(ThemeSettings.LIMEWIRE_THEME_FILE);
try {
if (visible)
FRAME.toFront();
FRAME.setVisible(visible);
} catch (NullPointerException npe2) {
GUIMediator.showError("ERROR_STARTUP_WINDOWS_COMPATIBILITY");
System.exit(0);
}
} else {
GUIMediator.showError("ERROR_STARTUP_WINDOWS_COMPATIBILITY");
System.exit(0);
}
} catch (Throwable t) {
if (visible)
FatalBugManager.handleFatalBug(npe);
else
showInternalError(npe);
}
} else {
if (visible)
FatalBugManager.handleFatalBug(npe);
else
showInternalError(npe);
}
} catch(Throwable t) {
if (visible)
FatalBugManager.handleFatalBug(t);
else
showInternalError(t);
}
if (visible) {
SearchMediator.requestSearchFocus();
// forcibily revalidate the FRAME
// after making it visible.
// on Java 1.5, it does not validate correctly.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
FRAME.getContentPane().invalidate();
FRAME.getContentPane().validate();
}
});
}
// If the app has already been made visible, don't display extra
// dialogs. We could display the pro dialog here, but it causes
// some odd issues when LimeWire is brought back up from the tray
if (visible && !_visibleOnce) {
// Show the startup dialogs in the swing thread.
showDialogsForFirstVisibility();
_visibleOnce = true;
}
}
});
}
/**
* Displays various dialog boxes that should only be shown the first
* time the application is made visible.
*/
private static final void showDialogsForFirstVisibility() {
if (!hasDonated())
UpgradeWindow.showProDialog();
if (!_displayedMessage &&
ResourceManager.hasLocalizedTipsOfTheDay() && StartupSettings.SHOW_TOTD.getValue()) {
ThreadFactory.startThread(new Runnable() {
public void run() {
try {
Thread.sleep(500);
} catch (Throwable t) { }
TipOfTheDayMediator.instance().displayTipWindow();
}
}, "TOTD");
}
}
/**
* Displays a dialog the first time a user performs a download.
* Returns true iff the user selects 'Yes'; returns false otherwise.
*/
public static boolean showFirstDownloadDialog() {
if (MessageService.YES_OPTION ==
showYesNoCancelMessage("DOWNLOAD_SHOW_FIRST_DOWNLOAD_WARNING",
QuestionsHandler.SKIP_FIRST_DOWNLOAD_WARNING))
return true;
return false;
}
/**
* Closes any dialogues that are displayed at startup and sets the flag to
* indicate that we've displayed a message.
*/
private static void closeStartupDialogs() {
if(SplashWindow.instance().isShowing())
SplashWindow.instance().toBack();
_displayedMessage = true;
TipOfTheDayMediator.instance().hide();
}
/**
* Checks to see if we should notify the user that they're running an
* older version of java.
*/
public void checkForJavaVersion() {
if(CommonUtils.isJavaOutOfDate() && JAVA_CHECK-- == 0) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
UpgradeWindow.showJavaDialog();
}
});
}
}
/**
* Returns a <tt>Dimension</tt> instance containing the dimensions of the
* wrapped JFrame.
*
* @return a <tt>Dimension</tt> instance containing the width and height
* of the wrapped JFrame
*/
public static final Dimension getAppSize() {
return FRAME.getSize();
}
/**
* Returns a <tt>Point</tt> instance containing the x, y position of the
* wrapped <ttJFrame</tt> on the screen.
*
* @return a <tt>Point</tt> instance containting the x, y position of the
* wrapped JFrame
*/
public static final Point getAppLocation() {
return FRAME.getLocation();
}
/**
* Returns the <tt>MainFrame</tt> instance. <tt>MainFrame</tt> maintains
* handles to all of the major gui classes.
*
* @return the <tt>MainFrame</tt> instance
*/
public final MainFrame getMainFrame() {
return MAIN_FRAME;
}
/**
* Returns the main application <tt>JFrame</tt> instance.
*
* @return the main application <tt>JFrame</tt> instance
*/
public static final JFrame getAppFrame() {
return FRAME;
}
/**
* Returns the router service variable for other classes to access.
*
* @return the <tt>RouterService</tt> instance
*/
public final RouterService getRouter() {
return _routerService;
}
/**
* Sets the router service variable for other classes to access.
*
* @param routerService the <tt>RouterService</tt> instance for other
* classes to access
*/
public final void setRouterService(RouterService routerService) {
_routerService = routerService;
}
/**
* Returns the status line instance for other classes to access
*/
public StatusLine getStatusLine() {
return STATUS_LINE;
}
/**
* Refreshes the various gui components that require refreshing.
*/
public final void refreshGUI() {
for (int i = 0; i < REFRESH_LIST.size(); i++) {
try {
((RefreshListener)REFRESH_LIST.get(i)).refresh();
} catch(Throwable t) {
// Show the error for each RefreshListener individually
// so that we continue refreshing the other items.
GUIMediator.showInternalError(t);
}
}
// update the status panel
int sharedFiles = RouterService.getNumSharedFiles();
int pendingShare = RouterService.getNumPendingShared();
int quality = getConnectionQuality();
STATUS_LINE.setStatistics(sharedFiles, pendingShare);
if(quality != StatusLine.STATUS_DISCONNECTED
&& quality != StatusLine.STATUS_CONNECTING) {
hideDisposableMessage(DISCONNECTED_MESSAGE);
}
updateConnectionUI(quality);
}
/**
* Returns the connectiong quality.
*/
public int getConnectionQuality() {
int stable =
RouterService.countConnectionsWithNMessages(STABLE_THRESHOLD);
int status;
if(stable == 0) {
int initializing = CONNECTION_MEDIATOR.getConnectingCount();
int connections = RouterService.getNumInitializedConnections();
// No initializing or stable connections
if(initializing == 0 && connections == 0) {
//Not attempting to connect at all...
if(!RouterService.isConnecting())
status = StatusLine.STATUS_DISCONNECTED;
//Attempting to connect...
else
status = StatusLine.STATUS_CONNECTING;
}
// No initialized, all initializing - connecting
else if(connections == 0)
status = StatusLine.STATUS_CONNECTING;
// Some initialized - poor connection.
else
status = StatusLine.STATUS_POOR;
} else if(RouterService.getConnectionManager().isConnectionIdle()) {
lastIdleTime = System.currentTimeMillis();
status = StatusLine.STATUS_IDLE;
} else {
int preferred = RouterService.getConnectionManager().
getPreferredConnectionCount();
// pro will have more.
if(CommonUtils.isPro())
preferred -= 2;
// ultrapeers don't need as many...
if(RouterService.isSupernode())
preferred -= 5;
preferred = Math.max(1, preferred); // prevent div by 0
double percent = (double)stable / (double)preferred;
if(percent <= 0.25)
status = StatusLine.STATUS_POOR;
else if(percent <= 0.5)
status = StatusLine.STATUS_FAIR;
else if(percent <= 0.75)
status = StatusLine.STATUS_GOOD;
else if(percent <= 1)
status = StatusLine.STATUS_EXCELLENT;
else /* if(percent > 1) */
status = StatusLine.STATUS_TURBOCHARGED;
}
switch(status) {
case StatusLine.STATUS_CONNECTING:
case StatusLine.STATUS_POOR:
case StatusLine.STATUS_FAIR:
case StatusLine.STATUS_GOOD:
// if one of these four, see if we recently woke up from
// idle, and if so, report as 'waking up' instead.
long now = System.currentTimeMillis();
if(now < lastIdleTime + 15 * 1000)
status = StatusLine.STATUS_WAKING_UP;
}
return status;
}
/**
* Sets the visibility state of the options window.
*
* @param visible the visibility state to set the window to
*/
public void setOptionsVisible(boolean visible) {
if (_optionsMediator == null) return;
_optionsMediator.setOptionsVisible(visible);
}
/**
* Sets the visibility state of the options window, and sets
* the selection to a option pane associated with a given key.
*
* @param visible the visibility state to set the window to
* @param key the unique identifying key of the panel to show
*/
public void setOptionsVisible(boolean visible, final String key) {
if (_optionsMediator == null) return;
_optionsMediator.setOptionsVisible(visible, key);
}
/**
* Returns whether or not the options window is visible
*
* @return <tt>true</tt> if the options window is visible,
* <tt>false</tt> otherwise
*/
public static boolean isOptionsVisible() {
if (_optionsMediator == null) return false;
return _optionsMediator.isOptionsVisible();
}
/**
* Gets a handle to the options window main <tt>JComponent</tt> instance.
*
* @return the options window main <tt>JComponent</tt>, or <tt>null</tt>
* if the options window has not yet been constructed (the window is
* guaranteed to be constructed if it is visible)
*/
public static Component getMainOptionsComponent() {
if (_optionsMediator == null) return null;
return _optionsMediator.getMainOptionsComponent();
}
/**
* Sets the visibility of the statistics window.
*
* @param visible the visibility state to set the window to
*/
public final void setStatisticsVisible(boolean visible) {
STATISTICS_MEDIATOR.setStatisticsVisible(visible);
}
/**
* Sets the tab pane to display the given tab.
*
* @param index the index of the tab to display
*/
public void setWindow(int index) {
MAIN_FRAME.setSelectedIndex(index);
}
/**
* Updates the icon at the specified tab index.
*
* @param index the fixed index of the tab to update
*/
public void updateTabIcon(int index) {
MAIN_FRAME.updateTabIcon(index);
}
/**
* Clear the connections in the connection view.
*/
public void clearConnections() {
CONNECTION_MEDIATOR.clearConnections();
}
/**
* Sets the connected/disconnected visual status of the client.
*
* @param connected the connected/disconnected status of the client
*/
private void updateConnectionUI(int quality) {
STATUS_LINE.setConnectionQuality(quality);
boolean connected =
quality != StatusLine.STATUS_DISCONNECTED;
MENU_MEDIATOR.setConnected(connected);
if (connected == false)
this.setSearching(false);
}
/**
* Returns the total number of uploads for this session.
*
* @return the total number of uploads for this session
*/
public int getTotalUploads() {
return UPLOAD_MEDIATOR.getTotalUploads();
}
/**
* Returns the total number of currently active uploads.
*
* @return the total number of currently active uploads
*/
public int getCurrentUploads() {
return UPLOAD_MEDIATOR.getCurrentUploads();
}
/**
* Returns the total number of downloads for this session.
*
* @return the total number of downloads for this session
*/
public final int getTotalDownloads() {
return DOWNLOAD_MEDIATOR.getTotalDownloads();
}
/**
* Returns the total number of currently active downloads.
*
* @return the total number of currently active downloads
*/
public final int getCurrentDownloads() {
return DOWNLOAD_MEDIATOR.getCurrentDownloads();
}
/**
* Tells the DownloadMediator to open a torrent
*/
public final void openTorrent() {
DOWNLOAD_MEDIATOR.openTorrent();
}
/**
* Tells the DownloadMediator to open a torrent from specified url
*/
public final void openTorrent(final URL url) {
ThreadFactory.startThread(new Runnable() {
public void run() {
try {
RouterService.downloadTorrent(url);
} catch (IOException ioe) {
showError("ERROR_COULD_NOT_OPEN_TORRENT_URL", "\""
+ url.toString() + "\".",
QuestionsHandler.TORRENT_DOWNLOAD_FAILURE);
}
}
}, ".torrent download thread");
}
/**
* Tells the library to add a new top-level (shared) folder.
*/
public final void addSharedLibraryFolder() {
LIBRARY_MEDIATOR.addSharedLibraryFolder();
}
/**
* Returns the active playlist or <code>null</code> if the playlist
* is not enabled.
*/
public static PlaylistMediator getPlayList() {
return MainFrame.getPlaylistMediator();
}
/**
* Determines whether or not the PlaylistMediator is being used this session.
*/
public static boolean isPlaylistVisible() {
// If we are not constructed yet, then make our best guess as
// to visibility. It is actually VERY VERY important that this
// returns the same thing throughout the entire course of the program,
// otherwise exceptions can pop up.
if(!isConstructed())
return PlayerSettings.PLAYER_ENABLED.getValue();
else
return getPlayList() != null && PlayerSettings.PLAYER_ENABLED.getValue();
}
/**
* Runs the appropriate methods to start LimeWire up
* hidden.
*/
public static void startupHidden() {
// sends us to the system tray on windows, ignored otherwise.
GUIMediator.showTrayIcon();
// If on OSX, we must set the framestate appropriately.
if(CommonUtils.isMacOSX())
GUIMediator.hideView();
}
/**
* Notification that visibility is now allowed.
*/
public static void allowVisibility() {
if(!_allowVisible && CommonUtils.isAnyMac())
MacEventHandler.instance().enablePreferences();
_allowVisible = true;
}
/**
* Notification that loading is finished. Updates the status line and
* bumps the AWT thread priority.
*/
public void loadFinished() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Thread awt = Thread.currentThread();
awt.setPriority(awt.getPriority() + 1);
STATUS_LINE.loadFinished();
}
});
}
/**
* Handles a 'reopen' event appropriately.
* Used primarily for allowing LimeWire to be made
* visible after it was started from system startup
* on OSX.
*/
public static void handleReopen() {
// Do not do anything
// if visibility is not allowed yet, as initialization
// is not yet finished.
if(_allowVisible) {
if(!_visibleOnce)
restoreView(); // First make sure it's not minimized
setAppVisible(true); // Then make it visible
// Otherwise (if the above operations were reversed), a tiny
// LimeWire icon would appear in the 'minimized' area of the dock
// for a split second, and the Console would report strange errors
}
}
/**
* Hides the GUI by either sending it to the System Tray or
* minimizing the window. Mimimize behavior occurs on platforms
* which do not support the System Tray.
* @see restoreView
*/
public static void hideView() {
FRAME.setState(Frame.ICONIFIED);
if (CommonUtils.supportsTray())
GUIMediator.setAppVisible(false);
}
/**
* Makes the GUI visible by either restoring it from the System Tray or
* the task bar.
* @see hideView
*/
public static void restoreView() {
// Frame must be visible for setState to work. Make visible
// before restoring.
if (CommonUtils.supportsTray()) {
// below is a little hack to get around odd windowing
// behavior with the system tray on windows. This enables
// us to get LimeWire to the foreground after it's run from
// the startup folder with all the nice little animations
// that we want
// cache whether or not to use our little hack, since setAppVisible
// changes the value of _visibleOnce
boolean doHack = false;
if (!_visibleOnce)
doHack = true;
GUIMediator.setAppVisible(true);
if (ApplicationSettings.DISPLAY_TRAY_ICON.getValue())
GUIMediator.showTrayIcon();
else
GUIMediator.hideTrayIcon();
if (doHack)
restoreView();
}
// If shutdown sequence was initiated, cancel it. Auto shutdown is
// disabled when the GUI is visible.
Finalizer.cancelShutdown();
FRAME.setState(Frame.NORMAL);
}
/**
* Determines the appropriate shutdown behavior based on user settings.
* This implementation decides between exiting the application immediately,
* or exiting after all file transfers in progress are complete.
*/
public static void close(boolean fromFrame) {
if (ApplicationSettings.MINIMIZE_TO_TRAY.getValue()) {
// if we want to minimize to the tray, but LimeWire wasn't
// able to load the tray library, then shutdown after transfers.
if(CommonUtils.supportsTray() && !ResourceManager.instance().isTrayLibraryLoaded())
shutdownAfterTransfers();
else {
applyWindowSettings();
GUIMediator.showTrayIcon();
hideView();
}
} else if (CommonUtils.isMacOSX() && fromFrame) {
//If on OSX, don't close in response to clicking on the 'X'
//as that's not normal behaviour. This can only be done on Java14
//though, because we need access to the
//com.apple.eawt.ApplicationListener.handleReOpenApplication event
//in order to restore the GUI.
GUIMediator.setAppVisible(false);
} else if (ApplicationSettings.SHUTDOWN_AFTER_TRANSFERS.getValue()) {
GUIMediator.shutdownAfterTransfers();
} else {
shutdown();
}
}
/**
* Shutdown the program cleanly.
*/
public static void shutdown() {
Finalizer.shutdown();
}
/**
* Shutdown the program cleanly after all transfers in progress are
* complete. Calling this method causes the GUI to be hidden while the
* application waits to shutdown.
* @see hideView
*/
public static void shutdownAfterTransfers() {
Finalizer.shutdownAfterTransfers();
GUIMediator.hideView();
}
public static void flagUpdate(String toExecute) {
Finalizer.flagUpdate(toExecute);
}
/**
* Shows the "About" menu with more information about the program.
*/
public static final void showAboutWindow() {
new AboutWindow().showDialog();
}
/**
* Shows the user notification area. The user notification icon and
* tooltip created by the NotifyUser object are not modified.
*/
public static void showTrayIcon() {
NotifyUserProxy.instance().addNotify();
}
/**
* Hides the user notification area.
*/
public static void hideTrayIcon() {
// Do not use hideNotify() here, since that will
// create multiple tray icons.
NotifyUserProxy.instance().removeNotify();
}
/**
* Sets the window height, width and location properties to remember the
* next time the program is started.
*/
public static void applyWindowSettings() {
ApplicationSettings.RUN_ONCE.setValue(true);
if (GUIMediator.isAppVisible()) {
// set the screen size and location for the
// next time the application is run.
Dimension dim = GUIMediator.getAppSize();
// only save reasonable sizes to get around a bug on
// OS X that could make the window permanently
// invisible
if((dim.height > 100) && (dim.width > 100)) {
Point loc = GUIMediator.getAppLocation();
ApplicationSettings.APP_WIDTH.setValue(dim.width);
ApplicationSettings.APP_HEIGHT.setValue(dim.height);
ApplicationSettings.WINDOW_X.setValue(loc.x);
ApplicationSettings.WINDOW_Y.setValue(loc.y);
}
}
}
/**
* Serves as a single point of access for any icons used in the program.
*
* @param imageName the name of the icon to return without path
* information, as in "plug"
* @return the <tt>ImageIcon</tt> object specified in the param string
*/
public static final ImageIcon getThemeImage(final String name) {
return ResourceManager.getThemeImage(name);
}
/**
* Returns an ImageIcon for the specified resource.
*/
public static final ImageIcon getImageFromPath(final String loc) {
return ResourceManager.getImageFromPath(loc);
}
/**
* Returns a new <tt>URL</tt> instance for the specified file name.
* The file must be located in the com/limegroup/gnutella/gui/resources
* directory, or this will return <tt>null</tt>.
*
* @param FILE_NAME the name of the file to return a url for without path
* information, as in "about.html"
* @return the <tt>URL</tt> instance for the specified file, or
* <tt>null</tt> if the <tt>URL</tt> could not be loaded
*/
public static URL getURLResource(final String FILE_NAME) {
return ResourceManager.getURLResource(FILE_NAME);
}
/**
* Resets locale options.
*/
public static void resetLocale() {
ResourceManager.resetLocaleOptions();
}
/**
* Returns the locale-specific String from the resource manager.
*
* @return an internationalized <tt>String</tt> instance
* corresponding with the <tt>resourceKey</tt>
*/
public static final String getStringResource(final String resourceKey) {
return ResourceManager.getStringResource(resourceKey);
}
/**
* Return ResourceBundle for use with specific xml schema
*
* @param schemaname the name of schema
* (not the URI but name returned by LimeXMLSchema.getDisplayString)
* @return a ResourceBundle matching the passed in param
*/
public static final ResourceBundle getXMLResourceBundle(final String schemaname) {
return ResourceManager.getXMLResourceBundle(schemaname);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific question message to the user with an input field<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param initialValue the initial input value
* @return a String containing the user input
*/
public static final String showInputMessage(
final String messageKey, String initialValue) {
return MessageService.instance().showInputMessage(
getStringResource(messageKey), initialValue);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user in the form of a yes or no
* question.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @return an integer indicating a yes or a no response from the user
*/
public static final int showYesNoMessage(
final String messageKey) {
return MessageService.instance().showYesNoMessage(
getStringResource(messageKey));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user in the form of a yes or no
* question.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param defaultValue the IntSetting to store/retrieve the default value
* @return an integer indicating a yes or a no response from the user
*/
public static final int showYesNoMessage(
final String messageKey,
final IntSetting defaultValue) {
return MessageService.instance().showYesNoMessage(
getStringResource(messageKey), defaultValue);
}
public static final int showYesNoTitledMessage(
final String messageKey,
final String titleKey) {
return MessageService.instance().showYesNoMessage(
getStringResource(messageKey),
getStringResource(titleKey));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user with a hard-coded <tt>String</tt>
* appended to it. This is in the form of a yes or no question.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param message a second, non-locale-specific message to display, such
* as a filename
* @return an integer indicating a yes or a no response from the user
*/
public static final int showYesNoMessage(
final String messageKey,
final Object message) {
return MessageService.instance().showYesNoMessage(
getStringResource(messageKey) + " " +
message);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user with a hard-coded <tt>String</tt>
* appended to it. This is in the form of a yes or no question.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param defaultValue the IntSetting to store/retrieve the defaultValue
* @return an integer indicating a yes or a no response from the user
*/
public static final int showYesNoMessage(
final String messageKey,
final Object message,
final IntSetting defaultValue) {
return MessageService.instance().showYesNoMessage(
getStringResource(messageKey) + " " +
message, defaultValue);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user with a hard-coded <tt>String</tt>
* in the middle of the message between two locale-specific
* <tt>String</tt> values. This is in the form of a yes or no
* question.<p>
*
* The <tt>messageStartKey</tt> and the <tt>messageEndKey</tt>
* parameters must be keys for locale-specific message <tt>String</tt>s
* and not a hard-coded values.
*
* @param messageStartKey the key for the locale-specific message to
* display at the beginning of the message
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param messageEndKey the key for the locale-specific message to
* display at the end of the message
* @return an integer indicating a yes or a no response from the user.
*/
public static final int showYesNoMessage(
final String messageStartKey,
final Object message,
final String messageEndKey) {
return MessageService.instance().showYesNoMessage(
getStringResource(messageStartKey) + " " +
message + " " +
getStringResource(messageEndKey));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user with a hard-coded <tt>String</tt>
* in the middle of the message between two locale-specific
* <tt>String</tt> values. This is in the form of a yes or no
* question.<p>
*
* The <tt>messageStartKey</tt> and the <tt>messageEndKey</tt>
* parameters must be keys for locale-specific message <tt>String</tt>s
* and not a hard-coded values.
*
* @param messageStartKey the key for the locale-specific message to
* display at the beginning of the message
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param messageEndKey the key for the locale-specific message to
* display at the end of the message
* @param defaultValue the IntSetting that stores/retrieves the defaultValue
* @return an integer indicating a yes or a no response from the user.
*/
public static final int showYesNoMessage(
final String messageStartKey,
final Object message,
final String messageEndKey,
final IntSetting defaultValue) {
return MessageService.instance().showYesNoMessage(
getStringResource(messageStartKey) + " " +
message + " " +
getStringResource(messageEndKey),
defaultValue);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user in the form of a yes or no or cancel
* question.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @return an integer indicating a yes or a no response from the user
*/
public static final int showYesNoCancelMessage(
final String messageKey) {
return MessageService.instance().showYesNoCancelMessage(
getStringResource(messageKey));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user in the form of a yes or no or cancel
* question.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param defaultValue the IntSetting to store/retrieve the default value
* @return an integer indicating a yes or a no response from the user
*/
public static final int showYesNoCancelMessage(
final String messageKey, final IntSetting defaultValue) {
return MessageService.instance().showYesNoCancelMessage(
getStringResource(messageKey), defaultValue);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user with a hard-coded <tt>String</tt>
* appended to it. This is in the form of a yes or no or cancel question.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param message a second, non-locale-specific message to display, such
* as a filename
* @return an integer indicating a yes or a no response from the user
*/
public static final int showYesNoCancelMessage(
final String messageKey,
final Object message) {
return MessageService.instance().showYesNoCancelMessage(
getStringResource(messageKey) + " " +
message);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user with a hard-coded <tt>String</tt>
* appended to it. This is in the form of a yes or no or cancel question.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param defaultValue the IntSetting to store/retrieve the defaultValue
* @return an integer indicating a yes or a no response from the user
*/
public static final int showYesNoCancelMessage(
final String messageKey,
final Object message,
final IntSetting defaultValue) {
return MessageService.instance().showYesNoCancelMessage(
getStringResource(messageKey) + " " +
message, defaultValue);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user with a hard-coded <tt>String</tt>
* in the middle of the message between two locale-specific
* <tt>String</tt> values. This is in the form of a yes or no or cancel
* question.<p>
*
* The <tt>messageStartKey</tt> and the <tt>messageEndKey</tt>
* parameters must be keys for locale-specific message <tt>String</tt>s
* and not a hard-coded values.
*
* @param messageStartKey the key for the locale-specific message to
* display at the beginning of the message
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param messageEndKey the key for the locale-specific message to
* display at the end of the message
* @return an integer indicating a yes or a no response from the user.
*/
public static final int showYesNoCancelMessage(
final String messageStartKey,
final Object message,
final String messageEndKey) {
return MessageService.instance().showYesNoCancelMessage(
getStringResource(messageStartKey) + " " +
message + " " +
getStringResource(messageEndKey));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user with a hard-coded <tt>String</tt>
* in the middle of the message between two locale-specific
* <tt>String</tt> values. This is in the form of a yes or no or cancel
* question.<p>
*
* The <tt>messageStartKey</tt> and the <tt>messageEndKey</tt>
* parameters must be keys for locale-specific message <tt>String</tt>s
* and not a hard-coded values.
*
* @param messageStartKey the key for the locale-specific message to
* display at the beginning of the message
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param messageEndKey the key for the locale-specific message to
* display at the end of the message
* @param defaultValue the IntSetting that stores/retrieves the defaultValue
* @return an integer indicating a yes or a no response from the user.
*/
public static final int showYesNoCancelMessage(
final String messageStartKey,
final Object message,
final String messageEndKey,
final IntSetting defaultValue) {
return MessageService.instance().showYesNoCancelMessage(
getStringResource(messageStartKey) + " " +
message + " " +
getStringResource(messageEndKey),
defaultValue);
}
/**
* Displays the message denoted by <code>messageKey</code> replacing all
* occurrences of {number} in the message string with the arguments given
* in <code>args</code>
* <p>
* For details on the syntax, please see
* {@link MessageFormat#format(java.lang.String, java.lang.Object[])} which
* is used internally.
*/
public static final void showFormattedMessage(final String messageKey,
Object[] args) {
MessageService.instance().showMessage(MessageFormat.format(getStringResource(messageKey), args));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
*/
public static final void showMessage(
final String messageKey) {
MessageService.instance().showMessage(
getStringResource(messageKey));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param ignore the BooleanSetting that stores/retrieves whether or
* not to display this message.
*/
public static final void showMessage(
final String messageKey, final BooleanSetting ignore) {
MessageService.instance().showMessage(
getStringResource(messageKey), ignore);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific disposable message to the user.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param ignore the BooleanSetting that stores/retrieves whether or
* not to display this message.
* @param msgType The <tt>JOptionPane</tt> message type. @see javax.swing.JOptionPane.
* @param msgTitle The title of the message window.
*/
public static final void showDisposableMessage(
final String messageKey,
final BooleanSetting ignore,
int msgType) {
MessageService.instance().showDisposableMessage(
messageKey, GUIMediator.getStringResource(messageKey), ignore, msgType);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Hides a
* locale-specific disposable message.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
*/
public static final void hideDisposableMessage(
final String messageKey) {
MessageService.instance().hideDisposableMessage(
messageKey);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays
* a message to the user with a locale-specific message with a
* hard-coded message appended to it.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param message a second, non-locale-specific message to display, such
* as a filename
*/
public static final void showMessage(
final String messageKey,
final Object message) {
MessageService.instance().showMessage(
getStringResource(messageKey) + " " +
message);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays
* a message to the user with a locale-specific message with a
* hard-coded message appended to it.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param ignore the BooleanSetting that stores/retrieves whether or
* not to display this message.
*/
public static final void showMessage(
final String messageKey,
final Object message,
final BooleanSetting ignore) {
MessageService.instance().showMessage(
getStringResource(messageKey) + " " +
message, ignore);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays
* a message to the user with a locale-specific message with a
* hard-coded message appended to it.<p>
*
* The <tt>messageStartKey</tt> and the <tt>messageEndKey</tt>
* parameters must be keys for locale-specific message
* <tt>String</tt>s and not a hard-coded values.
*
* @param messageStartKey the key for the locale-specific message to
* display at the beginning of the message
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param messageEndKey the key for the locale-specific message to
* display at the end of the message
*/
public static final void showMessage(
final String messageStartKey,
final Object message,
final String messageEndKey) {
MessageService.instance().showMessage(
getStringResource(messageStartKey) + " " +
message + " " +
getStringResource(messageEndKey));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays
* a message to the user with a locale-specific message with a
* hard-coded message appended to it.<p>
*
* The <tt>messageStartKey</tt> and the <tt>messageEndKey</tt>
* parameters must be keys for locale-specific message
* <tt>String</tt>s and not a hard-coded values.
*
* @param messageStartKey the key for the locale-specific message to
* display at the beginning of the message
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param messageEndKey the key for the locale-specific message to
* display at the end of the message
* @param ignore the BooleanSetting for that stores/retrieves whether
* or not to display this message.
*/
public static final void showMessage(
final String messageStartKey,
final Object message,
final String messageEndKey,
final BooleanSetting ignore) {
MessageService.instance().showMessage(
getStringResource(messageStartKey) + " " +
message + " " +
getStringResource(messageEndKey), ignore);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* confirmation message to the user.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
*/
public static final void showConfirmMessage(
final String messageKey) {
MessageService.instance().showConfirmMessage(
getStringResource(messageKey));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* confirmation message to the user.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param ignore the BooleanSetting for that stores/retrieves whether
* or not to display this message.
*/
public static final void showConfirmMessage(
final String messageKey,
final BooleanSetting ignore) {
MessageService.instance().showConfirmMessage(
getStringResource(messageKey), ignore);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays
* a confirmation message to the user.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param message a second, non-locale-specific message to display, such
* as a filename
*/
public static final void showConfirmMessage(
final String messageKey,
final Object message) {
MessageService.instance().showConfirmMessage(
getStringResource(messageKey) + " " +
message);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays
* a confirmation message to the user.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param ignore the BooleanSetting for that stores/retrieves whether
* or not to display this message.
*/
public static final void showConfirmMessage(
final String messageKey,
final Object message,
final BooleanSetting ignore) {
MessageService.instance().showConfirmMessage(
getStringResource(messageKey) + " " +
message, ignore);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* confirmation message to the user.<p>
*
* The <tt>messageStartKey</tt> and the <tt>messageEndKey</tt>
* parameters must be keys for locale-specific message <tt>String</tt>s
* and not a hard-coded values.
*
* @param messageStartKey the key for the locale-specific message to
* display at the beginning of the message
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param messageEndKey the key for the locale-specific message to
* display at the end of the message
*/
public static final void showConfirmMessage(
final String messageStartKey,
final Object message,
final String messageEndKey) {
MessageService.instance().showConfirmMessage(
getStringResource(messageStartKey) + " " +
message + " " +
getStringResource(messageEndKey));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* confirmation message to the user.<p>
*
* The <tt>messageStartKey</tt> and the <tt>messageEndKey</tt>
* parameters must be keys for locale-specific message <tt>String</tt>s
* and not a hard-coded values.
*
* @param messageStartKey the key for the locale-specific message to
* display at the beginning of the message
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param messageEndKey the key for the locale-specific message to
* display at the end of the message
* @param ignore the BooleanSetting for that stores/retrieves whether
* or not to display this message.
*/
public static final void showConfirmMessage(
final String messageStartKey,
final Object message,
final String messageEndKey,
final BooleanSetting ignore) {
MessageService.instance().showConfirmMessage(
getStringResource(messageStartKey) + " " +
message + " " +
getStringResource(messageEndKey), ignore);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display.
*/
public static final void showError(
final String messageKey) {
closeStartupDialogs();
MessageService.instance().showError(
getStringResource(messageKey));
//closeStartupDialogs();
}
public static final void showTranslatedError(String error) {
closeStartupDialogs();
MessageService.instance().showError(error);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display.
* @param ignore the BooleanSetting for that stores/retrieves whether
* or not to display this message.
*/
public static final void showError(
final String messageKey,
final BooleanSetting ignore) {
closeStartupDialogs();
MessageService.instance().showError(
getStringResource(messageKey), ignore);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific warning message to the user.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display.
* @param ignore the BooleanSetting for that stores/retrieves whether
* or not to display this message.
*/
public static final void showWarning(
final String messageKey,
final BooleanSetting ignore) {
closeStartupDialogs();
MessageService.instance().showWarning(
getStringResource(messageKey), ignore);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific warning message to the user.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
*
* @param messageKey the key for the locale-specific message to display.
*/
public static final void showWarning(final String messageKey) {
closeStartupDialogs();
MessageService.instance().showWarning(getStringResource(messageKey));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user with a hard-coded message
* appended to it at the end.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
* <p>
* For a more flexible way of choosing the place of the hard-coded value see
* {@link #showFormattedError(String, Object[]).
*
* @param messageKey the key for the locale-specific message to display
* @param message a second, non-locale-specific message to display, such
* as a filename
*/
public static final void showError(
final String messageKey,
final Object message) {
closeStartupDialogs();
MessageService.instance().showError(
getStringResource(messageKey) + " " +
message);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user with a hard-coded message
* appended to it at the end.<p>
*
* The <tt>messageKey</tt> parameter must be the key for a locale-
* specific message <tt>String</tt> and not a hard-coded value.
* <p>
* For a more flexible way of choosing the place of the hard-coded value see
* {@link #showFormattedError(String, Object[], BooleanSetting)}.
*
* @param messageKey the key for the locale-specific message to display
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param ignore the BooleanSetting for that stores/retrieves whether
* or not to display this message.
*/
public static final void showError(
final String messageKey,
final Object message,
final BooleanSetting ignore) {
closeStartupDialogs();
MessageService.instance().showError(
getStringResource(messageKey) + " " +
message, ignore);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user with a hard-coded names inbetween, which
* can appear anywhere within the localized text by making use of
* {@link MessageFormat#format(java.lang.String, java.lang.Object[])}.
* <p>
* A call to:
* <pre>
* KEY="the file {0} is moved to directory {1}."
* GUIMediator.showFormattedError(KEY,
* new Object[] { "text.txt", "/home/user"});
* </pre>
* would tranlate to:
* <pre>
* "the file text.txt is moved to directory /home/user"
* </pre>
* <p>
* For more details see {@link MessageFormat}.
*
* @param messageKey
* @param objs array of hardcoded object which will be merged into the
* messageKey's translation.
*
*/
public static final void showFormattedError(
final String messageKey,
final Object[] objs) {
closeStartupDialogs();
MessageService.instance().showError(
MessageFormat.format(getStringResource(messageKey), objs));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays a
* locale-specific message to the user with a hard-coded names inbetween, which
* can appear anywhere within the localized text by making use of
* {@link MessageFormat#format(java.lang.String, java.lang.Object[])}.
* <p>
* A call to:
* <pre>
* KEY="the file {0} is moved to directory {1}."
* GUIMediator.showFormattedError(KEY,
* new Object[] { "text.txt", "/home/user"}, booleanSetting);
* </pre>
* would tranlate to:
* <pre>
* "the file text.txt is moved to directory /home/user"
* </pre>
* <p>
* For more details see {@link MessageFormat}.
*
* @param messageKey
* @param objs
* @param ignore
*/
public static final void showFormattedError(
final String messageKey,
final Object[] objs,
final BooleanSetting ignore) {
closeStartupDialogs();
MessageService.instance().showError(
MessageFormat.format(getStringResource(messageKey), objs),
ignore);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays
* a message to the user with a locale-specific message with a
* hard-coded message appended to it.<p>
*
* The <tt>messageStartKey</tt> and the <tt>messageEndKey</tt>
* parameters must be keys for locale-specific message
* <tt>String</tt>s and not a hard-coded values.
*
* @param messageStartKey the key for the locale-specific message to
* display at the beginning of the message
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param messageEndKey the key for the locale-specific message to
* display at the end of the message
*/
public static final void showError(
final String messageStartKey,
final Object message,
final String messageEndKey) {
closeStartupDialogs();
MessageService.instance().showError(
getStringResource(messageStartKey) + " " +
message + " " +
getStringResource(messageEndKey));
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class. Displays
* a message to the user with a locale-specific message with a
* hard-coded message appended to it.<p>
*
* The <tt>messageStartKey</tt> and the <tt>messageEndKey</tt>
* parameters must be keys for locale-specific message
* <tt>String</tt>s and not a hard-coded values.
*
* @param messageStartKey the key for the locale-specific message to
* display at the beginning of the message
* @param message a second, non-locale-specific message to display, such
* as a filename
* @param messageEndKey the key for the locale-specific message to
* display at the end of the message
* @param ignore the BooleanSetting for that stores/retrieves whether
* or not to display this message.
*/
public static final void showError(
final String messageStartKey,
final Object message,
final String messageEndKey,
final BooleanSetting ignore) {
closeStartupDialogs();
MessageService.instance().showError(
getStringResource(messageStartKey) + " " +
message + " " +
getStringResource(messageEndKey), ignore);
}
/**
* Acts as a proxy for the <tt>MessageService</tt> class.
* @param t a Throwable object for displaying more information to the user
* @param detail A detailed message to display with the error
* @param curThread the thread the error occured in.
*/
public static final void showInternalError(Throwable t, String detail, String threadName) {
closeStartupDialogs();
BugManager.instance().handleBug(t, threadName, detail);
}
/**
* Stub for calling showInternalError(t, null, Thread.currentThread())
*
* @param t a Throwable object for displaying more information to the user
*/
public static final void showInternalError(Throwable t) {
closeStartupDialogs();
showInternalError(t, null, Thread.currentThread().getName());
}
/**
* Stub for calling showInternalError(t, null, curThread)
*
* @param t a Throwable object for displaying more information to the user
* @param curThread the thread the error occured in
*/
public static final void showInternalError(Throwable t, String threadName) {
closeStartupDialogs();
showInternalError(t, null, threadName);
}
/**
* Acts as a proxy for the Launcher class so that other classes only need
* to know about this mediator class.
*
* <p>Opens the specified url in a browser.
*
* @param url the url to open
* @return an int indicating the success of the browser launch
*/
public static final int openURL(String url) {
try {
return Launcher.openURL(url);
} catch(IOException ioe) {
GUIMediator.showError("ERROR_OPEN_URL", url + ".");
return -1;
}
}
/**
* Acts as a proxy for the Launcher class so that other classes only need
* to know about this mediator class.
*
* <p>Launches the file specified in its associated application.
*
* @param file a <tt>File</tt> instance denoting the abstract pathname
* of the file to launch
* @return an int indicating the success of the file launch
* @throws IOException if the file cannot be launched do to an IO problem
*/
public static final int launchFile(File file) throws IOException {
try {
return Launcher.launchFile(file);
} catch (SecurityException se) {
showError("MESSAGE_FILE_LAUNCHING_SECURITY_MESSAGE");
}
return -1;
}
/**
* Returns a <tt>Component</tt> standardly sized for horizontal separators.
*
* @return the constant <tt>Component</tt> used as a standard horizontal
* separator
*/
public static final Component getHorizontalSeparator() {
return Box.createRigidArea(new Dimension(6,0));
}
/**
* Returns a <tt>Component</tt> standardly sized for vertical separators.
*
* @return the constant <tt>Component</tt> used as a standard vertical
* separator
*/
public static final Component getVerticalSeparator() {
return Box.createRigidArea(new Dimension(0,6));
}
/**
* Connects the user from the network.
*/
public void connect() {
RouterService.connect();
}
/**
* Disconnects the user to the network.
*/
public void disconnect() {
RouterService.disconnect();
}
/**
* Notifies the user that LimeWire is disconnected
*/
public static void disconnected() {
showDisposableMessage(
DISCONNECTED_MESSAGE,
QuestionsHandler.NO_INTERNET_RETRYING,
JOptionPane.ERROR_MESSAGE);
}
/**
* Returns a <tt>boolean</tt> specifying whether or not the user has
* donated to the LimeWire project.
*
* @return <tt>true</tt> if the user has donated, <tt>false</tt> otherwise
*/
public static boolean hasDonated() {
return HAS_DONATED;
}
/**
* Sets the visible/invisible state of the tab associated with the
* specified index. The indeces correspond to the order of the tabs
* whether or not they are visible, as specified by the tab indices in
* this class.
*
* @param TAB_INDEX the index of the tab to make visible or invisible
* @param VISIBLE the visible/invisible state to set the tab to
*/
public void setTabVisible(final int TAB_INDEX, final boolean VISIBLE) {
MAIN_FRAME.setTabVisible(TAB_INDEX, VISIBLE);
}
/**
* Modifies the text displayed to the user in the splash screen to
* provide application loading information.
*
* @param text the text to display
*/
public static void setSplashScreenString(String text) {
if(!_allowVisible)
SplashWindow.setStatusText(text);
else if(isConstructed())
instance().STATUS_LINE.setStatusText(text);
}
/**
* Returns the point for the placing the specified component on the
* center of the screen.
*
* @param comp the <tt>Component</tt> to use for getting the relative
* center point
* @return the <tt>Point</tt> for centering the specified
* <tt>Component</tt> on the screen
*/
public static Point getScreenCenterPoint(Component comp) {
final Dimension COMPONENT_DIMENSION = comp.getSize();
Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
int appWidth = Math.min(screenSize.width,
COMPONENT_DIMENSION.width);
// compare against a little bit less than the screen size,
// as the screen size includes the taskbar
int appHeight = Math.min(screenSize.height - 40,
COMPONENT_DIMENSION.height);
return new Point((screenSize.width - appWidth) / 2,
(screenSize.height - appHeight) / 2);
}
/**
* Adds the <tt>FinalizeListener</tt> class to the list of classes that
* should be notified of finalize events.
*
* @param fin the <tt>FinalizeListener</tt> class that should be notified
*/
public static void addFinalizeListener(FinalizeListener fin) {
Finalizer.addFinalizeListener(fin);
}
/**
* Sets the searching or not searching status of the application.
*
* @param searching the searching status of the application
*/
public void setSearching(boolean searching) {
MAIN_FRAME.setSearching(searching);
}
/**
* Adds the specified <tt>RefreshListener</tt> instance to the list of
* listeners to be notified when a UI refresh event occurs.
*
* @param the new <tt>RefreshListener</tt> to add
*/
public static void addRefreshListener(RefreshListener listener) {
if (!REFRESH_LIST.contains(listener))
REFRESH_LIST.add(listener);
}
/**
* Removes the specified <tt>RefreshListener</tt> instance from the list
* of listeners to be notified when a UI refresh event occurs.
*
* @param the <tt>RefreshListener</tt> to remove
*/
public static void removeRefreshListener(RefreshListener listener) {
REFRESH_LIST.remove(listener);
}
/**
* Returns the <tt>Locale</tt> instance currently in use.
*
* @return the <tt>Locale</tt> instance currently in use
*/
public static Locale getLocale() {
return ResourceManager.getLocale();
}
/**
* Launches the specified audio file in the player.
*
* @param file the <tt>File</tt> instance to launch
*/
public void launchAudio(File file) {
MediaPlayerComponent.launchAudio(file);
}
/**
* Makes the update message show up in the status panel
*/
public void showUpdateNotification(UpdateInformation info) {
boolean popup = info.getUpdateCommand() != null;
STATUS_LINE.showUpdatePanel(popup, info);
}
/**
* Trigger a search based on a string.
*
* @param query the query <tt>String</tt>
* @return the GUID of the query sent to the network.
* Used mainly for testing
*/
public byte[] triggerSearch(String query) {
MAIN_FRAME.setSelectedIndex(SEARCH_INDEX);
return SearchMediator.triggerSearch(query);
}
/**
* Notification that the button state has changed.
*/
public void buttonViewChanged() {
IconManager.instance().wipeButtonIconCache();
updateButtonView(FRAME);
}
private void updateButtonView(Component c) {
if (c instanceof IconButton) {
((IconButton) c).updateUI();
}
Component[] children = null;
if (c instanceof Container) {
children = ((Container)c).getComponents();
}
if (children != null) {
for(int i = 0; i < children.length; i++) {
updateButtonView(children[i]);
}
}
}
/**
* trigger a browse host based on address and port
*/
public void doBrowseHost(String address, int port) {
MAIN_FRAME.setSelectedIndex(SEARCH_INDEX);
SearchMediator.doBrowseHost(address, port, null);
}
/**
* safely run code synchroneously in the event dispatching thread.
*/
public static void safeInvokeAndWait(Runnable runnable) {
if (EventQueue.isDispatchThread())
runnable.run();
else {
try {
SwingUtilities.invokeAndWait(runnable);
} catch (InvocationTargetException ite) {
Throwable t = ite.getTargetException();
if(t instanceof Error)
throw (Error)t;
else if(t instanceof RuntimeException)
throw (RuntimeException)t;
else
ErrorService.error(t);
} catch(InterruptedException ignored) {}
}
}
/**
* InvokesLater if not already in the dispatch thread.
*/
public static void safeInvokeLater(Runnable runnable) {
if (EventQueue.isDispatchThread())
runnable.run();
else
SwingUtilities.invokeLater(runnable);
}
/**
* Changes whether the media player is enabled and updates the GUI accordingly.
*/
public void setPlayerEnabled(boolean value) {
if (value == PlayerSettings.PLAYER_ENABLED.getValue())
return;
PlayerSettings.PLAYER_ENABLED.setValue(value);
getStatusLine().refresh();
LIBRARY_MEDIATOR.setPlayerEnabled(value);
LibraryPlayListTab.setPlayerEnabled(value);
}
}