ro.nextreports.designer.querybuilder.SQLViewPanel.java Source code

Java tutorial

Introduction

Here is the source code for ro.nextreports.designer.querybuilder.SQLViewPanel.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ro.nextreports.designer.querybuilder;

import info.clearthought.layout.TableLayout;
import info.clearthought.layout.TableLayoutConstants;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.sql.Connection;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.JCheckBox;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.HighlightPredicate;
import org.jdesktop.swingx.decorator.Highlighter;
import org.jdesktop.swingx.decorator.HighlighterFactory;

import ro.nextreports.designer.Globals;
import ro.nextreports.designer.datasource.DataSource;
import ro.nextreports.designer.datasource.DefaultDataSourceManager;
import ro.nextreports.designer.ui.IntegerTextField;
import ro.nextreports.designer.ui.JLine;
import ro.nextreports.designer.ui.TextHighlighter;
import ro.nextreports.designer.ui.sqleditor.BaseEditorKit;
import ro.nextreports.designer.ui.sqleditor.Editor;
import ro.nextreports.designer.ui.table.TableRowHeader;
import ro.nextreports.designer.util.ColorUtil;
import ro.nextreports.designer.util.CopyTableMouseAdapter;
import ro.nextreports.designer.util.I18NSupport;
import ro.nextreports.designer.util.ImageUtil;
import ro.nextreports.designer.util.MessageUtil;
import ro.nextreports.designer.util.NextReportsUtil;
import ro.nextreports.designer.util.ShortcutsUtil;
import ro.nextreports.designer.util.Show;
import ro.nextreports.designer.util.SwingUtil;
import ro.nextreports.designer.util.TableUtil;
import ro.nextreports.designer.util.UIActivator;

import ro.nextreports.engine.EngineProperties;
import ro.nextreports.engine.Report;
import ro.nextreports.engine.exporter.util.ParametersBean;
import ro.nextreports.engine.querybuilder.sql.Column;
import ro.nextreports.engine.querybuilder.sql.dialect.CSVDialect;
import ro.nextreports.engine.queryexec.QueryExecutor;
import ro.nextreports.engine.queryexec.QueryResult;
import ro.nextreports.engine.util.DialectUtil;
import ro.nextreports.engine.util.ParameterNotFoundException;
import ro.nextreports.engine.util.QueryUtil;
import com.jgoodies.looks.HeaderStyle;
import com.jgoodies.looks.Options;

/**
 * @author Decebal Suiu
 */
public class SQLViewPanel extends JPanel {

    // default query retrieves all data from authors table
    public static final String DEFAULT_QUERY = "<<SELECT>>";

    private static final Log LOG = LogFactory.getLog(SQLViewPanel.class);

    private JXTable resultTable;
    private ResultSetTableModel tableModel;
    private JTextComponent queryArea;
    private JCheckBox maxRowsCheckBox;
    private SQLStatusPanel statusPanel;
    private Thread executorThread;
    private Editor sqlEditor;
    private javax.swing.text.Highlighter.HighlightPainter errorPainter;
    private Object errorTag = null;

    private Action runAction;

    private static String sql;
    private boolean stop = false;

    public SQLViewPanel() {
        super();
        initUI();
    }

    private void initUI() {
        sqlEditor = new Editor() {
            public void afterCaretMove() {
                removeHighlightErrorLine();
            }
        };
        this.queryArea = sqlEditor.getEditorPanel().getEditorPane();
        queryArea.setText(DEFAULT_QUERY);

        errorPainter = new javax.swing.text.Highlighter.HighlightPainter() {
            @Override
            public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) {
                try {
                    Rectangle r = c.modelToView(c.getCaretPosition());
                    g.setColor(Color.RED.brighter().brighter());
                    g.fillRect(0, r.y, c.getWidth(), r.height);
                } catch (BadLocationException e) {
                    // ignore
                }
            }
        };

        ActionMap actionMap = sqlEditor.getEditorPanel().getEditorPane().getActionMap();

        // create the toolbar
        JToolBar toolBar = new JToolBar();
        toolBar.putClientProperty("JToolBar.isRollover", Boolean.TRUE); // hide buttons borders
        toolBar.putClientProperty(Options.HEADER_STYLE_KEY, HeaderStyle.BOTH);
        toolBar.setBorderPainted(false);

        // add cut action
        Action cutAction = actionMap.get(BaseEditorKit.cutAction);
        cutAction.putValue(Action.SMALL_ICON, ImageUtil.getImageIcon("cut"));
        cutAction.putValue(Action.SHORT_DESCRIPTION, I18NSupport.getString("sqlviewpanel.cut"));
        toolBar.add(cutAction);

        // add copy action
        Action copyAction = actionMap.get(BaseEditorKit.copyAction);
        copyAction.putValue(Action.SMALL_ICON, ImageUtil.getImageIcon("copy"));
        copyAction.putValue(Action.SHORT_DESCRIPTION, I18NSupport.getString("sqlviewpanel.copy"));
        toolBar.add(copyAction);

        // add paste action
        Action pasteAction = actionMap.get(BaseEditorKit.pasteAction);
        pasteAction.putValue(Action.SMALL_ICON, ImageUtil.getImageIcon("paste"));
        pasteAction.putValue(Action.SHORT_DESCRIPTION, I18NSupport.getString("sqlviewpanel.paste"));
        toolBar.add(pasteAction);

        // add separator
        SwingUtil.addCustomSeparator(toolBar);

        // add undo action
        Action undoAction = actionMap.get(BaseEditorKit.undoAction);
        undoAction.putValue(Action.SMALL_ICON, ImageUtil.getImageIcon("undo"));
        undoAction.putValue(Action.SHORT_DESCRIPTION, I18NSupport.getString("undo"));
        toolBar.add(undoAction);

        // add redo action
        Action redoAction = actionMap.get(BaseEditorKit.redoAction);
        redoAction.putValue(Action.SMALL_ICON, ImageUtil.getImageIcon("redo"));
        redoAction.putValue(Action.SHORT_DESCRIPTION, I18NSupport.getString("redo"));
        toolBar.add(redoAction);

        // add separator
        SwingUtil.addCustomSeparator(toolBar);

        // add find action
        Action findReplaceAction = actionMap.get(BaseEditorKit.findReplaceAction);
        findReplaceAction.putValue(Action.SMALL_ICON, ImageUtil.getImageIcon("find"));
        findReplaceAction.putValue(Action.SHORT_DESCRIPTION,
                I18NSupport.getString("sqleditor.findReplaceActionName"));
        toolBar.add(findReplaceAction);

        // add separator
        SwingUtil.addCustomSeparator(toolBar);

        // add run action
        runAction = new SQLRunAction();
        runAction.putValue(Action.SMALL_ICON, ImageUtil.getImageIcon("run"));
        runAction.putValue(Action.ACCELERATOR_KEY,
                KeyStroke.getKeyStroke(ShortcutsUtil.getShortcut("query.run.accelerator", "control 4")));
        runAction.putValue(Action.SHORT_DESCRIPTION, I18NSupport.getString("run.query") + " ("
                + ShortcutsUtil.getShortcut("query.run.accelerator.display", "Ctrl 4") + ")");
        // runAction is globally registered in QueryBuilderPanel !
        toolBar.add(runAction);

        //        ro.nextreports.designer.util.SwingUtil.registerButtonsForFocus(buttonsPanel);

        // create the table
        resultTable = new JXTable();
        resultTable.setDefaultRenderer(Integer.class, new ToStringRenderer()); // to remove thousand separators
        resultTable.setDefaultRenderer(Long.class, new ToStringRenderer());
        resultTable.setDefaultRenderer(Date.class, new DateRenderer());
        resultTable.setDefaultRenderer(Double.class, new DoubleRenderer());
        resultTable.addMouseListener(new CopyTableMouseAdapter(resultTable));
        TableUtil.setRowHeader(resultTable);
        resultTable.setColumnControlVisible(true);
        //        resultTable.getTableHeader().setReorderingAllowed(false);
        resultTable.setHorizontalScrollEnabled(true);

        // highlight table
        Highlighter alternateHighlighter = HighlighterFactory.createAlternateStriping(Color.WHITE,
                ColorUtil.PANEL_BACKROUND_COLOR);
        Highlighter nullHighlighter = new TextHighlighter(ResultSetTableModel.NULL_VALUE, Color.YELLOW.brighter());
        Highlighter blobHighlighter = new TextHighlighter(ResultSetTableModel.BLOB_VALUE, Color.GRAY.brighter());
        Highlighter clobHighlighter = new TextHighlighter(ResultSetTableModel.CLOB_VALUE, Color.GRAY.brighter());
        resultTable.setHighlighters(alternateHighlighter, nullHighlighter, blobHighlighter, clobHighlighter);
        resultTable.setBackground(ColorUtil.PANEL_BACKROUND_COLOR);
        resultTable.setGridColor(Color.LIGHT_GRAY);

        resultTable.setRolloverEnabled(true);
        resultTable.addHighlighter(new ColorHighlighter(HighlightPredicate.ROLLOVER_ROW, null, Color.RED));

        JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        split.setResizeWeight(0.66);
        split.setOneTouchExpandable(true);

        JPanel topPanel = new JPanel();
        topPanel.setLayout(new GridBagLayout());
        topPanel.add(toolBar, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
                GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
        topPanel.add(sqlEditor, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.WEST,
                GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));

        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new GridBagLayout());
        JScrollPane scrPanel = new JScrollPane(resultTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        statusPanel = new SQLStatusPanel();
        bottomPanel.add(scrPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.WEST,
                GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
        bottomPanel.add(statusPanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
                GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0));

        split.setTopComponent(topPanel);
        split.setBottomComponent(bottomPanel);
        split.setDividerLocation(400);

        setLayout(new BorderLayout());
        this.add(split, BorderLayout.CENTER);
    }

    public void setQueryString(String sqlString) {
        sql = sqlString;
        queryArea.setText(sqlString);
    }

    public String getQueryString() {
        String s = queryArea.getText();
        if ("".equals(s)) {
            if (sql == null) {
                return "";
            } else {
                return sql;
            }
        } else {
            return s;
        }
    }

    public boolean emptyQueryString() {
        String s = getQueryString();
        return ("".equals(s) || DEFAULT_QUERY.equals(s));
    }

    public void clear() {
        try {
            sql = "";
            queryArea.setText("");
            //         tableModel = new ScrollingResultSetTableModel(null);
            tableModel = new CachingResultSetTableModel(null);
            resultTable.setModel(tableModel);
            statusPanel.clear();
        } catch (Exception e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(Globals.getMainFrame(), e, I18NSupport.getString("error"),
                    JOptionPane.ERROR_MESSAGE);
        }
    }

    protected String getSql(Report report) {
        String sql;
        if (report == null) {
            sql = queryArea.getText();
        } else {
            if (report.getSql() != null) {
                sql = report.getSql();
            } else {
                try {
                    for (Column col : report.getQuery().getColumns()) {
                        col.getTable().setDialect(DialectUtil.getDialect(Globals.getConnection()));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    LOG.error(e.getMessage(), e);
                }
                sql = report.getQuery().toString();
            }
        }
        if (sql.equals("") || sql.equals(DEFAULT_QUERY)) {
            return null;
        }
        return sql;
    }

    protected ParametersBean selectParameters(Report report) {
        return selectParameters(report, null);
    }

    protected ParametersBean selectParameters(Report report, DataSource runDS) {
        String sql = getSql(report);
        return NextReportsUtil.selectParameters(sql, runDS);
    }

    protected QueryResult runQuery(ParametersBean pBean, boolean useMaxRows) throws Exception {
        return runQuery(Globals.getConnection(), pBean, useMaxRows);
    }

    protected QueryResult runQuery(Connection con, ParametersBean pBean, boolean useMaxRows) throws Exception {
        DataSource runDS = DefaultDataSourceManager.getInstance().getConnectedDataSource();
        boolean isCsv = runDS.getDriver().equals(CSVDialect.DRIVER_CLASS);
        QueryExecutor executor = new QueryExecutor(pBean.getQuery(), pBean.getParams(), pBean.getParamValues(), con,
                true, true, isCsv);
        executor.setTimeout(Globals.getQueryTimeout());
        if (useMaxRows) {
            executor.setMaxRows(maxRowsCheckBox.isSelected() ? statusPanel.getMaxRows() : 0);
        } else {
            executor.setMaxRows(Globals.getReportLayoutPanel().getRecords());
        }
        return executor.execute();
    }

    class SQLRunAction extends AbstractAction {

        public void actionPerformed(ActionEvent ev) {
            executorThread = new Thread(new Runnable() {

                public void run() {

                    removeHighlightErrorLine();

                    if (MessageUtil.showReconnect()) {
                        return;
                    }

                    final UIActivator activator = new UIActivator(Globals.getMainFrame(),
                            I18NSupport.getString("running.query"));
                    try {
                        runAction.setEnabled(false);

                        if (queryArea.getText().equals("")) {
                            return;
                        }

                        String sql = getSql(null);
                        try {
                            ParameterManager.getInstance().parametersAreDefined(sql);
                        } catch (ParameterNotFoundException ex) {
                            Show.error(I18NSupport.getString("parameter.undefined", ex.getParamName()));
                            return;
                        }

                        if (QueryUtil.restrictQueryExecution(sql)) {
                            Show.error(I18NSupport.getString("export.action.execute"));
                            return;
                        }

                        if (QueryUtil.isProcedureCall(sql)) {
                            if (!QueryUtil.isValidProcedureCall(sql,
                                    DialectUtil.getDialect(Globals.getConnection()))) {
                                Show.error(I18NSupport.getString("export.action.execute.procedure"));
                                return;
                            }
                            //                            String param = ParameterManager.getInstance().parametersAreForStoredProcedure();
                            //                            if (param != null) {
                            //                                Show.error(I18NSupport.getString("parameter.procedure.undefined", param));
                            //                                return;
                            //                            }
                        }

                        ParametersBean pBean = selectParameters(null);
                        if (pBean == null) {
                            return;
                        }

                        activator.start(new SQLStopAction());

                        final QueryResult result = runQuery(pBean, true);
                        if (result == null) {
                            if (activator != null) {
                                SwingUtilities.invokeLater(new Runnable() {
                                    public void run() {
                                        activator.stop();
                                    }
                                });
                            }
                            return;
                        }

                        // TODO ??
                        // first reset model
                        // tableModel = new ScrollingResultSetTableModel(null);
                        tableModel = new CachingResultSetTableModel(null, executorThread.isInterrupted());
                        resultTable.setModel(tableModel);

                        //tableModel = new ScrollingResultSetTableModel(result);
                        tableModel = new CachingResultSetTableModel(result, executorThread.isInterrupted());
                        ((CachingResultSetTableModel) tableModel).init();
                        resultTable.setModel(tableModel);
                        //resultTable.packAll();
                        statusPanel.setExecuteTime(result.getExecuteTime());
                        statusPanel.setRows(result.getRowCount());
                        TableRowHeader trh = TableUtil.setRowHeader(resultTable);
                        trh.setBackground(ColorUtil.PANEL_BACKROUND_COLOR);

                        if (result.getRowCount() == 0) {
                            Show.info(I18NSupport.getString("run.query.nodata"));
                        }

                    } catch (InterruptedException e) {
                        Show.dispose(); // close a possible previous dialog message
                        Show.info(Globals.getMainFrame(), I18NSupport.getString("query.cancelled"));
                    } catch (Exception e) {
                        highlightErrorLine(e);
                        e.printStackTrace();
                        Show.error(Globals.getMainFrame(), I18NSupport.getString("error"), e);
                    } catch (Throwable t) {
                        t.printStackTrace();
                        LOG.error(t.getMessage(), t);
                    } finally {
                        stop = false;
                        runAction.setEnabled(true);
                        if (activator != null) {
                            SwingUtilities.invokeLater(new Runnable() {
                                public void run() {
                                    activator.stop();
                                }
                            });
                        }
                    }
                }

            }, "NEXT : " + getClass().getSimpleName());
            executorThread.setPriority(EngineProperties.getRunPriority());
            executorThread.start();
        }
    }

    private void highlightErrorLine(Exception e) {
        removeHighlightErrorLine();
        // determine error line number, if any
        String er = e.getMessage();
        // error may contain line number info like " line 12" or " line 12, column 3 " ...
        String regex = ".*\\sline\\s(\\d+)([^\\d].*)*";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(er);
        // first found is line number
        if (m.find()) {
            String lineNo = m.group(1);
            LOG.info("Error on line number : " + lineNo);
            Document ed = sqlEditor.getEditorPanel().getEditorPane().getDocument();
            Element elem = ed.getDefaultRootElement().getElement(Integer.parseInt(lineNo) - 1);
            sqlEditor.getEditorPanel().getEditorPane().setCaretPosition(elem.getStartOffset());
            try {
                errorTag = sqlEditor.getEditorPanel().getEditorPane().getHighlighter()
                        .addHighlight(elem.getStartOffset(), elem.getEndOffset(), errorPainter);
            } catch (BadLocationException e1) {
                LOG.error("Could not highlight sql error line number", e1);
            }
        }
    }

    private void removeHighlightErrorLine() {
        if (errorTag != null) {
            sqlEditor.getEditorPanel().getEditorPane().getHighlighter().removeHighlight(errorTag);
        }
    }

    class SQLStopAction extends AbstractAction {

        public SQLStopAction() {
            super();
            putValue(Action.NAME, I18NSupport.getString("stop.query.execution"));
            putValue(Action.SMALL_ICON, ImageUtil.getImageIcon("stop_execution"));
            putValue(Action.SHORT_DESCRIPTION, I18NSupport.getString("stop.query.execution"));
            putValue(Action.LONG_DESCRIPTION, I18NSupport.getString("stop.query.execution"));
            putValue(Action.MNEMONIC_KEY, new Integer('S'));
            putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK));
        }

        public void actionPerformed(ActionEvent e) {
            if (stop) {
                Show.disposableInfo(I18NSupport.getString("stop.wait.second"));
                return;
            } else {
                Show.disposableInfo(I18NSupport.getString("stop.wait"));
            }
            if (executorThread != null) {
                stop = true;
                executorThread.interrupt();
                ((CachingResultSetTableModel) tableModel).setStop(true);
            }
        }

    }

    class SQLStatusPanel extends JPanel {

        private final DecimalFormat timeFormat = new DecimalFormat("####.### sec");
        private JTextField maxRowsTextField;
        private JLabel timeLabel;
        private JLabel rowsLabel;

        public SQLStatusPanel() {
            super();
            initUI();
        }

        public void setExecuteTime(long time) {
            timeLabel.setText(timeFormat.format((double) time / 1000));
        }

        public void setRows(long rows) {
            rowsLabel.setText(rows + " " + I18NSupport.getString("rows"));
        }

        public int getMaxRows() {
            int rows;
            try {
                rows = Integer.parseInt(maxRowsTextField.getText());
            } catch (NumberFormatException nfe) {
                //all rows
                rows = 0;
            }
            return rows;
        }

        private void initUI() {
            double[] columns = { TableLayoutConstants.FILL, TableLayoutConstants.PREFERRED,
                    TableLayoutConstants.PREFERRED, TableLayoutConstants.PREFERRED };

            double[] rows = { TableLayoutConstants.PREFERRED, };

            TableLayout layout = new TableLayout(columns, rows);
            layout.setHGap(6);
            this.setLayout(layout);
            createMaxRowsPanel();

            add(createMaxRowsPanel(), "0, 0");
            add(timeLabel = new JLabel("0 " + I18NSupport.getString("seconds")), "1, 0");
            add(new JLine(), "2, 0");
            add(rowsLabel = new JLabel("0 " + I18NSupport.getString("rows")), "3, 0");
        }

        private JPanel createMaxRowsPanel() {

            JPanel maxRowsPanel = new JPanel();
            double[] columns = { TableLayoutConstants.PREFERRED, 3, TableLayoutConstants.PREFERRED };

            double[] rows = { TableLayoutConstants.PREFERRED, };

            TableLayout layout = new TableLayout(columns, rows);
            maxRowsPanel.setLayout(layout);

            maxRowsCheckBox = new JCheckBox(I18NSupport.getString("max.rows"));
            maxRowsCheckBox.addItemListener(new ItemListener() {

                public void itemStateChanged(ItemEvent e) {
                    if (e.getStateChange() == ItemEvent.SELECTED) {
                        maxRowsTextField.setEditable(true);
                    } else {
                        maxRowsTextField.setEditable(false);
                    }
                }

            });
            maxRowsPanel.add(maxRowsCheckBox, "0, 0");

            maxRowsTextField = new IntegerTextField();
            maxRowsTextField.setText("500");
            maxRowsTextField.setColumns(7);
            maxRowsPanel.add(maxRowsTextField, "2, 0");

            // enable max rows feature
            enableMaxCheck();
            return maxRowsPanel;
        }

        public void clear() {
            timeLabel.setText("0 " + I18NSupport.getString("seconds"));
            rowsLabel.setText("0 " + I18NSupport.getString("rows"));
        }

        public void enableMaxCheck() {
            boolean checked = Globals.isMaxChecked();
            maxRowsCheckBox.setSelected(checked);
            if (checked) {
                maxRowsTextField.setEditable(true);
            } else {
                maxRowsTextField.setEditable(false);
            }
        }

    }

    public void enableMaxCheck() {
        statusPanel.enableMaxCheck();
    }

    /**
     * Overwrite some renderers in JXTable because we need
     * to take care about ResultSetTableModel.NULL_VALUE value
     * (which is a String)!
     */
    private class DateRenderer extends DefaultTableCellRenderer {
        DateFormat formatter;

        public DateRenderer() {
            super();
        }

        public void setValue(Object value) {
            // Timestamp is also a Date, but we want to show also the time for it
            if (value instanceof Timestamp) {
                setText((value == null) ? ""
                        : value.equals(ResultSetTableModel.NULL_VALUE) ? ResultSetTableModel.NULL_VALUE
                                : value.toString());
            } else {
                if (formatter == null) {
                    formatter = DateFormat.getDateInstance();
                }
                setText((value == null) ? ""
                        : value.equals(ResultSetTableModel.NULL_VALUE) ? ResultSetTableModel.NULL_VALUE
                                : formatter.format(value));
            }
        }
    }

    private class DoubleRenderer extends DefaultTableCellRenderer {
        NumberFormat formatter;

        public DoubleRenderer() {
            super();
        }

        public void setValue(Object value) {
            if (formatter == null) {
                formatter = NumberFormat.getInstance();
            }
            setText((value == null) ? ""
                    : value.equals(ResultSetTableModel.NULL_VALUE) ? ResultSetTableModel.NULL_VALUE
                            : formatter.format(value));
        }
    }

    private class ToStringRenderer extends DefaultTableCellRenderer {

        public ToStringRenderer() {
            super();
        }

        public void setValue(Object value) {
            setText((value == null) ? ""
                    : value.equals(ResultSetTableModel.NULL_VALUE) ? ResultSetTableModel.NULL_VALUE
                            : value.toString());
        }
    }

    public void doRun() {
        runAction.actionPerformed(null);
    }

    public JEditorPane getEditorPane() {
        return sqlEditor.getEditorPanel().getEditorPane();
    }
}