/*
* Copyright (c) 2006 Universitaet Kassel
*
* E-Mail : lado@student.uni-kassel.de
* Original Filename: org.dgpf.gui.DGPFFrame.java
*
* License : GNU LESSER GENERAL PUBLIC LICENSE
* Version 2.1, February 1999
* You should have received a copy of this license along
* with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307, USA or download the license under
* http://www.gnu.org/copyleft/lesser.html.
*
* Warranty : This software is provided "as is" without any
* warranty; without even the implied warranty of
* merchantability or fitness for a particular purpose.
* See the Gnu Lesser General Public License for more
* details.
*/
package org.dgpf.gui;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyVetoException;
import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import javax.swing.border.BevelBorder;
import org.dgpf.gui.actions.AbortSeAction;
import org.dgpf.gui.actions.CloseAction;
import org.dgpf.gui.actions.CloseAllAction;
import org.dgpf.gui.actions.MinimizeAction;
import org.dgpf.gui.actions.UnminimizeAction;
import org.dgpf.gui.components.DGPFFileFilter;
import org.dgpf.gui.components.FileChooser;
import org.dgpf.gui.components.MenuBar;
import org.dgpf.gui.components.SplitPane;
import org.dgpf.gui.dialogs.AboutDialog;
import org.dgpf.gui.dialogs.ConnectToHostDialog;
import org.dgpf.gui.dialogs.HostlistEditor;
import org.dgpf.gui.dialogs.SettingsDialog;
import org.dgpf.gui.dialogs.StartJarDialog;
import org.dgpf.gui.utils.BrowserLaunch;
import org.dgpf.gui.utils.Host;
import org.dgpf.gui.utils.HostListUtils;
import org.dgpf.gui.utils.LanguageSwitcher;
import org.dgpf.gui.utils.PrefUtils;
/**
* @author Lado Kumsiashvili
*/
public class Frame extends JFrame implements ActionListener,
MouseListener, WindowListener
{
/**
* serialVersionUID.
*/
private static final long serialVersionUID = 1L;
/**
* Default offset when a new InternalFrame
is created.
*/
private static final int DEFAULT_IFRAME_OFFSET = 40;
/**
* The DGPF client.
*/
private Client m_client;
/**
* The main contentPane.
*/
private Container m_contentPane;
/**
* The main menu bar.
*/
private MenuBar m_menuBar;
/**
* The internal desktop managing client windows.
*/
DesktopPane m_desktop;
/**
* The statusBar bar.
*/
private JPanel m_statusBar;
/**
* Shows the user's current host list.
*/
private JLabel m_statusHostlist;
/**
* Shows info about the connected daemons.
*/
private JLabel m_statusDaemons;
/**
* List holding
*/
final private JList m_list = new JList();
/**
* Separates dekstop from host list/infopanel.
*/
SplitPane m_splitPane;
/**
* Separates infopanel from host list.
*/
SplitPane m_subSplitPane;
/**
* Shows a Host infopanel, derived from a DGPFInternalframe.
*/
private InfoPanel m_infoPanel = new InfoPanel();
/**
* Class constructor.
*
* @param p_client
* The DGPF client.
* @param p_title
* Frame title.
*/
public Frame(Client p_client, String p_title)
{
super(p_title);
this.m_client = p_client;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.m_contentPane = getContentPane();
this.m_contentPane.setLayout(new BorderLayout());
/* Internal desktop */
this.m_desktop = new DesktopPane();
this.m_splitPane = new SplitPane(JSplitPane.HORIZONTAL_SPLIT, true,
true);
this.m_subSplitPane = new SplitPane(JSplitPane.VERTICAL_SPLIT, true,
true);
this.m_splitPane.setLeftComponent(this.m_desktop);
this.m_list.setListData(this.m_desktop.getFrames());
this.m_list.addMouseListener(this);
JScrollPane l_scrollPane = new JScrollPane(this.m_list);
this.m_subSplitPane.setTopComponent(l_scrollPane);
this.m_subSplitPane.setBottomComponent(new JScrollPane(
this.m_infoPanel));
this.m_splitPane.setRightComponent(this.m_subSplitPane);
this.m_splitPane.setDividerLocation(600);
this.m_subSplitPane.setDividerLocation(300);
this.m_contentPane.add(this.m_splitPane, BorderLayout.CENTER);
/* Menu bar */
this.m_menuBar = new MenuBar(this);
setJMenuBar(this.m_menuBar);
/* Status bar */
this.m_statusBar = new JPanel();
this.m_statusBar.setLayout(new BorderLayout());
this.m_statusHostlist = new JLabel();
this.m_statusHostlist.setBorder(new BevelBorder(BevelBorder.LOWERED));
updateHostlistText();
this.m_statusBar.add(this.m_statusHostlist, BorderLayout.CENTER);
this.m_statusDaemons = new JLabel();
this.m_statusDaemons.setBorder(new BevelBorder(BevelBorder.LOWERED));
updateDaemonsDisplay();
this.m_statusBar.add(this.m_statusDaemons, BorderLayout.EAST);
this.m_contentPane.add(this.m_statusBar, BorderLayout.SOUTH);
this.addWindowListener(this);
setSavedLayout();
}
/**
* Updates the text in the bottom status bar.
*/
public void updateHostlistText()
{
String l_text = this.m_desktop.getFrames().size() + " "
+ LanguageSwitcher.getString("frame_status_text_hosts");
if(this.m_client.getHostlistFilename() != null
&& this.m_client.getHostlistFilename() != "")
{
l_text += " (" + this.m_client.getHostlistFilename() + ")";
}
this.m_statusHostlist.setText(l_text);
}
/**
* React on menu clicks.Search
*
* @param p_event to be handled.
*/
public void actionPerformed(ActionEvent p_event)
{
String l_cmd = p_event.getActionCommand();
/* file menu */
if(l_cmd.equals("mb_connect_to_host_frame"))
{
new ConnectToHostDialog(this);
return;
}
/* connect to list of hosts */
if(l_cmd.equals("mb_connect_to_hosts"))
{
File l_file = null;
if(this.m_client.getHostlist().size() < 1)
{
FileChooser l_fileChooser = new FileChooser();
String suggestedFile = PrefUtils.getString(LanguageSwitcher
.getString("history.last_opend_host_list"), LanguageSwitcher
.getString("hle_fc_default_file"));
l_file = l_fileChooser.getFile(LanguageSwitcher
.getString("hle_fc_panel_caption"), new DGPFFileFilter(
LanguageSwitcher.getString("hle_fc_filefilter"), "xml"),
suggestedFile, LanguageSwitcher.getString("btn_open"));
// read hostlist from file
if(l_file != null && l_file.canRead())
{
Vector l_hostList = null;
try
{
l_hostList = HostListUtils.getHosts(l_file);
this.m_client.setHostlist(l_file.getCanonicalPath(), l_hostList);
}
catch(Exception e)
{
JOptionPane.showMessageDialog(this, LanguageSwitcher
.getString("msgb_hle_file_error"), LanguageSwitcher
.getString("msgb_name_error"), JOptionPane.ERROR_MESSAGE);
}
PrefUtils.putString(LanguageSwitcher
.getString("history.last_opend_host_list"), l_file
.getAbsolutePath());
}
}
for(Host l_h : this.getClient().getHostlist())
{
createInternalFrame(l_h);
}
return;
}
if(l_cmd.equals("start_jar"))
{
new StartJarDialog(this, this.m_desktop.getFrames().toArray(
new InternalFrame[] {}));
return;
}
if(l_cmd.equals("exit"))
{
// close all connection
for(InternalFrame l_iframe : this.m_desktop.getFrames())
{
l_iframe.closeCon();
}
System.exit(0);
}
/* edit menu */
if(l_cmd.equals("hostlist_editor"))
{
new HostlistEditor(this.m_client, this);
return;
}
if(l_cmd.equals("settings"))
{
new SettingsDialog(this);
return;
}
/* help menu */
if(l_cmd.equals("homepage"))
{
BrowserLaunch.openURL("http://dgpf.sourceforge.net/");
return;
}
if(l_cmd.equals("docs"))
{
BrowserLaunch
.openURL("http://dgpf.sourceforge.net/documents/index.php");
return;
}
if(l_cmd.equals("javadocs"))
{
BrowserLaunch
.openURL("http://dgpf.sourceforge.net/documents/documentation/index.html");
return;
}
if(l_cmd.equals("join"))
{
BrowserLaunch
.openURL("http://dgpf.sourceforge.net/developers/join.php");
return;
}
if(l_cmd.equals("about"))
{
new AboutDialog(this);
return;
}
p_event.getSource();
}
/**
* Creates a new DGPFInternalFrame
that will connect to a
* Daemon
.
*
* @param p_host
* is the Host
to connect to.
*/
public void createInternalFrame(Host p_host)
{
// check if already connected to this host
for(InternalFrame l_frame : this.m_desktop.getFrames())
{
if(l_frame.getHost().equals(p_host))
{
return;
}
}
// create frame and connect
try
{
String l_name = null;
if(p_host != null)
{
l_name = p_host.getHostname() + ":" + p_host.getPort();
}
else
{
l_name = LanguageSwitcher.getString("se_local");
}
int l_iframe_offset = this.m_desktop.getFrames().size()
* Frame.DEFAULT_IFRAME_OFFSET;
InetSocketAddress l_inetSocketAddress = new InetSocketAddress(p_host.getHostname(), p_host.getPort());
Socket l_socket = new Socket();
l_socket.connect(l_inetSocketAddress,3000);
String l_logFile = null;
if (PrefUtils.getBoolean("log_se", false))
{
l_logFile = PrefUtils.getString("log_se_dir", null);
}
this.getDesktopPane().add(
new InternalFrame(this, l_name, l_iframe_offset, l_iframe_offset,
InternalFrame.getDefaultDimension(), l_logFile, l_socket, p_host));
}
catch(NumberFormatException e)
{
JOptionPane.showMessageDialog(this, LanguageSwitcher
.getString("msgb_invalid_port"), LanguageSwitcher
.getString("msgb_name_error"), JOptionPane.ERROR_MESSAGE);
return;
}
catch(SocketTimeoutException ste)
{
JOptionPane.showMessageDialog(this, LanguageSwitcher
.getString("msgb_conn_refused")
+ p_host.getHostname(), LanguageSwitcher
.getString("msgb_name_error"), JOptionPane.ERROR_MESSAGE);
return;
}
catch(ConnectException e)
{
JOptionPane.showMessageDialog(this, LanguageSwitcher
.getString("msgb_conn_refused")
+ p_host.getHostname(), LanguageSwitcher
.getString("msgb_name_error"), JOptionPane.ERROR_MESSAGE);
return;
}
catch(SocketException e)
{
JOptionPane.showMessageDialog(this, LanguageSwitcher
.getString("msgb_conn_refused")
+ p_host.getHostname(), LanguageSwitcher
.getString("msgb_name_error"), JOptionPane.ERROR_MESSAGE);
return;
}
catch(UnknownHostException e)
{
JOptionPane.showMessageDialog(this, LanguageSwitcher
.getString("msgb_conn_refused")
+ p_host.getHostname(), LanguageSwitcher
.getString("msgb_name_error"), JOptionPane.ERROR_MESSAGE);
return;
}
catch(IOException e)
{
e.printStackTrace();
return;
}
updateInfos();
}
/**
* updates all daemon size and host list on Frame.
*/
public void updateInfos()
{
updateList(); // updating jlist.
updateDaemonsDisplay(); // update daemons count.
}
/**
* @return desktopPane.
*/
public DesktopPane getDesktopPane()
{
return this.m_desktop;
}
/**
* Updates the text for the daemon info display in the status bar.
*/
private void updateDaemonsDisplay()
{
this.m_statusDaemons.setText(LanguageSwitcher
.getString("frame_status_daemons_pre")
+ " "
+ this.m_desktop.getFrames().size()
+ " "
+ LanguageSwitcher.getString("frame_status_daemons_post"));
}
/**
* @return Returns the client.
*/
public final Client getClient()
{
return this.m_client;
}
/**
* Getter for list.
*
* @return list
*/
public JList getList()
{
return this.m_list;
}
/**
* Updates the jlist.
*/
private void updateList()
{
this.m_list.updateUI();
}
/**
* Invoked when the mouse button has been clicked (pressed and released)
* on a component.
*
* @param p_event
* a MouseEvent.
*/
public void mouseClicked(MouseEvent p_event)
{
Point l_p = p_event.getPoint();
int l_index = this.m_list.locationToIndex(l_p);
if(this.m_desktop.getFrames().size() < 1)
{
return;
}
InternalFrame l_frame = this.m_desktop.getFrames().get(l_index);
if(SwingUtilities.isRightMouseButton(p_event)
&& !this.m_list.isSelectionEmpty()
&& this.m_list.locationToIndex(p_event.getPoint()) == this.m_list
.getSelectedIndex())
{
JPopupMenu l_menu = new JPopupMenu();
JMenuItem l_menuitem = new JMenuItem(new CloseAction(l_frame));
l_menuitem.setMnemonic(LanguageSwitcher.getChar("actions.close_mnemo"));
l_menu.add(l_menuitem);
l_menuitem = new JMenuItem(new CloseAllAction(getAllFrames()
.toArray(new InternalFrame[] {})));
l_menuitem.setMnemonic(LanguageSwitcher.getChar("actions.close_all_mnemo"));
l_menu.add(l_menuitem);
if(!l_frame.isIcon())
{
l_menuitem = new JMenuItem(new MinimizeAction(l_frame));
l_menuitem.setMnemonic(LanguageSwitcher.getChar("actions.minimize_mnemo"));
}
else
{
l_menuitem = new JMenuItem(new UnminimizeAction(l_frame));
l_menuitem.setMnemonic(LanguageSwitcher.getChar("actions.unminimize_mnemo"));
}
l_menu.add(l_menuitem);
l_menuitem = new JMenuItem(new AbortSeAction(this.m_client,
getFrameAt(l_index).getCp()));
l_menuitem.setMnemonic(LanguageSwitcher.getChar("actions.abortse_mnemo"));
l_menu.add(l_menuitem);
l_menu.show(this.m_list, p_event.getX(), p_event.getY());
}
if(getAllFrames().size() <= l_index)
{
return;
}
int click = p_event.getClickCount();
if(click == 1)
{
try
{
getFrameAt(l_index).moveToFront();
getFrameAt(l_index).setSelected(true);
this.m_infoPanel.getConnectedSince().setText(
getFrameAt(l_index).getSeInfo().getConnectedSince());
}
catch(PropertyVetoException e1)
{
e1.printStackTrace();
}
}
else
if(click == 2)
{
DesktopPane.toggleFrameMaximized(l_frame);
}
}
/**
* New panel to set.
*
* @param p_panel
* panel to set.
*/
public void toggleSeInfo(JPanel p_panel)
{
int l_prevLocation = this.m_subSplitPane.getDividerLocation();
this.m_subSplitPane.setBottomComponent(new JScrollPane(p_panel));
this.m_subSplitPane.setDividerLocation(l_prevLocation);
}
/**
* Invoked when a mouse button has been pressed on a component.
*
* @param p_e
* a MouseEvent.
*/
public void mousePressed(MouseEvent p_e)
{
// Nothing yet.
}
/**
* Invoked when a mouse button has been released on a component.
*
* @param p_e
* a MouseEvent.
*/
public void mouseReleased(MouseEvent p_e)
{
// Nothing yet.
}
/**
* Invoked when the mouse enters a component.
*
* @param p_e
* a MouseEvent.
*/
public void mouseEntered(MouseEvent p_e)
{
// Nothing yet.
}
/**
* Invoked when the mouse exits a component.
*
* @param p_e
* a MouseEvent.
*/
public void mouseExited(MouseEvent p_e)
{
// Nothing yet.
}
/**
* Retrurns all internalframes.
*
* @return all internal frames.
*/
public Vector getAllFrames()
{
return this.m_desktop.getFrames();
}
/**
* Gets an InternalFrame at a given position.
*
* @param p_position
* to get JInternalFrame.
* @return a JInternalFrame at a given position.
*/
public InternalFrame getFrameAt(int p_position)
{
return getAllFrames().get(p_position);
}
/**
* Getter for hostInfo.
*
* @return hostInfo.
*/
public JPanel getInfoPanel()
{
return this.m_infoPanel;
}
/**
* Setter for hostInfo.
*
* @param p_panel
* hostInfo JPanel to set.
*/
public void setInfoPanel(InfoPanel p_panel)
{
this.m_infoPanel = p_panel;
}
/**
* Clears the fields.
*/
public void clearInfo()
{
this.m_infoPanel.clearInfo();
}
/**
* @see java.awt.event.WindowListener#windowOpened(java.awt.event.WindowEvent)
* @param l_arg0
*/
public void windowOpened(WindowEvent l_arg0)
{
// Nothing yet.
}
/**
* @see java.awt.event.WindowListener#windowClosing(java.awt.event.WindowEvent)
* @param p_arg0
*/
public void windowClosing(WindowEvent p_arg0)
{
saveLayout();
}
/**
* @see java.awt.event.WindowListener#windowClosed(java.awt.event.WindowEvent)
* @param arg0 WindowEvent to handle.
*/
public void windowClosed(WindowEvent arg0)
{
// Nothing yet.
}
/**
* @see java.awt.event.WindowListener#windowIconified(java.awt.event.WindowEvent)
* @param p_arg0
*/
public void windowIconified(WindowEvent p_arg0)
{
// Nothing yet.
}
/**
* @see java.awt.event.WindowListener#windowDeiconified(java.awt.event.WindowEvent)
* @param p_arg0
*/
public void windowDeiconified(WindowEvent p_arg0)
{
// Nothing yet.
}
/**
* @see java.awt.event.WindowListener#windowActivated(java.awt.event.WindowEvent)
* @param p_arg0
*/
public void windowActivated(WindowEvent p_arg0)
{
// Nothing yet.
}
/**
* @see java.awt.event.WindowListener#windowDeactivated(java.awt.event.WindowEvent)
* @param p_arg0
*/
public void windowDeactivated(WindowEvent p_arg0)
{
// Nothing yet.
}
/**
* Sets thie current layout
*/
private void setSavedLayout()
{
setSize(new Dimension(PrefUtils.getInt("frame_width_X", 800),
PrefUtils.getInt("frame_height_Y", 600)));
setLocation(new Point(PrefUtils.getInt("frame_position_X", 0),
PrefUtils.getInt("frame_position_Y", 0)));
}
/**
* Saves thie current layout.
*/
private void saveLayout()
{
PrefUtils.putInt("frame_position_X", this.getX());
PrefUtils.putInt("frame_position_Y", this.getY());
PrefUtils.putInt("frame_width_X", this.getWidth());
PrefUtils.putInt("frame_height_Y", this.getHeight());
}
}