Java - 如何在结果中突出显示搜索到的单词

时间:2015-10-09 04:32:50

标签: java jframe

这是搜索它,但是我无法在结果中突出显示搜索到的单词,它应该在结果窗格中以黄色突出显示搜索到的单词

这是应该做的事情

Image Link

突出显示在结果窗格中搜索的内容

谢谢

以下是代码:/

package search.text.file;

  import java.awt.BorderLayout;
  import java.awt.EventQueue;
  import java.awt.GridBagConstraints;
  import java.awt.GridBagLayout;
  import java.awt.Insets;
  import java.awt.Color;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileReader;
  import java.io.IOException;
  import javax.swing.DefaultListModel;
  import javax.swing.JButton;
  import javax.swing.JFrame;
  import javax.swing.JLabel;
  import javax.swing.JList;
  import javax.swing.JOptionPane;
  import javax.swing.JPanel;
  import javax.swing.JScrollPane;
  import javax.swing.JTextField;
  import javax.swing.UIManager;
  import javax.swing.UnsupportedLookAndFeelException;


public class SearchTextFile {

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

public SearchTextFile() {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException |     IllegalAccessException | UnsupportedLookAndFeelException ex) {
            }

            JFrame frame = new JFrame("Bible Search");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new TestPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
}

public class TestPane extends JPanel {

    private JTextField findText;
    private JButton search;
    private DefaultListModel<String> model;

    public TestPane() {
        setLayout(new BorderLayout());
        JPanel searchPane = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(2, 2, 2, 2);
        searchPane.add(new JLabel("Find: "), gbc);
        gbc.gridx++;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1;
        findText = new JTextField(20);
        searchPane.add(findText, gbc);

        gbc.gridx++;
        gbc.fill = GridBagConstraints.NONE;
        gbc.weightx = 0;
        search = new JButton("Search");
        searchPane.add(search, gbc);

        add(searchPane, BorderLayout.NORTH);

        model = new DefaultListModel<>();
        JList list = new JList(model);
        add(new JScrollPane(list));

        ActionHandler handler = new ActionHandler();

        search.addActionListener(handler);
        findText.addActionListener(handler);
    }

    public class ActionHandler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            model.removeAllElements();
//                    BufferedReader reader = null;

            String searchText = findText.getText();
            try (BufferedReader reader = new BufferedReader(new     FileReader(new File("bible.txt")))) {

                String text = null;
                while ((text = reader.readLine()) != null) {

                    if (text.contains(searchText)) {

                        model.addElement(text);

                    }

                }

            } catch (IOException exp) {

                exp.printStackTrace();
                JOptionPane.showMessageDialog(TestPane.this, "Something Went Wrong", "Error", JOptionPane.ERROR_MESSAGE);

            }
          }
       }
}
}

3 个答案:

答案 0 :(得分:3)

首先看一下Writing a Custom Cell Renderer。这样您就可以自定义JList

中每个单元格的方式

在你的情况下,它有点困难,因为你想要突出显示单词(黄色),所以你需要做一些额外的工作来将这个单词包装在<html><font>标签中

像...一样的东西。

public class HighlightListCellRenderer extends DefaultListCellRenderer {

    @Override
    public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        if (value instanceof String && searchPhrase != null) {
            String text = (String) value;
            if (text.contains(searchPhrase)) {
                text = text.replace(" ", "&nbsp;");
                value = "<html>" + text.replace(searchPhrase, "<font color=#ffff00>" + searchPhrase + "</font>") + "</html>";
            }
        }
        return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); //To change body of generated methods, choose Tools | Templates.
    }

}

在我的示例中,HighlightListCellRendererTestPane的内部类,这使它可以访问我添加的searchPhrase字段。

Highlighted

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringJoiner;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class SearchTextFile {

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

    public SearchTextFile() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Bible Search");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JTextField findText;
        private JButton search;
        private DefaultListModel<String> model;
        private JList list;

        private String searchPhrase;

        public TestPane() {
            setLayout(new BorderLayout());
            JPanel searchPane = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(2, 2, 2, 2);
            searchPane.add(new JLabel("Find: "), gbc);
            gbc.gridx++;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 1;
            findText = new JTextField(20);
            searchPane.add(findText, gbc);

            gbc.gridx++;
            gbc.fill = GridBagConstraints.NONE;
            gbc.weightx = 0;
            search = new JButton("Search");
            searchPane.add(search, gbc);

            add(searchPane, BorderLayout.NORTH);

            model = new DefaultListModel<>();
            list = new JList(model);
            list.setCellRenderer(new HighlightListCellRenderer());
            add(new JScrollPane(list));

            ActionHandler handler = new ActionHandler();

            search.addActionListener(handler);
            findText.addActionListener(handler);

            try (BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/Script.txt")))) {

                String text = null;
                while ((text = reader.readLine()) != null) {
                    model.addElement(text);
                }

            } catch (IOException exp) {

                exp.printStackTrace();

            }
        }

        public class ActionHandler implements ActionListener {

            @Override
            public void actionPerformed(ActionEvent e) {
                searchPhrase = findText.getText();
                if (searchPhrase != null && searchPhrase.trim().length() == 0) {
                    searchPhrase = null;
                }
                list.repaint();
//              model.removeAllElements();
////                    BufferedReader reader = null;
//
//              String searchText = findText.getText();
//              try (BufferedReader reader = new BufferedReader(new FileReader(new File("bible.txt")))) {
//
//                  String text = null;
//                  while ((text = reader.readLine()) != null) {
//
//                      if (text.contains(searchText)) {
//
//                          model.addElement(text);
//
//                      }
//
//                  }
//
//              } catch (IOException exp) {
//
//                  exp.printStackTrace();
//                  JOptionPane.showMessageDialog(TestPane.this, "Something Went Wrong", "Error", JOptionPane.ERROR_MESSAGE);
//
//              }
            }
        }

        public class HighlightListCellRenderer extends DefaultListCellRenderer {

            public final String WITH_DELIMITER = "((?<=%1$s)|(?=%1$s))";

            @Override
            public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                if (value instanceof String && searchPhrase != null) {
                    String text = (String) value;
                    if (text.contains(searchPhrase)) {
                        text = text.replace(" ", "&nbsp;");
                        value = "<html>" + text.replace(searchPhrase, "<font color=#ffff00>" + searchPhrase + "</font>") + "</html>";
                    }
                }
                return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); //To change body of generated methods, choose Tools | Templates.
            }

        }
    }
}

如果你想突出显示文字的背景(黄色),你可以使用像...这样的东西。

value = "<html>" + text.replace(searchPhrase, "<span STYLE='background-color: #ffff00'>" + searchPhrase + "</span>") + "</html>";

代替

答案 1 :(得分:1)

我会考虑使用JTextPane来显示文字并进行突出显示。即文本通常显示在文本组件中。

这是一个简单的例子:

import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;

public class TextAndNewLinesTest extends JFrame
{
    public TextAndNewLinesTest()
        throws Exception
    {
        String text =
            "one two three four five\r\n" +
            "one two three four five\r\n" +
            "one two three four five\r\n" +
            "one two three four five\r\n" +
            "one two three four five\r\n";

        JTextPane textPane = new JTextPane();
        textPane.setText(text);
        JScrollPane scrollPane = new JScrollPane( textPane );
        getContentPane().add( scrollPane );

        StyledDocument doc = textPane.getStyledDocument();
        SimpleAttributeSet keyWord = new SimpleAttributeSet();
        StyleConstants.setBackground(keyWord, Color.CYAN);

        String search = "three";
        int offset = 0;

        int length = textPane.getDocument().getLength();
        text = textPane.getDocument().getText(0, length);

        while ((offset = text.indexOf(search, offset)) != -1)
        {
            doc.setCharacterAttributes(offset, search.length(), keyWord, false); 
            offset += search.length();
        }
    }

    public static void main(String[] args)
        throws Exception
    {
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new TextAndNewLinesTest();
        frame.setTitle("Text and New Lines");
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.setSize(400, 120);
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}

此外,使用JTextPane时,您只需使用read(...)方法将数据加载到文本窗格中。

在构建搜索功能时,您将在开始搜索之前使用以下内容清除属性:

doc.setCharacterAttributes(0, doc.getLength(), new SimpleAttributeSet(), true);

答案 2 :(得分:0)

我得到了它的工作:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class MySearch02 {

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

public MySearch02() {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            }

            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new TestPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
    }

    public class TestPane extends JPanel {

        private JTextField findText;
        private JTextArea ta;
        private Timer keyTimer;

        public TestPane() {
        setLayout(new BorderLayout());
        JPanel searchPane = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(2, 2, 2, 2);
        searchPane.add(new JLabel("Find: "), gbc);
        gbc.gridx++;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1;
        findText = new JTextField(20);
        searchPane.add(findText, gbc);

        add(searchPane, BorderLayout.NORTH);

        ta = new JTextArea(20, 40);
        ta.setWrapStyleWord(true);
        ta.setLineWrap(true);
        ta.setEditable(false);
        add(new JScrollPane(ta));

        loadFile();

        keyTimer = new Timer(250, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String find = findText.getText();
                Document document = ta.getDocument();
                try {
                    for (int index = 0; index + find.length() < document.getLength(); index++) {
                        String match = document.getText(index, find.length());
                        if (find.equals(match)) {
                                javax.swing.text.DefaultHighlighter.DefaultHighlightPainter highlightPainter =
                                    new     javax.swing.text.DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
                            ta.getHighlighter().addHighlight(index, index +     find.length(),
                                    highlightPainter);
                        }
                    }
                } catch (BadLocationException exp) {
                    exp.printStackTrace();
                }
            }
        });
        keyTimer.setRepeats(false);

        findText.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                keyTimer.restart();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                keyTimer.restart();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                keyTimer.restart();
            }
        });
    }

    protected void loadFile() {
        String searchText = findText.getText();
        try (BufferedReader reader = new BufferedReader(new FileReader(new File("search.txt")))) {
            ta.read(reader, "Text");
        } catch (IOException exp) {
            exp.printStackTrace();
            JOptionPane.showMessageDialog(TestPane.this, "Could not create file", "Error", JOptionPane.ERROR_MESSAGE);
        }
        ta.setCaretPosition(0);
    }
}
}