/* (C) 2001-2002, DIUF, http://www.unifr.ch/diuf
*
* 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.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package iiuf.xmillum;
import iiuf.awt.BorderLayout;
import iiuf.swing.CheckBoxList;
import iiuf.swing.JWindowToolBarUI;
import iiuf.util.FilePreferences;
import iiuf.util.Preferences;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import javax.swing.JScrollPane;
import javax.swing.AbstractListModel;
import javax.swing.ListModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* XMIllumFrame
*
* JFrame implementation of XMIllum
*
* @author $Author: hassan $
* @version $Revision: 1.1 $
*/
public class XMIllumFrame {
/** Zoom preference */
static final String XMIFRAME_ZOOM = "xmillumframe.zoom";
/** Layers preference */
static final String XMIFRAME_LAYERS = "xmillumframe.layers";
/** Browser context */
BrowserContext context = new BrowserContext();
/** List of layers */
CheckBoxList layersList;
/** List of status messages */
MessageListModel statusList;
BrowserPanel mainPanel;
/**
* Creates a new XMIllumFrame.
*
* @param sourceDocumentBaseURL Source document base URL.
* @param stylesheetURL Stylesheet URL.
*/
public XMIllumFrame(final URL sourceDocumentBaseURL, URL stylesheetURL) throws IOException, SAXException, ParserConfigurationException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource isource = new InputSource(sourceDocumentBaseURL.openStream());
final Element sourceDocument = db.parse(isource).getDocumentElement();
context.addStatusListener(new StatusListener() {
public void setStatus(String message) {
if (statusList != null) {
statusList.addMessage(message);
}
}
});
context.addDocumentChangeListener(new DocumentChangeListener() {
public void documentChanged(DocumentChangeEvent e) {
switch (e.getType()) {
case DocumentChangeEvent.DOCUMENT_CHANGED:
String[] layers = context.getDocument().getLayerNames();
JCheckBox[] boxes = new JCheckBox[layers.length];
for (int i = 0; i < layers.length; i++) {
boxes[i] = new JCheckBox(layers[i]);
boxes[i].setSelected(true);
boxes[i].addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
JCheckBox cb = (JCheckBox) e.getSource();
context.toggleLayer(cb.getText(), cb.isSelected());
}
});
}
layersList.setListData(boxes);
break;
}
}
});
context.setWindowCreator(new WindowCreator() {
public Window createWindow(String title) {
return new IWindow(title);
}
});
layersList = new CheckBoxList();
layersList.setVisibleRowCount(3);
JScrollPane layersPane = new JScrollPane(layersList);
layersPane.setBorder(BorderFactory.createTitledBorder("Layers"));
statusList = new MessageListModel(20);
JFrame w = new JFrame("XMIllum");
w.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
context.finish();
context.clearLayer();
Preferences.store();
System.exit(0);
}
});
mainPanel = new BrowserPanel(context);
JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
split.setLeftComponent(mainPanel);
split.setRightComponent(new JScrollPane(new JList(statusList)));
JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
JComboBox zoom = new JComboBox(new ZoomEntry[] {
new ZoomEntry(BrowserPanel.SCALE_IMMEDIATE, 8.0d, "800%"),
new ZoomEntry(BrowserPanel.SCALE_IMMEDIATE, 4.0d, "400%"),
new ZoomEntry(BrowserPanel.SCALE_IMMEDIATE, 2.0d, "200%"),
new ZoomEntry(BrowserPanel.SCALE_IMMEDIATE, 1.5d, "150%"),
new ZoomEntry(BrowserPanel.SCALE_IMMEDIATE, 1.25d, "125%"),
new ZoomEntry(BrowserPanel.SCALE_IMMEDIATE, 1.0d, "100%"),
new ZoomEntry(BrowserPanel.SCALE_IMMEDIATE, 0.5d, "50%"),
new ZoomEntry(BrowserPanel.SCALE_IMMEDIATE, 0.25d, "25%"),
new ZoomEntry(BrowserPanel.SCALE_IMMEDIATE, 0.125d, "12.5%"),
new ZoomEntry(BrowserPanel.SCALE_SMART, BrowserPanel.SMARTSCALE_FIT_WIDTH, "Fit Width"),
new ZoomEntry(BrowserPanel.SCALE_SMART, BrowserPanel.SMARTSCALE_FIT_WINDOW, "Fit in Window")
});
zoom.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int zoom = ((JComboBox) e.getSource()).getSelectedIndex();
Preferences.set(XMIFRAME_ZOOM, new Integer(zoom));
ZoomEntry ze = (ZoomEntry) ((JComboBox) e.getSource()).getItemAt(zoom);
mainPanel.setScale(ze.getType(), ze.getFactor());
}
});
try {
zoom.setSelectedIndex(((Integer) Preferences.get(XMIFRAME_ZOOM, new Integer(5))).intValue());
} catch (IllegalArgumentException e) {
zoom.setSelectedIndex(5);
}
zoom.setBorder(BorderFactory.createTitledBorder("Zoom"));
// Required for Java 1.4.0 (?)
zoom.setMaximumSize(zoom.getMinimumSize());
leftPanel.add(zoom);
leftPanel.add(layersPane);
JSplitPane mainsplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
mainsplit.setOneTouchExpandable(true);
mainsplit.setLeftComponent(leftPanel);
mainsplit.setRightComponent(split);
w.getContentPane().setLayout(new BorderLayout());
w.getContentPane().add(mainsplit, BorderLayout.CENTER);
w.pack();
Preferences.watch(w);
w.setVisible(true);
context.setSource(new IllumSource() {
public Element getData() {
return sourceDocument;
}
public URL getBaseURL() {
return sourceDocumentBaseURL;
}
});
context.loadStylesheet(stylesheetURL);
}
/**
* ListModel for the status messages.
*/
class MessageListModel extends AbstractListModel {
/** List containing the messages */
ArrayList l = new ArrayList();
int bufferSize;
/**
* Creates a new message list.
*
* @param max Max. number of messages.
*/
public MessageListModel(int max) {
bufferSize = max;
}
/**
* Adds a message to the list.
*
* @param message Message to be added to the list.
*/
public void addMessage(String message) {
l.add(message);
if (l.size() > bufferSize) {
l.remove(0);
}
fireContentsChanged(this, 0, l.size()-1);
}
/**
* Returns the message at the given position.
*
* @param i Position
* @return Message
*/
public Object getElementAt(int i) {
return l.get(l.size()-1-i);
}
/**
* Returns the total number of messages.
*
* @return Number of messages
*/
public int getSize() {
return l.size();
}
}
class ZoomEntry {
String message;
int type;
double factor;
public ZoomEntry(int t, double f, String m) {
type = t;
factor = f;
message = m;
}
public int getType() {
return type;
}
public double getFactor() {
return factor;
}
public String toString() {
return message;
}
}
/** Windows generated by the the WindowCreator */
class IWindow extends JFrame implements Window {
/**
* Creates an IWindow
*
* @param title Window title.
*/
public IWindow(String title) {
super(title);
setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
setState(java.awt.Frame.ICONIFIED);
}
});
}
/**
* Sets a menu bar in the window.
*
* @param menubar The menubar to set.
*/
public void setMenu(JMenuBar menubar) {
setJMenuBar(menubar);
}
/**
* Opens the window.
*/
public void open() {
pack();
Preferences.watch(this);
setState(java.awt.Frame.NORMAL);
show();
}
/**
* Closes the window.
*/
public void close() {
hide();
dispose();
}
/**
* Gets the content pane.
*
* @return Content pane for adding objects.
*/
public Container getContentPane() {
return super.getContentPane();
}
}
/**
* Main entry point.
*
* @param arg Command line arguments.
*/
public static void main(String arg[]) throws IOException, SAXException, MalformedURLException, ParserConfigurationException {
if (arg.length != 2) {
System.err.println("Usage: java iiuf.xmillum.XMIllumFrame <xml-file> <xsl-file>");
System.exit(1);
}
Preferences.addStore(new FilePreferences("xmillumframe"));
URL baseURL = (new File(arg[0])).toURL();
URL stylesheetURL = (new File(arg[1])).toURL();
new XMIllumFrame(baseURL, stylesheetURL);
}
}