001    /* JAPI - (Yet another (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     * @warning DO NOT RELY ON THE INHERITANCE!
035     * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a>
036     */
037    public final class JSAXErrorHandler extends JOptionPane implements ErrorHandler {
038    
039        /** Action Factory. */
040        private static final ActionFactory actionFactory = ActionFactory.getFactory("net.sf.japi.swing");
041    
042        /** The JTextArea which displays the errors.
043         * @serial include
044         */
045        private JTextArea errorPane = new JTextArea();
046    
047        /** The Dialog.
048         * @serial include
049         */
050        private JDialog dialog;
051    
052        /** Parent component.
053         * @serial include
054         */
055        private final Component parent;
056    
057        /** Button for closing.
058         * @serial include
059         */
060        private JButton closeButton;
061    
062        /** Create a JSAXErrorHandler.
063         * @param parent
064         */
065        public JSAXErrorHandler(final Component parent) {
066            errorPane.setEditable(false);
067            setMessage(new JScrollPane(errorPane));
068            final JButton clearButton = new JButton(actionFactory.createAction(false, "saxErrorClear", this));
069            closeButton = new JButton(actionFactory.createAction(false, "saxErrorClose", this));
070            this.parent = parent;
071            setOptions(new Object[] { closeButton, clearButton });
072        }
073    
074        /** {@inheritDoc} */
075        public void warning(final SAXParseException exception) throws SAXException {
076            add("warning", exception);
077        }
078    
079        /** {@inheritDoc} */
080        public void error(final SAXParseException exception) throws SAXException {
081            add("error", exception);
082        }
083    
084        /** {@inheritDoc} */
085        public void fatalError(final SAXParseException exception) throws SAXException {
086            add("fatal", exception);
087        }
088    
089        /** Add an exception.
090         * @param level Error level
091         * @param exception Exception
092         */
093        private void add(final String level, final SAXParseException exception) {
094            final StringBuilder errorMsg = new StringBuilder();
095            final int lineNumber   = exception.getLineNumber();
096            final int columnNumber = exception.getColumnNumber();
097            errorMsg.append(exception.getSystemId());
098            errorMsg.append(':');
099            if (lineNumber != 0) {
100                errorMsg.append(lineNumber);
101                errorMsg.append(':');
102                if (columnNumber != 0) {
103                    errorMsg.append(columnNumber);
104                    errorMsg.append(':');
105                }
106            }
107            errorMsg.append(' ');
108            errorMsg.append(level);
109            errorMsg.append(": ");
110            errorMsg.append(exception.getMessage());
111            if (exception.getException() != null) {
112                errorMsg.append(" (Cause: ");
113                errorMsg.append(exception.getException().toString());
114                errorMsg.append(')');
115            }
116            errorMsg.append('\n');
117            errorPane.append(errorMsg.toString());
118            showDialog();
119        }
120    
121        /** Show the dialog. */
122        private void showDialog() {
123            if (dialog == null) {
124                dialog = createDialog(parent, actionFactory.getString("saxError_title"));
125                closeButton.requestFocusInWindow();
126                dialog.getRootPane().setDefaultButton(closeButton);
127                dialog.setModal(false);
128                dialog.setResizable(true);
129                dialog.setVisible(true);
130            }
131        }
132    
133        /** Action method for clearing. */
134        public void saxErrorClear() {
135            errorPane.setText("");
136        }
137    
138        /** Action method for closing. */
139        public void saxErrorClose() {
140            setValue(closeButton);
141            dialog.setVisible(false);
142            dialog.dispose();
143            dialog = null;
144        }
145    
146    } // class JSAXErrorHandler