001    /* JAPI - (Yet anothr (hopefully) useful) Java API
002     *
003     * Copyright (C) 2004-2006 Christian Hujer
004     *
005     * This program is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU General Public License as
007     * published by the Free Software Foundation; either version 2 of the
008     * License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful, but
011     * WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013     * General Public License for more details.
014     *
015     * You should have received a copy of the GNU General Public License
016     * along with this program; if not, write to the Free Software
017     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018     * 02111-1307, USA.
019     */
020    
021    package net.sf.japi.swing;
022    
023    import java.awt.Component;
024    import javax.swing.JButton;
025    import javax.swing.JDialog;
026    import javax.swing.JOptionPane;
027    import javax.swing.JScrollPane;
028    import javax.swing.JTextArea;
029    import org.xml.sax.ErrorHandler;
030    import org.xml.sax.SAXException;
031    import org.xml.sax.SAXParseException;
032    
033    /** Implementation of {@link ErrorHandler} for displaying XML parser errors on the screen.
034     * @author <a href="mailto:Christian.Hujer@itcqis.com">Christian Hujer</a>
035     */
036    public final class JSAXErrorHandler extends JOptionPane implements ErrorHandler {
037    
038        /** Action Factory. */
039        private static final ActionFactory actionFactory = ActionFactory.getFactory("net.sf.japi.swing");
040    
041        /** The JTextArea which displays the errors.
042         * @serial include
043         */
044        private JTextArea errorPane = new JTextArea();
045    
046        /** The Dialog.
047         * @serial include
048         */
049        private JDialog dialog;
050    
051        /** Parent component.
052         * @serial include
053         */
054        private final Component parent;
055    
056        /** Button for closing.
057         * @serial include
058         */
059        private JButton closeButton;
060    
061        /** Create a JSAXErrorHandler.
062         * @param parent
063         */
064        public JSAXErrorHandler(final Component parent) {
065            errorPane.setEditable(false);
066            setMessage(new JScrollPane(errorPane));
067            final JButton clearButton = new JButton(actionFactory.createAction(false, "saxErrorClear", this));
068            closeButton = new JButton(actionFactory.createAction(false, "saxErrorClose", this));
069            this.parent = parent;
070            setOptions(new Object[] { closeButton, clearButton });
071        }
072    
073        /** {@inheritDoc} */
074        public void warning(final SAXParseException exception) throws SAXException {
075            add("warning", exception);
076        }
077    
078        /** {@inheritDoc} */
079        public void error(final SAXParseException exception) throws SAXException {
080            add("error", exception);
081        }
082    
083        /** {@inheritDoc} */
084        public void fatalError(final SAXParseException exception) throws SAXException {
085            add("fatal", exception);
086        }
087    
088        /** Add an exception.
089         * @param level Error level
090         * @param exception Exception
091         */
092        private void add(final String level, final SAXParseException exception) {
093            final StringBuilder errorMsg = new StringBuilder();
094            final int lineNumber   = exception.getLineNumber();
095            final int columnNumber = exception.getColumnNumber();
096            errorMsg.append(exception.getSystemId());
097            errorMsg.append(':');
098            if (lineNumber != 0) {
099                errorMsg.append(lineNumber);
100                errorMsg.append(':');
101                if (columnNumber != 0) {
102                    errorMsg.append(columnNumber);
103                    errorMsg.append(':');
104                }
105            }
106            errorMsg.append(' ');
107            errorMsg.append(level);
108            errorMsg.append(": ");
109            errorMsg.append(exception.getMessage());
110            if (exception.getException() != null) {
111                errorMsg.append(" (Cause: ");
112                errorMsg.append(exception.getException().toString());
113                errorMsg.append(')');
114            }
115            errorMsg.append('\n');
116            errorPane.append(errorMsg.toString());
117            showDialog();
118        }
119    
120        /** Show the dialog. */
121        private void showDialog() {
122            if (dialog == null) {
123                dialog = createDialog(parent, actionFactory.getString("saxError_title"));
124                closeButton.requestFocusInWindow();
125                dialog.getRootPane().setDefaultButton(closeButton);
126                dialog.setModal(false);
127                dialog.setResizable(true);
128                dialog.setVisible(true);
129            }
130        }
131    
132        /** Action method for clearing. */
133        public void saxErrorClear() {
134            errorPane.setText("");
135        }
136    
137        /** Action method for closing. */
138        public void saxErrorClose() {
139            setValue(closeButton);
140            dialog.setVisible(false);
141            dialog.dispose();
142            dialog = null;
143        }
144    
145    } // class JSAXErrorHandler