You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2009/03/12 11:22:56 UTC

svn commit: r752828 - in /cayenne/main/trunk/framework: cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/ cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/validation/ cayenne-modeler/src/main/java/org/apache/caye...

Author: aadamchik
Date: Thu Mar 12 10:22:47 2009
New Revision: 752828

URL: http://svn.apache.org/viewvc?rev=752828&view=rev
Log:
CAY-1164  Implement EJBQL query support in the Modeler

patch by Olga Tkachova - preliminary code showing EJBQL errors

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/EJBQLQueryValidator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/validation/EJBQlQueryValidatorTest.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/TreeNodeValidator.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlQueryScriptsTab.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlTabbedView.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/JCayenneTextPane.java

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/EJBQLQueryValidator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/EJBQLQueryValidator.java?rev=752828&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/EJBQLQueryValidator.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/EJBQLQueryValidator.java Thu Mar 12 10:22:47 2009
@@ -0,0 +1,191 @@
+/*****************************************************************
+ *   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 org.apache.cayenne.project.validator;
+
+import java.lang.reflect.Field;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.ejbql.EJBQLException;
+
+import org.apache.cayenne.project.ProjectPath;
+import org.apache.cayenne.query.EJBQLQuery;
+
+public class EJBQLQueryValidator extends TreeNodeValidator {
+
+    // private DataDomain dd;
+    @Override
+    public void validateObject(ProjectPath treeNodePath, Validator validator) {
+        EJBQLQuery query = (EJBQLQuery) treeNodePath.getObject();
+        PositionException message = validateEJBQL(query, treeNodePath
+                .firstInstanceOf(DataDomain.class));
+
+        if (message != null) {
+            validator.registerWarning(
+                    "EJBQL query " + query.getName() + " has error.",
+                    treeNodePath);
+        }
+    }
+
+    public PositionException validateEJBQL(EJBQLQuery query, DataDomain dd) {
+
+        if (query.getEjbqlStatement() != null) {
+            PositionException message = null;
+
+            try {
+                query.getExpression(dd.getEntityResolver());
+            }
+            catch (CayenneRuntimeException e) {
+                message = new PositionException();
+                message.setE(e);
+                if (e.getCause() != null) {
+
+                    message.setMessage(e.getCause().getMessage());
+
+                    if (e instanceof EJBQLException) {
+
+                        EJBQLException ejbqlException = (EJBQLException) e;
+                        Throwable cause = ejbqlException.getCause();
+
+                        try {
+                            Field tokenField = cause.getClass().getField("currentToken");
+
+                            Object token = tokenField.get(cause);
+                            Field nextTokenField = token.getClass().getField("next");
+                            Object nextToken = nextTokenField.get(token);
+                            Field beginColumnField = nextToken.getClass().getField(
+                                    "beginColumn");
+                            Field beginLineField = nextToken.getClass().getField(
+                                    "beginLine");
+                            Field endColumnField = nextToken.getClass().getField(
+                                    "endColumn");
+                            Field endLineField = nextToken.getClass().getField("endLine");
+                            Field imageField = nextToken.getClass().getField("image");
+
+                            message.setBeginColumn((Integer) beginColumnField
+                                    .get(nextToken));
+                            message.setBeginLine((Integer) beginLineField.get(nextToken));
+                            message.setEndColumn((Integer) endColumnField.get(nextToken));
+                            message.setEndLine((Integer) endLineField.get(nextToken));
+                            message.setImage((String) imageField.get(nextToken));
+                            message.setLength(message.getImage().length());
+                        }
+                        catch (Exception e1) {
+                            throw new CayenneRuntimeException(e1);
+                        }
+
+                    }
+                }
+                else {
+                    message.setE(e);
+                    message.setMessage(e.getUnlabeledMessage());
+                }
+
+            }
+            catch (Exception e) {
+                message = new PositionException();
+                message.setE(e);
+                message.setMessage(e.getMessage());
+            }
+
+            return message;
+        }
+        else {
+            return null;
+        }
+
+    }
+
+    public class PositionException {
+
+        private Integer beginColumn;
+        private Integer beginLine;
+        private Integer endColumn;
+        private Integer endLine;
+        private Integer length;
+        private String image;
+        private String message;
+        private Exception e;
+
+        public Integer getLength() {
+            return length;
+        }
+
+        public void setLength(Integer length) {
+            this.length = length;
+        }
+
+        public Exception getE() {
+            return e;
+        }
+
+        public void setE(Exception e) {
+            this.e = e;
+        }
+
+        public String getMessage() {
+            return message;
+        }
+
+        public void setMessage(String message) {
+            this.message = message;
+        }
+
+        public Integer getBeginColumn() {
+            return beginColumn;
+        }
+
+        public void setBeginColumn(Integer beginColumn) {
+            this.beginColumn = beginColumn;
+        }
+
+        public Integer getBeginLine() {
+            return beginLine;
+        }
+
+        public void setBeginLine(Integer beginLine) {
+            this.beginLine = beginLine;
+        }
+
+        public Integer getEndColumn() {
+            return endColumn;
+        }
+
+        public void setEndColumn(Integer endColumn) {
+            this.endColumn = endColumn;
+        }
+
+        public Integer getEndLine() {
+            return endLine;
+        }
+
+        public void setEndLine(Integer endLine) {
+            this.endLine = endLine;
+        }
+
+        public String getImage() {
+            return image;
+        }
+
+        public void setImage(String image) {
+            this.image = image;
+        }
+    }
+
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/TreeNodeValidator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/TreeNodeValidator.java?rev=752828&r1=752827&r2=752828&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/TreeNodeValidator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/TreeNodeValidator.java Thu Mar 12 10:22:47 2009
@@ -32,6 +32,7 @@
 import org.apache.cayenne.map.Procedure;
 import org.apache.cayenne.map.ProcedureParameter;
 import org.apache.cayenne.project.ProjectPath;
+import org.apache.cayenne.query.EJBQLQuery;
 import org.apache.cayenne.query.ProcedureQuery;
 import org.apache.cayenne.query.SQLTemplate;
 import org.apache.cayenne.query.SelectQuery;
@@ -60,6 +61,7 @@
     protected static final SelectQueryValidator selectQueryValidator = new SelectQueryValidator();
 
     protected static final ProcedureQueryValidator procedureQueryValidator = new ProcedureQueryValidator();
+    protected static final EJBQLQueryValidator ejbqlQueryValidator = new EJBQLQueryValidator();
 
     protected static final SQLTemplateValidator sqlTemplateValidator = new SQLTemplateValidator();
 
@@ -115,6 +117,9 @@
         else if (validatedObj instanceof ProcedureQuery) {
             validatorObj = procedureQueryValidator;
         }
+        else if (validatedObj instanceof EJBQLQuery) {
+            validatorObj = ejbqlQueryValidator;
+        }
         else {
             // ignore unknown nodes
             return;

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/validation/EJBQlQueryValidatorTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/validation/EJBQlQueryValidatorTest.java?rev=752828&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/validation/EJBQlQueryValidatorTest.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/validation/EJBQlQueryValidatorTest.java Thu Mar 12 10:22:47 2009
@@ -0,0 +1,76 @@
+/*****************************************************************
+ *   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 org.apache.cayenne.validation;
+
+import org.apache.cayenne.project.validator.EJBQLQueryValidator;
+import org.apache.cayenne.project.validator.EJBQLQueryValidator.PositionException;
+import org.apache.cayenne.query.EJBQLQuery;
+import org.apache.cayenne.unit.CayenneCase;
+
+
+public class EJBQlQueryValidatorTest  extends CayenneCase{
+
+    public void testValidateEJBQL(){
+        String[] ejbqlError = new String[] {
+                "select g from G g",
+                "select Artist FROM Artist",
+                "select f from g", 
+                "dddd",
+                "select g.f from g",
+                "select Artist.f from Artist", 
+                "select Artist.f FROM Artist a",
+                "select a FROM Artist a WHERE a.artistName = ?1 OR ",
+                "select b FROM Artist a WHERE a.artistName = ?1 OR a.artistName = :nam",
+                "select artistName FROM Artist a WHERE a.artistName = ?1 OR a.artistName = :name",
+                "select a FROM Artist a WHERE a.artistName = ?",
+                "select a FROM Artist a WHERE  OR a.artistName = :name",
+                "select b FROM Artist b WHERE  a.artistName = :name",
+                "a FROM Artist a",
+                "ubdate a FROM Artist a",
+                "update a FROM Artist"
+        };
+        Object[] typeError = new Object[] {
+                new org.apache.cayenne.CayenneRuntimeException(),
+                new java.lang.NullPointerException(),
+                new java.lang.NullPointerException(),
+                new org.apache.cayenne.ejbql.EJBQLException(), 
+                new org.apache.cayenne.CayenneRuntimeException(),
+                new org.apache.cayenne.ejbql.EJBQLException(), 
+                new org.apache.cayenne.ejbql.EJBQLException(),
+                new org.apache.cayenne.ejbql.EJBQLException(),
+                new java.lang.NullPointerException(),
+                new java.lang.NullPointerException(),
+                new org.apache.cayenne.ejbql.EJBQLException(),
+                new org.apache.cayenne.ejbql.EJBQLException(),
+                new org.apache.cayenne.ejbql.EJBQLException(), 
+                new org.apache.cayenne.ejbql.EJBQLException(),
+                new org.apache.cayenne.ejbql.EJBQLException(),
+                new org.apache.cayenne.ejbql.EJBQLException()
+        };
+        
+        
+
+        for (int i=0; i<ejbqlError.length;i++) {            
+            EJBQLQuery queryError = new EJBQLQuery(ejbqlError[i]);
+            EJBQLQueryValidator ejbqlQueryValidator = new EJBQLQueryValidator();
+            PositionException s = ejbqlQueryValidator.validateEJBQL(queryError, getDomain());
+            assertEquals(typeError[i].getClass(),s.getE().getClass());
+          }
+    }
+}

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlQueryScriptsTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlQueryScriptsTab.java?rev=752828&r1=752827&r2=752828&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlQueryScriptsTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlQueryScriptsTab.java Thu Mar 12 10:22:47 2009
@@ -19,6 +19,9 @@
 package org.apache.cayenne.modeler.editor;
 
 import java.awt.BorderLayout;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+
 import javax.swing.JPanel;
 import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;
@@ -28,6 +31,8 @@
 import org.apache.cayenne.map.event.QueryEvent;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.util.CayenneWidgetFactory;
+import org.apache.cayenne.project.validator.EJBQLQueryValidator;
+import org.apache.cayenne.project.validator.EJBQLQueryValidator.PositionException;
 import org.apache.cayenne.query.EJBQLQuery;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.swing.components.textpane.JCayenneTextPane;
@@ -36,13 +41,9 @@
 public class EjbqlQueryScriptsTab extends JPanel implements DocumentListener {
 
     protected ProjectController mediator;
-
-    /**
-     * JEdit text component for highlighing SQL syntax (see CAY-892)
-     */
     protected JCayenneTextPane scriptArea;
-    protected JPanel panelArea;
     private boolean updateDisabled;
+    protected EJBQLQueryValidator ejbqlQueryValidator = new EJBQLQueryValidator();
 
     public EjbqlQueryScriptsTab(ProjectController mediator) {
         this.mediator = mediator;
@@ -51,7 +52,6 @@
 
     void displayScript() {
         EJBQLQuery query = getQuery();
-        updateDisabled = true;
         scriptArea.setText(query.getEjbqlStatement());
         updateDisabled = false;
     }
@@ -60,7 +60,17 @@
 
         scriptArea = CayenneWidgetFactory.createJEJBQLTextPane();
         scriptArea.getDocument().addDocumentListener(this);
+        scriptArea.addFocusListener(new FocusListener() {
+
+            public void focusGained(FocusEvent e) {
+                validateEJBQL();
+            }
+
+            public void focusLost(FocusEvent e) {
+                validateEJBQL();
+            }
 
+        });
         setLayout(new BorderLayout());
         add(scriptArea, BorderLayout.WEST);
         add(scriptArea.scrollPane, BorderLayout.CENTER);
@@ -76,6 +86,8 @@
         }
         scriptArea.setEnabled(true);
         displayScript();
+
+        validateEJBQL();
         setVisible(true);
 
     }
@@ -87,7 +99,6 @@
 
     void setEJBQL(DocumentEvent e) {
         Document doc = e.getDocument();
-
         try {
             setEJBQL(doc.getText(0, doc.getLength()));
         }
@@ -131,4 +142,18 @@
             setEJBQL(e);
         }
     }
+
+    void validateEJBQL() {
+        PositionException positionException = ejbqlQueryValidator.validateEJBQL(
+                getQuery(),
+                mediator.getCurrentDataDomain());
+        if (positionException != null) {
+
+            scriptArea.setHighlightText(
+                    positionException.getBeginLine(),
+                    positionException.getBeginColumn(),
+                    positionException.getLength());
+
+        }
+    }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlTabbedView.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlTabbedView.java?rev=752828&r1=752827&r2=752828&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlTabbedView.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EjbqlTabbedView.java Thu Mar 12 10:22:47 2009
@@ -22,6 +22,7 @@
 import javax.swing.JTabbedPane;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
+
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.event.QueryDisplayEvent;
 import org.apache.cayenne.modeler.event.QueryDisplayListener;

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/JCayenneTextPane.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/JCayenneTextPane.java?rev=752828&r1=752827&r2=752828&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/JCayenneTextPane.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/swing/components/textpane/JCayenneTextPane.java Thu Mar 12 10:22:47 2009
@@ -18,8 +18,11 @@
 import javax.swing.text.Document;
 import javax.swing.text.Highlighter;
 
+import org.apache.cayenne.modeler.Main;
 import org.apache.cayenne.swing.components.textpane.syntax.SQLSyntaxConstants;
 import org.apache.cayenne.swing.components.textpane.syntax.SyntaxConstant;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 public class JCayenneTextPane extends JPanel {
 
@@ -27,6 +30,7 @@
     private JTextPaneScrollable pane;
     public JScrollPane scrollPane;
     public boolean repaint;
+    private static Log logObj = LogFactory.getLog(Main.class);
 
     public void setText(String text) {
         pane.setText(text);
@@ -63,6 +67,7 @@
             y = (int) caretCoords.getY();
         }
         catch (BadLocationException ex) {
+            logObj.warn("Error: " , ex);
         }
 
         int lineHeight = pane.getFontMetrics(pane.getFont()).getHeight();
@@ -103,7 +108,8 @@
         setMinimumSize(new Dimension(30, 30));
         setBackground(new Color(245, 238, 238));
         setBorder(null);
-        pane = new JTextPaneScrollable(new EditorKit(syntaxConstant)) {           
+        pane = new JTextPaneScrollable(new EditorKit(syntaxConstant)) {
+
             public void paint(Graphics g) {
                 super.paint(g);
                 JCayenneTextPane.this.repaint();
@@ -122,35 +128,21 @@
             public void insertUpdate(DocumentEvent evt) {
                 try {
                     removeHighlightText();
-                }
-                catch (BadLocationException e) {
-                    e.printStackTrace();
-                }
-
-                try {
                     if (pane.getText(evt.getOffset(), 1).toString().equals("/")
                             || pane.getText(evt.getOffset(), 1).toString().equals("*")) {
                         pane.repaint();
-                    }
+                    } 
                 }
-                catch (BadLocationException e) {
-                    // TODO Auto-generated catch block
-                    e.printStackTrace();
+                catch (Exception e) {
+                    logObj.warn("Error: " , e);
                 }
             }
 
             public void removeUpdate(DocumentEvent evt) {
-                try {
-                    removeHighlightText();
-                }
-                catch (BadLocationException e) {
-                    e.printStackTrace();
-                }
-
+                removeHighlightText();
             }
 
             public void changedUpdate(DocumentEvent evt) {
-
             }
 
         });
@@ -162,17 +154,22 @@
         highlighter.addHighlight(lastIndex, endIndex, painter);
     }
 
-    public void setHighlightText(int line, int lastIndex, int size)
-            throws BadLocationException {
+    public void setHighlightText(int line, int lastIndex, int size) {
 
-        int position = getPosition(line, lastIndex);
-        int positionEnd = position + size;
-        Highlighter highlighter = pane.getHighlighter();
-        removeHighlightText(highlighter);
-        highlighter.addHighlight(position, positionEnd, painter);
+        int position;
+        try {
+            position = getPosition(line, lastIndex);
+            int positionEnd = position + size;
+            Highlighter highlighter = pane.getHighlighter();
+            removeHighlightText(highlighter);
+            highlighter.addHighlight(position, positionEnd, painter);
+        }
+        catch (BadLocationException e) {
+            logObj.warn("Error: " , e);
+        }
     }
 
-    public void removeHighlightText(Highlighter highlighter) throws BadLocationException {
+    public void removeHighlightText(Highlighter highlighter) {
 
         Highlighter.Highlight[] highlights = highlighter.getHighlights();
         for (int i = 0; i < highlights.length; i++) {
@@ -183,7 +180,7 @@
         }
     }
 
-    public void removeHighlightText() throws BadLocationException {
+    public void removeHighlightText() {
         Highlighter highlighter = pane.getHighlighter();
         removeHighlightText(highlighter);
     }
@@ -206,13 +203,18 @@
         int starting_y = -1;
 
         try {
-            starting_y = pane.modelToView(start).y
-                    - scrollPane.getViewport().getViewPosition().y
-                    + fontHeight
-                    - fontDesc;
+            if (pane.modelToView(start) == null) {
+                starting_y = -1;
+            }
+            else {
+                starting_y = pane.modelToView(start).y
+                        - scrollPane.getViewport().getViewPosition().y
+                        + fontHeight
+                        - fontDesc;
+            }
         }
-        catch (BadLocationException e1) {
-            e1.printStackTrace();
+        catch (Exception e1) {
+            logObj.warn("Error: " , e1);
         }
 
         for (int line = startline, y = starting_y; line <= endline; y += fontHeight, line++) {
@@ -235,7 +237,7 @@
 
     class JTextPaneScrollable extends JTextPane {
 
-        // private static final long serialVersionUID = 6270183148379328084L;
+        private static final long serialVersionUID = 1L;
 
         public JTextPaneScrollable(EditorKit editorKit) {
             // Set editor kit