// Help.java
package net.sf.gogui.gui;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import static net.sf.gogui.gui.I18n.i18n;
import net.sf.gogui.util.Platform;
/** Window for displaying help in HTML format.
The window is a JFrame on all platforms but the Mac, where it is a
parent-less JDialog (to avoid the brushed-metal look, which shouldn't be
used for the help window) */
public class Help
implements ActionListener, HyperlinkListener
{
public Help(URL contents, MessageDialogs messageDialogs,
String title)
{
m_messageDialogs = messageDialogs;
m_contents = contents;
Container contentPane;
if (Platform.isMac())
{
JDialog dialog = new JDialog((Frame)null, title);
contentPane = dialog.getContentPane();
m_window = dialog;
}
else
{
JFrame frame = new JFrame(title);
GuiUtil.setGoIcon(frame);
contentPane = frame.getContentPane();
m_window = frame;
}
JPanel panel = new JPanel(new BorderLayout());
contentPane.add(panel);
panel.add(createButtons(), BorderLayout.NORTH);
m_editorPane = new JEditorPane();
m_editorPane.setEditable(false);
m_editorPane.addHyperlinkListener(this);
int width = GuiUtil.getDefaultMonoFontSize() * 50;
int height = GuiUtil.getDefaultMonoFontSize() * 60;
JScrollPane scrollPane =
new JScrollPane(m_editorPane,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
if (Platform.isMac())
// Default Apple L&F uses no border, but Quaqua 3.7.4 does
scrollPane.setBorder(null);
scrollPane.setPreferredSize(new Dimension(width, height));
panel.add(scrollPane, BorderLayout.CENTER);
m_window.pack();
loadURL(m_contents);
appendHistory(m_contents);
}
public void actionPerformed(ActionEvent event)
{
String command = event.getActionCommand();
if (command.equals("back"))
back();
else if (command.equals("close"))
m_window.setVisible(false);
else if (command.equals("contents"))
{
loadURL(m_contents);
appendHistory(m_contents);
}
else if (command.equals("forward"))
forward();
}
public Window getWindow()
{
return m_window;
}
public void hyperlinkUpdate(HyperlinkEvent e)
{
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
{
URL url = e.getURL();
String protocol = url.getProtocol();
if (protocol.equals("jar") || protocol.equals("file"))
{
loadURL(url);
appendHistory(url);
}
else
openExternal(url);
}
}
private int m_historyIndex = -1;
private JButton m_buttonBack;
private JButton m_buttonForward;
private final JEditorPane m_editorPane;
private java.util.List<URL> m_history = new ArrayList<URL>();
private final URL m_contents;
private final MessageDialogs m_messageDialogs;
private final Window m_window;
private void appendHistory(URL url)
{
if (m_historyIndex >= 0 && historyEquals(m_historyIndex, url))
return;
if (m_historyIndex + 1 < m_history.size())
{
if (! historyEquals(m_historyIndex + 1, url))
{
m_history = m_history.subList(0, m_historyIndex + 1);
m_history.add(url);
}
}
else
m_history.add(url);
++m_historyIndex;
historyChanged();
}
private void back()
{
assert m_historyIndex > 0;
assert m_historyIndex < m_history.size();
--m_historyIndex;
loadURL(getHistory(m_historyIndex));
historyChanged();
}
private JComponent createButtons()
{
JToolBar toolBar = new JToolBar();
toolBar.add(createToolBarButton("go-home", "contents", "TT_HELP_TOC"));
m_buttonBack = createToolBarButton("go-previous", "back",
"TT_HELP_BACK");
toolBar.add(m_buttonBack);
m_buttonForward = createToolBarButton("go-next", "forward",
"TT_HELP_FORWARD");
toolBar.add(m_buttonForward);
if (! Platform.isMac())
toolBar.setRollover(true);
toolBar.setFloatable(false);
return toolBar;
}
private JButton createToolBarButton(String icon, String command,
String toolTip)
{
JButton button = new JButton();
button.setActionCommand(command);
button.setToolTipText(i18n(toolTip));
button.addActionListener(this);
button.setIcon(GuiUtil.getIcon(icon, command));
button.setFocusable(false);
return button;
}
private void forward()
{
assert m_historyIndex + 1 < m_history.size();
++m_historyIndex;
loadURL(getHistory(m_historyIndex));
historyChanged();
}
private URL getHistory(int index)
{
return m_history.get(index);
}
private void historyChanged()
{
boolean backPossible = (m_historyIndex > 0);
boolean forwardPossible = (m_historyIndex < m_history.size() - 1);
m_buttonBack.setEnabled(backPossible);
m_buttonForward.setEnabled(forwardPossible);
}
private boolean historyEquals(int index, URL url)
{
// Compare as strings to avoid Findbugs warning about potentially
// blocking URL.equals()
return getHistory(index).toString().equals(url.toString());
}
private void loadURL(URL url)
{
try
{
m_editorPane.setPage(url);
}
catch (IOException e)
{
String mainMessage =
MessageFormat.format("MSG_HELP_LOAD_FAILURE", url.toString());
m_messageDialogs.showError(m_window, mainMessage, e.getMessage(),
false);
}
}
/** Open URL in external browser if possible.
If it doesn't work, the URL is opened inside this dialog. */
private void openExternal(URL url)
{
if (! Platform.openInExternalBrowser(url))
loadURL(url);
appendHistory(url);
}
}