|
Rank: Newbie
Groups: Registered
Joined: 9/26/2017 Posts: 5 Location: Germany
|
We're using RapidSpell Desktop Java version 2.2.1 in combination with JtextPanes with html content. In order to format the html text we have to perform html operations directly on the HtmlDocument (for example to insert a new paragraph "<p></p>" by pressing the ENTER key). Performing such an operation on a text line with misspelled words highlighted by RapidSpellAsYouType removes at least some of these highlights. This bug can also be reproduced with RapidSpell Desktop version 3.0.0 (evaluation). To preproduce, start the following code, type some misspelled words (which will be correct highlighted) and then press the ENTER button in the bottom right corner ( not the ENTER key). This button inserts a new paragraph and erases at least some of the highlights (if you press the enter button after typing a blank, the last of the highlights remains). Quote:import java.awt.*; import java.awt.event.*; import java.io.*;
import javax.swing.*; import javax.swing.text.*; import javax.swing.text.html.*;
import com.keyoti.rapidSpell.*; import com.keyoti.rapidSpell.desktop.*;
public class RapidSpellBug extends JFrame { public RapidSpellBug() { super(); this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); JPanel content = new JPanel(new GridBagLayout()); setContentPane(content); JTextPane pane = new JTextPane(); pane.setContentType("text/html"); pane.setText("<html><body><p></p></body></html>"); JScrollPane scroll = new JScrollPane(pane); scroll.setBorder(BorderFactory.createLineBorder(Color.black)); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.gridwidth = 1; c.gridheight = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.WEST; c.weightx = 1.0; c.weighty = 1.0; ((GridBagLayout)content.getLayout()).setConstraints(scroll, c); content.add(scroll); JButton button = new JButton("ENTER"); c = new GridBagConstraints(); c.gridx = 0; c.gridy = 1; c.gridwidth = 1; c.gridheight = 1; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; c.weightx = 0.0; c.weighty = 0.0; c.insets = new Insets(0, 3, 0, 0); ((GridBagLayout)content.getLayout()).setConstraints(button, c); content.add(button); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { HTMLDocument doc = (HTMLDocument)pane.getDocument(); pane.requestFocus(); int pos = doc.getLength() - 1; pane.setCaretPosition(pos); Element element = doc.getParagraphElement(pos);
HTML.Tag insertTag = HTML.getTag(element.getName()); int startOffset = element.getStartOffset(); int endOffset = element.getEndOffset(); try { String elementText = "<p>" + doc.getText(startOffset, endOffset - startOffset) + "</p>"; doc.setOuterHTML(element, elementText + "<p></p>"); } catch (BadLocationException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } } });
RapidSpellAsYouType asYouType = new RapidSpellAsYouType(); asYouType.setGUILanguage(LanguageType.GERMAN); asYouType.setLanguageParser(LanguageType.GERMAN); asYouType.getRapidSpellChecker().setSharedDictionary(true); asYouType.getRapidSpellChecker().optimizeForMemory = true;
asYouType.setCheckCompoundWords(true); asYouType.setIgnoreCapitalizedWords(false); asYouType.setIgnoreWordsWithDigits(false); asYouType.setLookIntoHyphenatedText(true); asYouType.setSeparateHyphenWords(false); asYouType.setSuggestSplitWords(false); asYouType.setIgnoreXML(true); asYouType.setTextComponent(pane); }
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception exception) { System.out.println("WARNUNG: Unsupported L&F !!!"); } RapidSpellBug test = new RapidSpellBug(); test.setSize(new Dimension(400,400)); test.setLocation(50,50); test.setVisible(true); }
}
|
|
Rank: Advanced Member
Groups: Administrators, Registered
Joined: 8/13/2004 Posts: 2,669 Location: Canada
|
You have to clear the highlights and recheck, because your code is pulling the rug out from under the spell checker, it doesn't like it. Code: button.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) { HTMLDocument doc = (HTMLDocument) pane.getDocument(); pane.requestFocus(); int pos = doc.getLength() - 1; pane.setCaretPosition(pos); Element element = doc.getParagraphElement(pos);
HTML.Tag insertTag = HTML.getTag(element.getName()); int startOffset = element.getStartOffset(); int endOffset = element.getEndOffset();
try { String elementText = "<p>" + doc.getText(startOffset, endOffset - startOffset) + "</p>"; doc.setOuterHTML(element, elementText + "<p></p>"); } catch (BadLocationException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } //************************************************************ asYouType.clearAllHighlights(); asYouType.forceCheckAll(); } });
best Jim -your feedback is helpful to other users, thank you!
|
|
Rank: Newbie
Groups: Registered
Joined: 9/26/2017 Posts: 5 Location: Germany
|
Thank you, that did it.
Unfortunately I now have another problem. The forced recheck calls "setSelectionStart(int)" (RapidSpellAsYouType.CheckNewText()) on one of my JTextPanes, which is currently not visible on the screen (it's inside a JSrollPane and currently scrolled out of sight). "setSelectionStart(int)" changes the caret position which calls the method "changeCaretPosition(int, Position$Bias)" of the class DefaultCaret. This method calls the method "repaintNewCaret()" which calls "adjustVisibility(Rectangle)". This last method calls "component.scrollRectToVisible()" which forces the mentioned JTextPane to the visible area, i.e. the Screen "jumps" to another component as the one currently changed.
As mentioned above we're using RapidSpell Desktop Java version 2.2.1 (currently with Java 1.8.0_131). Unfortunately the issue seems to happen only under certain circumstances, so I haven't been able to create a show case. However, in my application I have a data constellation which reproduces the issue always. Since it's always one specific JTextPane which causes the problem (and no other), maybe there's some special constellation which triggers RapidSpellAsYouType to call "setSelectionStart(int)" only on this JTextPane.
Do you have any ideas how to prevent this behaviour? My current solution disables the scrolling of all components but the one I have currently changed. This seems to work but it's quite crude. I would prefer a more elegant solution.
Best regards, Oliver
|
|
Rank: Advanced Member
Groups: Administrators, Registered
Joined: 8/13/2004 Posts: 2,669 Location: Canada
|
We can add code to only call setSelectionStart if the textbox is visible, that seems like it would help, but that's only possible for v3. -your feedback is helpful to other users, thank you!
|
|
Rank: Newbie
Groups: Registered
Joined: 9/26/2017 Posts: 5 Location: Germany
|
Simply checking for isVisible() (or isShowing()) wouldn't do it, because the questionable component is inside the same panel as the changed one (only scrolled out of sight), so isVisible() and isShowing() would both be true. So you would have to check if the components location is currently visible on screen. But we have also other text components which are really not visible() (i.e. on another tab of a JTabbedPane or inside another frame) so checking isVisible()/isShowing() in addition would also be reasonable.
A solution for v3 shouldn't be a problem, we're currently talking about upgrading.
|
|
Rank: Advanced Member
Groups: Administrators, Registered
Joined: 8/13/2004 Posts: 2,669 Location: Canada
|
Thanks, I'm with you. Ok a better solution is to be selective about what gets repainted, that's now possible in the v3 build. Change code to Code: public void actionPerformed(ActionEvent e) { HTMLDocument doc = (HTMLDocument) pane.getDocument(); pane.requestFocus(); int pos = doc.getLength() - 1; pane.setCaretPosition(pos); Element element = doc.getParagraphElement(pos);
HTML.Tag insertTag = HTML.getTag(element.getName()); int startOffset = element.getStartOffset(); int endOffset = element.getEndOffset();
try { String elementText = "<p>" + doc.getText(startOffset, endOffset - startOffset) + "</p>"; doc.setOuterHTML(element, elementText + "<p></p>"); } catch (BadLocationException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } asYouType.clearHighlights(pane); asYouType.forceCheck(pane); }
https://www.dropbox.com/...RapidSpellEval.jar?dl=0
-your feedback is helpful to other users, thank you!
|
|
Rank: Newbie
Groups: Registered
Joined: 9/26/2017 Posts: 5 Location: Germany
|
Thank you very much, that did it perfectly. Now the only thing we have to do is to upgrade to v3:-). Will the patch be included in the official download version after upgrading or do we need to get a special patched version?
By the way: if I'm right it's currently not possible to add or remove a single text component to/from RapidSpellAsYouType. But we are creating text components dynamically, so I always have to recompute the array of text components and set it as a whole (asYouType.setTextComponents(JTextComponent[])). Do you plan to add something like "addTextComponent(JTextComponent)" or "removeTextComponent(JTextComponent)" in future releases?
|
|
Rank: Advanced Member
Groups: Administrators, Registered
Joined: 8/13/2004 Posts: 2,669 Location: Canada
|
Quote: Thank you very much, that did it perfectly. Now the only thing we have to do is to upgrade to v3:-). Will the patch be included in the official download version after upgrading or do we need to get a special patched version?
It won't be included until the next release but let me know via sales@keyoti.com after purchase and I'll send the full patched version. Please use that email for any sales related questions too of course. Quote: By the way: if I'm right it's currently not possible to add or remove a single text component to/from RapidSpellAsYouType. But we are creating text components dynamically, so I always have to recompute the array of text components and set it as a whole (asYouType.setTextComponents(JTextComponent[])). Do you plan to add something like "addTextComponent(JTextComponent)" or "removeTextComponent(JTextComponent)" in future releases?
Yes you are right, and yes we will add those methods at some point, thanks for your feedback. Jim -your feedback is helpful to other users, thank you!
|
|
Rank: Newbie
Groups: Registered
Joined: 9/26/2017 Posts: 5 Location: Germany
|
Thanks Jim, you'll hear from us via sales@keyoti.com. Oliver
|
|