【问题标题】:How to find whole word only in JtextPane如何仅在 JtextPane 中查找整个单词
【发布时间】:2014-07-03 05:37:38
【问题描述】:

我必须只在给定文本中找出整个单词。我试过了。但是,它有时不起作用。例如,整个单词包含给定文本的开头作为子字符串,给定文本的结尾包含整个单词,我继续按搜索按钮在某些情况下显示错误“偏移超出范围”。请帮助我。提前谢谢。

这是我的代码:

    public class FindWholeWord extends javax.swing.JFrame {

    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 (Exception ex) {
            ex.printStackTrace();
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new FindWholeWord().setVisible(true);
            }
        });
    }
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JTextField searchText;
    private javax.swing.JTextPane textPane;
    private javax.swing.JButton search;

    public FindWholeWord() {
        initComponents();
    }

    public void highLight(JTextComponent component, String patteren) {
        try {
            Document doc = component.getDocument();
            String text = component.getText(0, doc.getLength());
            int pos = component.getCaretPosition();
            if (pos == doc.getLength()) {
                pos = 0;
            }
            int index = text.toUpperCase().indexOf(patteren.toUpperCase(), pos);
            int start = Utilities.getWordStart(component, index);
            int end = Utilities.getWordEnd(component, index + patteren.length());

            int patterenLn=patteren.length();
            int diff=end-start;
            if (index >= 0) {
                if((start==index)&&(end==index+patterenLn+1)){
                component.setSelectionStart(index);
                component.setSelectionEnd(index + patteren.length());
                component.getCaret().setSelectionVisible(true);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        search = new javax.swing.JButton();
        searchText = new javax.swing.JTextField();
        scrollPane = new javax.swing.JScrollPane();
        textPane = new javax.swing.JTextPane();
        searchText.setText("test");
        textPane.setText("test qweqw test asdasdas test");

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        search.setText("Search");
        search.setFocusable(false);
        search.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                searchActionPerformed(evt);
            }
        });

        scrollPane.setViewportView(textPane);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                .addGap(36, 36, 36)
                .addComponent(search, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(32, 32, 32)
                .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(114, Short.MAX_VALUE))
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(scrollPane)
                .addContainerGap()));
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                .addGap(36, 36, 36)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(search)
                .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)));

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

    private void searchActionPerformed(java.awt.event.ActionEvent evt) {
        highLight(textPane, searchText.getText());
    }
}

【问题讨论】:

  • @Jens javax.swing.text.Utilities ;)
  • 从 Oracle 官方教程中的“如何在 JTextComponents 中搜索”代码开始
  • 上个月在这里询问并回答了有关性能的注意问题
  • 请保持代码 sn-ps short 并解释实际问题,您尝试了什么以及到底出了什么问题。

标签: java string swing awt


【解决方案1】:

在搜索时索引很少有问题,首先,在您尝试使用该值之前,您不会检查indexOf 的结果是否为-1;如果匹配的单词在文档的末尾,它不会返回匹配,等等...

我没有尝试修补它,而是重写了它......

public void highLight(JTextComponent component, String patteren) {
    try {
        Document doc = component.getDocument();
        String text = component.getText(0, doc.getLength());
        int pos = component.getCaretPosition();
        boolean found = false;
        int findLength = patteren.length();
        // Rest the search position if we're at the end of the document
        if (pos + findLength > doc.getLength()) {
            pos = 0;
        }
        while (pos + findLength <= doc.getLength()) {
            // Extract the text from teh docuemnt
            String match = doc.getText(pos, findLength).toLowerCase();
            // Check to see if it matches or request
            if (match.equals(patteren)) {
                found = true;
                break;
            }
            pos++;
        }

        if (found) {
            component.setSelectionStart(pos);
            component.setSelectionEnd(pos + patteren.length());
            component.getCaret().setSelectionVisible(true);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

更新

要启用对“整个”单词的检查,只需检查前面和后面的字符是否有空格。诀窍是防止它过度运行Document...

if (match.equals(patteren)) {
    if (pos - 1 >= 0 && 
            doc.getText(pos - 1, 1).equals(" ")) {
        if (pos + findLength == doc.getLength() ||
                doc.getText(pos + findLength, 1).equals(" ")) {
            found = true;
            break;
        }
    }
}

更新为更积极的空白检查

if (match.equals(patteren)) {
    if (pos - 1 >= 0
            && Character.isWhitespace(doc.getText(pos - 1, 1).charAt(0))) {
        if (pos + findLength == doc.getLength()
                || Character.isWhitespace(doc.getText(pos + findLength, 1).charAt(0))) {
            found = true;
            break;
        }
    }
}

【讨论】:

  • 我只想搜索整个单词。例如给定的文本是“testcase something test anything test”。只突出显示两次测试。我不想在测试用例中突出显示测试。你拿这个文本并检查我的程序,然后您就可以轻松理解我的问题。谢谢您的回复。
  • 好的,看看如何修改匹配的if 语句以满足该要求
  • 我已经用以下测试“testcase dsfbr test hfgbr test hdgfrhd testcase fgd test rejhge herbgur test”尝试了这个程序。它不会突出显示所有“测试”。请检查一次。谢谢。
  • 假设您只想要整个单词匹配,它可以找到。它匹配您提供的String 中的每个" test "
  • 试试下面的“testcase dsfbr test hfgbr(here \n) test hdgfrhd testcase(here \n) fgd test rejhge herbgur test”。Cpmment显示单行。那是我换行。给定的文本是三行。请尝试并回复我。谢谢。
【解决方案2】:

为什么不使用正则表达式?

Matcher matcher = Pattern.compile("(?i)" + pattern + "\\b").matcher(text);
while (matcher.find(pos)) {
  component.setSelectionStart(matcher.start());
  component.setSelectionEnd(matcher.end());
  component.getCaret().setSelectionVisible(true);
  break;
}

【讨论】:

  • 没关系。但是,这不是检查单词空间的结尾。
【解决方案3】:

运行此代码 - 处理 -1 索引值。

    public class Trial extends javax.swing.JFrame {

    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 (Exception ex) {
            ex.printStackTrace();
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Trial().setVisible(true);
            }
        });
    }
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JTextField searchText;
    private javax.swing.JTextPane textPane;
    private javax.swing.JButton search;

    public Trial() {
        initComponents();
    }

    public void highLight(JTextComponent component, String patteren) {
        try {
            Document doc = component.getDocument();
            String text = component.getText(0, doc.getLength());
            int pos = component.getCaretPosition();
            if (pos == doc.getLength()) {
                pos = 0;
            }
            int index = text.toUpperCase().indexOf(patteren.toUpperCase(), pos);
            int start = 0;
            int end = 0;

            if(index>=0){
            start=Utilities.getWordStart(component, index);
            end=Utilities.getWordEnd(component, index + patteren.length());
            int patterenLn=patteren.length();
            int diff=end-start;
            if (index >= 0) {
                if((start==index)&&(end==index+patterenLn+1)){
                component.setSelectionStart(index);
                component.setSelectionEnd(index + patteren.length());
                component.getCaret().setSelectionVisible(true);
                }
            }
        }else{
            JOptionPane.showMessageDialog(component, "Word Not FOund");
        }

        }catch (Exception e) {
            e.printStackTrace();
        }

    }

    @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        search = new javax.swing.JButton();
        searchText = new javax.swing.JTextField();
        scrollPane = new javax.swing.JScrollPane();
        textPane = new javax.swing.JTextPane();
        searchText.setText("test");
        textPane.setText("test qweqw test asdasdas test");

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        search.setText("Search");
        search.setFocusable(false);
        search.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                searchActionPerformed(evt);
            }
        });

        scrollPane.setViewportView(textPane);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                .addGap(36, 36, 36)
                .addComponent(search, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(32, 32, 32)
                .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(114, Short.MAX_VALUE))
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(scrollPane)
                .addContainerGap()));
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                .addGap(36, 36, 36)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(search)
                .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)));

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

    private void searchActionPerformed(java.awt.event.ActionEvent evt) {
        highLight(textPane, searchText.getText());
    }
    }

【讨论】:

    猜你喜欢
    • 2018-07-23
    • 2011-04-09
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多