Java Highlighter继续亮相

时间:2015-03-06 19:43:40

标签: java documentlistener

我有以下代码用于突出显示,并且无法弄清楚为什么它会继续突出超出指定的范围。

        class DocListener implements DocumentListener {

        Color Valid_COLOR = Color.GREEN;
        Color Error_COLOR = Color.PINK;
        HostCollectionTextField field;
        Pattern p;
        Matcher m;
        private String valid = "(\\d{1,3}(?:\\.\\d{1,3}){2}\\.(\\d{1,3}))(?:(?:-|\\s+to\\s+)(\\d{1,3}(?![\\d\\.]))|(?:-|\\s*to\\s+)(\\d{1,3}(?:\\.\\d{1,3}){3})|\\s+(25\\d(?:\\.\\d{1,3}){3})|\\s*\\/(\\d{1,3}))?";

        public DocListener(Component field) {
            this.field = (HostCollectionTextField) field;
            p = Pattern.compile(valid);

        }

        @Override
        public void insertUpdate(DocumentEvent e) {
         //   System.out.println("insert:" + field.getText());
            m = p.matcher(this.field.getText());
            while (m.find()) {
                try {
                    String b = m.group();
                    System.out.println(b);
                    int index = field.getText().indexOf(b);
                    System.out.println("index=" + index);
                    int end = index + b.length();
                    System.out.println("end=" + end);
                    Highlighter.HighlightPainter painter = new DefaultHighlighter.DefaultHighlightPainter(Valid_COLOR);

                    this.field.getHighlighter().addHighlight(index, end, painter);

                    System.out.println(">> " + b.substring(2, b.length() - 2));
                } catch (BadLocationException ex) {
                    System.out.println(ex);
                }
            }
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            System.out.println("removing text");
        }

        @Override
        public void changedUpdate(DocumentEvent e) {

            System.out.println("Change:" + field.getText());
        }
    }

}

enter image description here

您可以在下面的图片中看到问题。

只应突出显示有效匹配,但荧光笔永远不会停止突出显示。

这是我的SSCCE

public class SSCCE extends javax.swing.JFrame {

/**
 * Creates new form SSCCE
 */
public SSCCE() {
    initComponents();
    this.textField.getDocument().addDocumentListener(new DocListener(this.textField));
}

class DocListener implements DocumentListener {

    Color Valid_COLOR = Color.GREEN;
    Color Error_COLOR = Color.PINK;
    JTextField field;
    Pattern p;
    Matcher m;
    Highlighter.HighlightPainter painter;
    private String valid = "(\\d{1,3}(?:\\.\\d{1,3}){2}\\.(\\d{1,3}))(?:(?:-|\\s+to\\s+)(\\d{1,3}(?![\\d\\.]))|(?:-|\\s*to\\s+)(\\d{1,3}(?:\\.\\d{1,3}){3})|\\s+(25\\d(?:\\.\\d{1,3}){3})|\\s*\\/(\\d{1,3}))?";

    public DocListener(Component field) {
        this.field = (JTextField) field;
        p = Pattern.compile(valid);

    }

    @Override
    public void insertUpdate(DocumentEvent e) {
        System.out.println("insert:" + field.getText());
        m = p.matcher(this.field.getText());
        ArrayList<String> matches = new ArrayList();
        while (m.find()) {
            try {
                String b = m.group();
                matches.add(b);
                int index = m.start();
                int end = m.end();
                System.out.println("start:" + index + " end:" + end);                   
                painter = new DefaultHighlighter.DefaultHighlightPainter(Valid_COLOR);
                this.field.getHighlighter().addHighlight(index, end, painter);

            } catch (BadLocationException ex) {
                System.out.println(ex);
            }
        }

    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        System.out.println("removing text");
    }

    @Override
    public void changedUpdate(DocumentEvent e) {

        System.out.println("Change:" + field.getText());
    }
}


/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    textField = new javax.swing.JTextField();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    textField.setText("jTextField1");

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addComponent(textField, javax.swing.GroupLayout.PREFERRED_SIZE, 408, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(0, 0, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(110, 110, 110)
            .addComponent(textField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(170, Short.MAX_VALUE))
    );

    pack();
}// </editor-fold>                        

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(SSCCE.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(SSCCE.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(SSCCE.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(SSCCE.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new SSCCE().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JTextField textField;
// End of variables declaration                   

}

1 个答案:

答案 0 :(得分:0)

我刚刚使用Matcher中的值来设置荧光笔的开始/结束值:

int start = matcher.start(i);
int end = matcher.end(i);
inputArea.getHighlighter().addHighlight( start, end, DefaultHighlighter.DefaultPainter );

以下是演示此功能的完整代码:

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;

import java.awt.*;
import java.awt.event.*;

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class RegexKing implements ActionListener, DocumentListener
{

    public static void main(String[] args)
    {
        new RegexKing();
    }

    public RegexKing()
    {
        initGUI();
        setupGUI();
        displayFrame();

    }

    public void initGUI()
    {
        // init
        frame = new JFrame("Regex King");
        container = new JPanel();

        inputArea = new JTextArea();
        regexField =new JTextField();
        outputArea = new JTextArea();

        quickMatch = new JCheckBox("Attempt Match on Change");
        matchButton = new JButton("Match");

        inputScroll = new JScrollPane(inputArea);
        outputScroll = new JScrollPane(outputArea);

        // setup
        outputArea.setEditable(false);
        matchButton.addActionListener(this);
        regexField.getDocument().addDocumentListener(this);

        // key binding
        KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Event.SHIFT_MASK, false);
        Action keyact = new AbstractAction()
        {
            public void actionPerformed(ActionEvent e)
            {
                doMatch();
            }
        };

        container.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(key, "DO_MATCH");
        container.getActionMap().put("DO_MATCH", keyact);

    }

    public void setupGUI()
    {
        gbl = new GridBagLayout();
        gbc = new GridBagConstraints();

        container.setLayout(gbl);

        setInsets(2, 2, 2, 2);
        gbcf = GridBagConstraints.BOTH;

        setComp(inputScroll, 10, 10, 20, 1, 1, 1);
        setComp(quickMatch, 10, 20, 1, 1, 1, .1);
        setComp(matchButton, 20, 20, 1, 1, 1, .1);
        setComp(regexField, 10, 30, 20, 1, 1, .1);
        setComp(outputScroll, 10, 40, 20, 1, 1, 1);
    }

    public void setComp(JComponent comp, int gx, int gy, int gw, int gh, double wx, double wy)
    {
        gbc.gridx = gx;
        gbc.gridy = gy;
        gbc.gridwidth = gw;
        gbc.gridheight = gh;
        gbc.weightx = wx;
        gbc.weighty = wy;

        gbc.fill = gbcf;

        gbl.setConstraints(comp, gbc);
        container.add(comp);
    }

    public void setInsets(int top, int bottom, int left, int right)
    {
        gbc.insets.top = top;
        gbc.insets.bottom = bottom;
        gbc.insets.left = left;
        gbc.insets.right = right;
    }

    public void displayFrame()
    {
        frame.setContentPane(container);
        frame.setSize(500, 500);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public void insertUpdate(DocumentEvent e)
    {
        if(quickMatch.isSelected() == true)
        {
            doMatch();
        }
    }

    public void removeUpdate(DocumentEvent e)
    {
        if(quickMatch.isSelected() == true)
        {
            doMatch();
        }
    }

    public void changedUpdate(DocumentEvent e)  {}


    public void actionPerformed(ActionEvent evt)
    {
        if(evt.getSource() == matchButton)
        {
            doMatch();
        }
    }

    public void doMatch()
    {
        outputArea.setText("\nAttempting Match...");
        inputArea.getHighlighter().removeAllHighlights();

        try
        {

            String inputText = inputArea.getText();
            Pattern pattern = Pattern.compile(regexField.getText());
            Matcher matcher = pattern.matcher(inputText);

            int matchCount = 0;

            while(matcher.find())
            {

                matchCount++;
                outputArea.append("\n\nMatch #" + matchCount);

                for (int i = 0; i < matcher.groupCount() + 1; i++)
                {
                    outputArea.append("\nGroup #" + i + ": " + matcher.group(i));
                    outputArea.append(" , " + matcher.end(i));
                    int start = matcher.start(i);
                    int end = matcher.end(i);
                    inputArea.getHighlighter().addHighlight( start, end, DefaultHighlighter.DefaultPainter );

                    if (matchCount == 1) inputArea.setCaretPosition(start);
                }

            }

        }
        catch(Exception exc)
        {
            outputArea.append("\nEXCEPTION THROWN");
        }

        outputArea.append("\n\nFinished.\n");

    }

    GridBagLayout gbl;
    GridBagConstraints gbc;
    int gbcf;

    JFrame frame;
    JPanel container;

    JTextArea inputArea;
    JTextField regexField;
    JTextArea outputArea;

    JScrollPane inputScroll;
    JScrollPane outputScroll;

    JCheckBox quickMatch;
    JButton matchButton;

}

在顶部文本区域输入一些文字。在文本字段中输入搜索字符串。如果选中该复选框,则在更改搜索字符串时将完成匹配。如果未选中该复选框,则需要单击“匹配”按钮。某些调试信息将出现在第二个文本区域中。

不要忘记实现removeUpdate(...)方法,因为从文档中删除字符可以更改突出显示。