tuliob / jsyntaxpane

Automatically exported from code.google.com/p/jsyntaxpane
0 stars 0 forks source link

SyntaxActions hijack all editor panes #19

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Add another JEditorPane and JScrollPane to SyntaxTester
2. Do not call setEditorKit() on the second editorpane
3. setContentType("text/html") on the second editorpane
4. start SyntaxTester

What is the expected output? What do you see instead?
1. Type "(" in the second pane.  
Expected: no autocomplete
Actual: autocomplete

2. Type [tab] in the second pane
Expected: tab
Actual: exception 

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException:
javax.swing.text.html.HTMLDocument cannot be cast to
javax.swing.text.PlainDocument
    at
jsyntaxpane.SyntaxActions$IndentAction.actionPerformed(SyntaxActions.java:122)

see attached SyntaxTester.java for repro

Original issue reported on code.google.com by javlo...@gmail.com on 9 Aug 2008 at 5:09

Attachments:

GoogleCodeExporter commented 9 years ago
Problem re-created.  I'm investigating it now...

Original comment by ayman.al...@gmail.com on 12 Aug 2008 at 6:44

GoogleCodeExporter commented 9 years ago
Problem is that in SyntaxActions, at about line 340 (labeled 7 here):
1    public static void addAction(JTextComponent control, String stroke,
2            TextAction action) {
3        KeyStroke ks = KeyStroke.getKeyStroke(stroke);
4        if (ks == null) {
5            throw new IllegalArgumentException("invalid keystroke: " + stroke);
6        }
7        control.getKeymap().addActionForKeyStroke(ks, action);
8    }

The same keymap is used by all EditorPanes.  Probably the default one.  Need a 
way to
add bindings to a specific keymap just for that pane.  I'll research the Keymap
hierarchy classes later when I have a chance.  

Could be tricky, but a very good bug catch!

Original comment by ayman.al...@gmail.com on 12 Aug 2008 at 7:05

GoogleCodeExporter commented 9 years ago
Looked at Swing keymaps, and so far no idea how to resolve this.  Most keymap 
methods
are static methods of the TextComponent.  So how can I add a key binding to 
just one
component?  Any ideas anybody?

Original comment by ayman.al...@gmail.com on 15 Aug 2008 at 8:15

GoogleCodeExporter commented 9 years ago
Thanks @javlopez for finding this tricky issue!

Think we should create a custom Keymap and do setKeymap() on JTextComponent. 
When we
do a getKeymap(), this custom object will be returned to us. I don't know if we 
can
clone() the existing Keymap and set it again:

// init code
Keymap commonKeymap = control.getKeymap();
Keymap customKeymap = (Keymap)((Colonable)commonKeymap).clone();
control.setKeymap(customKeymap);

// Later
control.getKeymap().addActionForKeyStroke(ks, action);

Original comment by subwiz on 16 Aug 2008 at 7:29

GoogleCodeExporter commented 9 years ago
I am getting class cast exception when trying to cast to Cloneable! So above 
approach
does not hold good!

Original comment by subwiz on 16 Aug 2008 at 8:06

GoogleCodeExporter commented 9 years ago
<quote>
JTextComponent defines getKeymap() and setKeymap() methods you can use to query 
and
set the current keymap of a text component. There are no public implementations 
of
the Keymap  interface, so you cannot instantiate one directly. Instead, create 
a new
Keymap by calling the static JTextComponent.addKeymap() method. This method 
allows
you to specify a name and parent for the new Keymap. Both arguments are 
optional,
however, so you may pass in null.
</quote>

From: http://www.unix.com.ua/orelly/java-ent/jfc/ch03_08.htm

And see this for creating private keymap which is used only by our component:

http://books.google.com/books?id=E0HGXKrxcS8C&pg=PA89&lpg=PA89&dq=swing+Keymap+c
ommon+to+all+component&source=web&ots=jeZVgHPlH5&sig=wArw85z8_ZV_q9FZKvCsQt9FHEA
&hl=en&sa=X&oi=book_result&resnum=3&ct=result

So basically, it is:

// init
Keymap jsyntaxpaneKeyMap = JTextComponent.addKeymap(null,
JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP);

// immdtly after creating TextComponent:
control.setKeymap(jsyntaxpaneKeyMap);

// Now, this should work:
control.getKeymap().addActionForKeyStroke(ks, action);

Original comment by subwiz on 16 Aug 2008 at 8:22

GoogleCodeExporter commented 9 years ago
Rev. 30 has a fix. Let me know if it works!

Original comment by subwiz on 16 Aug 2008 at 8:58

GoogleCodeExporter commented 9 years ago
Another regression issue was fixed in rev.31.

Original comment by subwiz on 16 Aug 2008 at 9:35