简体   繁体   English

Java Swing 拼写检查器

[英]Java Swing Spell Checker

I have a quick question about implementing my SpellChecker into my Swing Text Editor.我有一个关于在我的 Swing 文本编辑器中实施我的拼写检查器的快速问题。 I tried to search around but couldn't find anything on how to get the red squiggly line under misspelled words.我试图四处搜索,但找不到任何关于如何在拼写错误的单词下显示红色波浪线的信息。 Is there something I could import then call on those misspellings?有什么我可以导入然后调用那些拼写错误的东西吗? Also, how would I be able to make a menu pop up when I right-click on those miss spelled words?另外,当我右键单击那些拼写错误的单词时,如何弹出菜单? Thanks谢谢

There is plenty of material out there depending on what you want to do...有很多材料取决于你想做什么......

First of, use a JTextPane , which supports nice text formatting options.首先,使用JTextPane ,它支持很好的文本格式设置选项。

How to underline text:如何给文本加下划线:

Comments are included as explanations.评论作为解释包含在内。

import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

public class WordUnderline {
    public static void main(final String[] args) {
        SwingUtilities.invokeLater(() -> {
            final Style defaultStyle = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
            
            final JTextPane pane = new JTextPane();
            
            //My super-creative text...
            pane.setText("These are words...\nHere come more words!\nWord word word.");
            
            final StyledDocument doc = pane.getStyledDocument();
            doc.addDocumentListener(new DocumentListener() {
                private void clearStyle(final DocumentEvent e) {
                    SwingUtilities.invokeLater(() -> doc.setCharacterAttributes(0, doc.getLength(), defaultStyle, true));
                }
                
                @Override
                public void insertUpdate(final DocumentEvent e) {
                    //When you type a new letter, we want to (lets say) clear all the styles from the whole document...
                    clearStyle(e);
                }

                @Override
                public void removeUpdate(final DocumentEvent e) {
                    //When you erase a letter, we want to (lets say) clear all styles from the whole document...
                    clearStyle(e);
                }

                @Override
                public void changedUpdate(final DocumentEvent e) {
                    //When changing the style of the document, we want to do nothing else (but the change will happen).
                }
            });
            
            final JButton doit = new JButton("Underline selected text!");
            doit.addActionListener(e -> {
                final SimpleAttributeSet sas = new SimpleAttributeSet();
                StyleConstants.setUnderline(sas, true);
                /*I would suggest here to experiment a bit with the StyleConstants
                class... For example: StyleConstants.setBackground(sas, Color.RED);*/
                final int start = pane.getSelectionStart();
                final int end = pane.getSelectionEnd();
                doc.setCharacterAttributes(start, end - start, sas, true);
            });
            
            final JPanel contents = new JPanel(new BorderLayout());
            contents.add(doit, BorderLayout.PAGE_START);
            contents.add(pane, BorderLayout.CENTER);
            
            final JFrame frame = new JFrame("Word underline.");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(contents);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

How to pop a menu on word selection:如何在单词选择时弹出菜单:

Comments are included as explanations.评论作为解释包含在内。

import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;
import javax.swing.text.Utilities;

public class WordPopUp {
    public static void main(final String[] args) {
        SwingUtilities.invokeLater(() -> {
            final JTextPane pane = new JTextPane();
            
            //My super-creative text...
            pane.setText("These are words...\nHere come more words!\nWord word word.");
            
            pane.addMouseListener(new MouseAdapter() {
                private boolean pendingPopUp = false; //Indicates whether we have already a popup popped up...
                
                private void pop(final MouseEvent mevt) {
                    if (SwingUtilities.isRightMouseButton(mevt)) {
                        try {
                            final StyledDocument doc = pane.getStyledDocument();

                            //Get the location of the document where the user clicked:
                            final int offset = pane.viewToModel(mevt.getPoint());
                            
                            //Find what word is at the location of the document where the user clicked:
                            final int start = Utilities.getWordStart(pane, offset),
                                      end = Utilities.getWordEnd(pane, offset);
                            
                            //Set the selection to be that word:
                            pane.setSelectionStart(start);
                            pane.setSelectionEnd(end);
                            
                            //Obtain the value of the selected word:
                            final String word = doc.getText(start, end - start);

                            //Create the contents of the popup:
                            final JPanel popupPanel = new JPanel();

                            //Create the alternative words (via JButtons):
                            final int cnt = 4;
                            final ArrayList<JButton> words = new ArrayList<>();
                            for (int i = 0; i < cnt; ++i) {
                                final JButton button = new JButton(word + (i + 1));
                                popupPanel.add(button);
                                words.add(button);
                            }
                            final JButton cancel = new JButton("Cancel");
                            popupPanel.add(cancel);

                            //Create the popup itself:
                            final Popup popup = PopupFactory.getSharedInstance().getPopup(pane, popupPanel, mevt.getXOnScreen(), mevt.getYOnScreen());

                            //Hook action listenere to the word and cancel buttons:
                            words.forEach(button -> button.addActionListener(e -> {
                                try {
                                    //Get the text of that button (it is going to be the new word):
                                    final String newWord = ((JButton) e.getSource()).getText();
                                    
                                    //Replace the old text with the new one:
                                    doc.remove(start, end - start);
                                    doc.insertString(start, newWord, null);
                                    
                                    //Prepare caret position, so the user can keep on writing:
                                    pane.setCaretPosition(start + newWord.length());
                                }
                                catch (final BadLocationException | RuntimeException x) {
                                    JOptionPane.showMessageDialog(pane, "Oups!");
                                }
                                finally {
                                    popup.hide();
                                    pendingPopUp = false;
                                }
                            }));

                            //On cancel, deselect the selected text and close the popup:
                            cancel.addActionListener(e -> {
                                popup.hide();
                                pane.setSelectionStart(offset);
                                pane.setSelectionEnd(offset);
                                pendingPopUp = false;
                            });
                            
                            pendingPopUp = true;
                            popup.show();
                        }
                        catch (final BadLocationException | RuntimeException x) {
                            JOptionPane.showMessageDialog(pane, "Oups! No word found?...");
                        }
                    }
                }
                
                private void maybePop(final MouseEvent mevt) {
                    if (mevt.isPopupTrigger()) {
                        if (pendingPopUp)
                            System.err.println("A popup is already popped. Close it to pop a new one.");
                        else
                            pop(mevt);
                    }
                }
                
                @Override
                public void mouseClicked(final MouseEvent mevt) {
                    maybePop(mevt);
                }
                
                @Override
                public void mousePressed(final MouseEvent mevt) {
                    maybePop(mevt);
                }
                
                @Override
                public void mouseReleased(final MouseEvent mevt) {
                    maybePop(mevt);
                }
            });
            
            final JFrame frame = new JFrame("Word underline.");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(new JScrollPane(pane));
            
            //Give some room to spare:
            final Dimension dim = frame.getPreferredSize();
            dim.width += 100;
            dim.height += 100;
            frame.setPreferredSize(dim);
            
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

Resources and references:资源和参考:

  1. How to Use Editor Panes and Text Panes 如何使用编辑器窗格和文本窗格
  2. clickable text from jTextPane 来自 jTextPane 的可点击文本
  3. making text underline font by using JTextPane? 使用 JTextPane 制作文本下划线字体?
  4. How to get selection from JTextPane 如何从 JTextPane 中获取选择
  5. How to clear all styling from StyledDocument? 如何清除 StyledDocument 中的所有样式?
  6. Getting 'Attempt to mutate notification' exception 获取“尝试改变通知”异常
  7. How do I set different colors for text and underline in JTextPane? 如何在 JTextPane 中为文本和下划线设置不同的 colors?
  8. Underline StyleConstant in a different colour with AttributeSet 使用 AttributeSet 在不同颜色下划线 StyleConstant
  9. Deselect selected text in JTextPane 在 JTextPane 中取消选择选定的文本

how to get the red squiggly line under misspelled words.如何在拼写错误的单词下获得红色波浪线。

You can highlight the text and use a custom Painter to draw the red squiggly line.您可以突出显示文本并使用自定义 Painter 绘制红色波浪线。

Check out the Squiggle Painter for the custom painting code.查看Squiggle Painter以获得自定义绘画代码。

Basic usage would be:基本用法是:

SquigglePainter red = new SquigglePainter( Color.RED );

try
{
    textField.getHighlighter().addHighlight( ?, ?, red );
}
catch(BadLocationException ble) {}

where the "?" “?”在哪里? would be the start/end offset of the text you want to underline.将是您要加下划线的文本的开始/结束偏移量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM