#181523: adding factory method for creating unified single line editors diff --git a/editor.lib/apichanges.xml b/editor.lib/apichanges.xml --- a/editor.lib/apichanges.xml +++ b/editor.lib/apichanges.xml @@ -104,6 +104,21 @@ + + Adding Utilities.createSingleLineEditor + + + + + +

+ Adding o.n.editor.Utilities.createSingleLineEditor(String mimeType) method + in order to give modules a unified way of creating simple TextField-like + controls. +

+
+
+ Hiding listener methods from public API diff --git a/editor.lib/nbproject/project.properties b/editor.lib/nbproject/project.properties --- a/editor.lib/nbproject/project.properties +++ b/editor.lib/nbproject/project.properties @@ -39,7 +39,7 @@ javac.compilerargs=-Xlint:unchecked javac.source=1.6 -spec.version.base=2.6 +spec.version.base=2.7 is.autoload=true javadoc.arch=${basedir}/arch.xml diff --git a/editor.lib/src/org/netbeans/editor/Utilities.java b/editor.lib/src/org/netbeans/editor/Utilities.java --- a/editor.lib/src/org/netbeans/editor/Utilities.java +++ b/editor.lib/src/org/netbeans/editor/Utilities.java @@ -41,18 +41,31 @@ package org.netbeans.editor; +import java.awt.AWTKeyStroke; import java.awt.Rectangle; import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; import java.awt.Insets; +import java.awt.KeyboardFocusManager; import java.awt.Shape; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.geom.Rectangle2D; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.SwingUtilities; import javax.swing.Action; +import javax.swing.InputMap; +import javax.swing.JComponent; +import javax.swing.JEditorPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; import javax.swing.KeyStroke; +import javax.swing.border.CompoundBorder; +import javax.swing.border.EmptyBorder; import javax.swing.text.JTextComponent; import javax.swing.text.BadLocationException; import javax.swing.text.EditorKit; @@ -65,6 +78,7 @@ import javax.swing.text.Element; import javax.swing.text.View; import org.netbeans.api.editor.EditorRegistry; +import org.netbeans.api.editor.mimelookup.MimeLookup; import org.netbeans.lib.editor.util.CharSequenceUtilities; import org.netbeans.lib.editor.util.swing.DocumentUtilities; import org.netbeans.modules.editor.lib.drawing.DrawEngineDocView; @@ -1540,4 +1554,75 @@ } return null; } + + /** + * Creates a single line editor pane. Can be called from AWT event thread only. + * + * @param mimeType The mimetype of the editor's content. + * + * @return Two components, the first one is a visual JComponent and + * the second one is the editor JTextComponent. + * + * @since 2.7 + */ + public static JComponent [] createSingleLineEditor(String mimeType) { + assert SwingUtilities.isEventDispatchThread() + : "Utilities.createSingleLineEditor must be called from AWT thread only"; // NOI18N + + EditorKit kit = MimeLookup.getLookup(mimeType).lookup(EditorKit.class); + if (kit == null) { + throw new IllegalArgumentException("No EditorKit for '" + mimeType + "' mimetype."); //NOI18N + } + + JEditorPane editorPane = new JEditorPane(); + editorPane.setEditorKit(kit); + + editorPane.putClientProperty( + "HighlightsLayerExcludes", //NOI18N + "^org\\.netbeans\\.modules\\.editor\\.lib2\\.highlighting\\.CaretRowHighlighting$" //NOI18N + ); + getEditorUI(editorPane).textLimitLineVisible = false; + + KeyStroke enterKs = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); + KeyStroke escKs = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); + KeyStroke tabKs = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0); + InputMap im = editorPane.getInputMap(); + im.put(enterKs, NO_ACTION); + im.put(escKs, NO_ACTION); + im.put(tabKs, NO_ACTION); + + editorPane.setBorder ( + new CompoundBorder (editorPane.getBorder(), + new EmptyBorder (0, 0, 0, 0)) + ); + + JTextField referenceTextField = new JTextField("M"); //NOI18N + Set tfkeys = referenceTextField.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); + editorPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, tfkeys); + tfkeys = referenceTextField.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); + editorPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, tfkeys); + + JScrollPane sp = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + sp.setBorder(referenceTextField.getBorder()); + sp.setBackground(referenceTextField.getBackground()); + + JPanel panel = new JPanel(new GridBagLayout()); + panel.setBackground(referenceTextField.getBackground()); + GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + gridBagConstraints.weightx = 1.0; + panel.add(editorPane, gridBagConstraints); + sp.setViewportView(panel); + + int preferredHeight = referenceTextField.getPreferredSize().height; + if (sp.getPreferredSize().height < preferredHeight) { + sp.setPreferredSize(referenceTextField.getPreferredSize()); + } + sp.setMinimumSize(sp.getPreferredSize()); + + return new JComponent [] { sp, editorPane }; + } + + private static final String NO_ACTION = "no-action"; //NOI18N } diff --git a/spi.debugger.ui/nbproject/project.xml b/spi.debugger.ui/nbproject/project.xml --- a/spi.debugger.ui/nbproject/project.xml +++ b/spi.debugger.ui/nbproject/project.xml @@ -61,7 +61,7 @@ 2 - 2.1 + 2.7 @@ -70,7 +70,7 @@ 1 - 1.11 + 1.24 diff --git a/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/WatchPanel.java b/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/WatchPanel.java --- a/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/WatchPanel.java +++ b/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/WatchPanel.java @@ -40,7 +40,6 @@ */ package org.netbeans.modules.debugger.ui; -import java.awt.AWTKeyStroke; import org.openide.awt.Mnemonics; import org.openide.util.NbBundle; @@ -49,22 +48,11 @@ import javax.swing.border.CompoundBorder; import java.util.*; import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.KeyboardFocusManager; -import java.awt.event.KeyEvent; -import java.io.IOException; -import javax.swing.text.StyledDocument; +import javax.swing.text.JTextComponent; import org.netbeans.api.editor.DialogBinding; -import org.netbeans.editor.EditorUI; +import org.netbeans.editor.Utilities; import org.netbeans.spi.debugger.ui.EditorContextDispatcher; -import org.openide.ErrorManager; -import org.openide.cookies.EditorCookie; import org.openide.filesystems.FileObject; -import org.openide.loaders.DataObject; -import org.openide.loaders.DataObjectNotFoundException; -import org.openide.text.NbDocument; /** * A GUI panel for customizing a Watch. @@ -74,7 +62,7 @@ public class WatchPanel { private JPanel panel; - private JEditorPane editorPane; + private JTextComponent editorPane; private String expression; public WatchPanel(String expression) { @@ -94,23 +82,20 @@ panel.setLayout (new BorderLayout ()); panel.setBorder (new EmptyBorder (11, 12, 1, 11)); panel.add (BorderLayout.NORTH, textLabel); + + FileObject file = EditorContextDispatcher.getDefault().getMostRecentFile(); + int line = EditorContextDispatcher.getDefault().getMostRecentLineNumber(); + //Add JEditorPane and context - editorPane = new JEditorPane();//expression); // NOI18N + JComponent [] editorComponents = Utilities.createSingleLineEditor(file.getMIMEType()); + editorPane = (JTextComponent) editorComponents[1]; + DialogBinding.bindComponentToFile(file, line, 0, 0, editorPane); editorPane.setText(expression); - setupContext(editorPane, - EditorContextDispatcher.getDefault().getMostRecentFile(), - EditorContextDispatcher.getDefault().getMostRecentLineNumber()); editorPane.setText (expression); editorPane.selectAll (); - JScrollPane sp = createScrollableLineEditor(editorPane); - int h = sp.getPreferredSize().height; - int w = Math.min(70*editorPane.getFontMetrics(editorPane.getFont()).charWidth('a'), - org.openide.windows.WindowManager.getDefault().getMainWindow().getSize().width); - sp.setPreferredSize(new Dimension(w, h)); - - panel.add (BorderLayout.CENTER, sp); + panel.add (BorderLayout.CENTER, editorComponents[0]); editorPane.getAccessibleContext ().setAccessibleDescription (bundle.getString ("ACSD_CTL_Watch_Name")); // NOI18N editorPane.setBorder ( new CompoundBorder (editorPane.getBorder (), @@ -129,114 +114,6 @@ return panel; } - private static void setupUI(final JEditorPane editorPane) { - Runnable runnable = new Runnable() { - public void run() { - EditorUI eui = org.netbeans.editor.Utilities.getEditorUI(editorPane); - if (eui == null) { - return; - } - editorPane.putClientProperty( - "HighlightsLayerExcludes", //NOI18N - "^org\\.netbeans\\.modules\\.editor\\.lib2\\.highlighting\\.CaretRowHighlighting$" //NOI18N - ); - // Do not draw text limit line - try { - java.lang.reflect.Field textLimitLineField = EditorUI.class.getDeclaredField("textLimitLineVisible"); // NOI18N - textLimitLineField.setAccessible(true); - textLimitLineField.set(eui, false); - } catch (Exception ex) {} - } - }; - if (SwingUtilities.isEventDispatchThread()) { - runnable.run(); - } else { - SwingUtilities.invokeLater(runnable); - } - } - - private static void setupContext(JEditorPane editorPane, FileObject file, int line) { - if (line < 1) { - line = 1; - } - StyledDocument doc; - if (file == null) { - return; - } - try { - DataObject dobj = DataObject.find (file); - EditorCookie ec = dobj.getCookie(EditorCookie.class); - if (ec == null) { - return; - } - try { - doc = ec.openDocument(); - } catch (IOException ex) { - ErrorManager.getDefault().notify(ex); - return; - } - } catch (DataObjectNotFoundException ex) { - // null dobj - return; - } - try { - int offset = NbDocument.findLineOffset(doc, line - 1); // findLineOffset() expects zero based line numbers - //editorPane.getDocument().putProperty(javax.swing.text.Document.StreamDescriptionProperty, dobj); - //System.err.println("WatchPanel.setupContext("+file+", "+line+", "+offset+")"); - DialogBinding.bindComponentToDocument(doc, offset, 0, editorPane); - } catch (IndexOutOfBoundsException ioobex) { - ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioobex); - } - setupUI(editorPane); - } - - private static JScrollPane createScrollableLineEditor(JEditorPane editorPane) { - // Remove control keys: - KeyStroke enterKs = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); - KeyStroke escKs = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); - KeyStroke tabKs = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0); - InputMap im = editorPane.getInputMap(); - im.put(enterKs, "none"); - im.put(escKs, "none"); - im.put(tabKs, "none"); - - final JScrollPane sp = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_NEVER, - JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - - editorPane.setBorder ( - new CompoundBorder (editorPane.getBorder(), - new EmptyBorder (0, 0, 0, 0)) - ); - - JTextField referenceTextField = new JTextField("M"); - JPanel panel = new JPanel(new GridBagLayout()); - panel.setBackground(referenceTextField.getBackground()); - sp.setBorder(referenceTextField.getBorder()); - sp.setBackground(referenceTextField.getBackground()); - - GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; - gridBagConstraints.weightx = 1.0; - panel.add(editorPane, gridBagConstraints); - sp.setViewportView(panel); - - int preferredHeight = referenceTextField.getPreferredSize().height; - if (sp.getPreferredSize().height < preferredHeight) { - sp.setPreferredSize(referenceTextField.getPreferredSize()); - } - sp.setMinimumSize(sp.getPreferredSize()); - - setupUI(editorPane); - - Set tfkeys = referenceTextField.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); - editorPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, tfkeys); - tfkeys = referenceTextField.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); - editorPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, tfkeys); - return sp; - } - - public String getExpression() { return editorPane.getText().trim(); }