Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #28876

Re: Regex?

From Knute Johnson <eternal@knutejohnson.com>
Newsgroups comp.lang.java.programmer
Subject Re: Regex?
Date 2014-06-30 09:52 -0700
Organization A noiseless patient Spider
Message-ID <los4ji$tqb$1@dont-email.me> (permalink)
References (3 earlier) <lo1im5$3ak$1@dont-email.me> <lo1j4g$6l6$1@dont-email.me> <lo2dji$k7u$1@dont-email.me> <3rplq9hoa7vg9b7oq6iqh4e5iesatvg1f5@4ax.com> <lofrui$n84$1@dont-email.me>

Show all headers | View raw


On 6/25/2014 18:10, Knute Johnson wrote:
>
> So instead of that approach I decided to use Matcher.find() to search
> through the string and keep a list of the matches.
>
> I'll post some code once I've got it cleaned up and debugged.
>

The point behind my regex questions were that I was trying to duplicate 
the text search feature found on FireFox.  On FireFox if you type CTRL-F 
you get a text box and some controls on the bottom of the FireFox window 
that you can type into and search the text on the displayed web page. 
For my purposes I don't need the up and down arrows and the Match Case 
features.  I just wanted to find the text and be able to use the ENTER 
and SHIFT-ENTER keys to move about and the ESC key to close the search 
window.

The interesting thing that I found by accident on a web search is that a 
JTextComponent that is not in focus will not display selected text.  I 
still need to come up with a simple reversible way to swap out the Caret 
on the target JTextComponent when my SearchField is displayed.

Code is posted below and if you want to play with it, you can find the 
source and a compiled jar at: http://knutejohnson.com/searchfield.

Thank you everybody that responded to my query.

package com.knutejohnson.components;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;

import com.knutejohnson.classes.*;

public class TestSearchField extends JFrame {
     private final JTextArea textArea = new JTextArea(10,40);
     private final SearchField searchField = new SearchField(10,textArea);
     private final JScrollPane scrollPane =
      new JScrollPane(textArea,
      JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
      JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

     private boolean flag;

     public TestSearchField() {
         try {
             URL url = new URL("http://knutejohnson.com/gba");
             BufferedReader br = new BufferedReader(new InputStreamReader(
              url.openStream()));
             String str;
             while ((str = br.readLine()) != null) {
                 textArea.append(str);
                 textArea.append("\n");
             }
             textArea.setCaretPosition(0);
             br.close();
         } catch (IOException ex) {
             ex.printStackTrace();
         }

         addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent we) {
                 TestSearchField.this.dispose();
             }
         });

         add(scrollPane,BorderLayout.CENTER);

         textArea.addKeyListener(new KeyAdapter() {
             public void keyPressed(KeyEvent ke) {
                 if (ke.isControlDown() && ke.getKeyCode() == 
KeyEvent.VK_F) {
                     if (!flag) {
                         flag = true;
                         TestSearchField.this.add(
                          searchField,BorderLayout.SOUTH);
                         TestSearchField.this.pack();
                     }
                     searchField.requestFocus();
                 }
             }
         });
         textArea.setLineWrap(true);
         textArea.setWrapStyleWord(true);

         searchField.addCloseListener(new CloseListener() {
             public void close(CloseEvent ce) {
                 remove(searchField);
                 pack();
                 flag = false;
             }
         });

         pack();
         setVisible(true);
     }

     public static void main(String[] args) {
         EventQueue.invokeLater(new Runnable() {
             public void run() {
                 new TestSearchField();
             }
         });
     }
}

package com.knutejohnson.components;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.regex.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;

import com.knutejohnson.classes.*;

/**
  * Entering text into the SearchField causes a scan of the JTextComponent
  * parameter.  Matching text will be highlighted and the background color
  * of the SearchField will be used to indicate successful/unsuccesful 
searches
  *
  * @author  Knute Johnson
  */

public class SearchField extends JTextField implements DocumentListener,
  KeyListener {
     /** background color to indicate a successful search */
     private static final Color LIGHT_GREEN = new Color(220,255,220);
     /** background color to indicate an unsuccessful search */
     private static final Color LIGHT_RED = new Color(255,220,220);

     /** the JTextComponent to be searched */
     private final JTextComponent comp;
     /** a list of begin and end locations of matching text */
     private final java.util.List<Point> finds = new ArrayList<>();

     /** the index of the currently highlighted find */
     private int index;

     /**
      * Constructs a SearchField with the specified length and 
JTextComponent
      * to search.
      *
      * @param columns   the number of columns to use to calculate the
      *                  preferred width
      * @param comp      the {@code JTextComponent} to search
      */
     public SearchField(int columns, JTextComponent comp) {
         super(columns);

         this.comp = comp;

         getDocument().addDocumentListener(this);
         addKeyListener(this);

         // give the JTextComponent to be searched a new Caret that has a
         // visible selection even when out of focus
         comp.setCaret(new DefaultCaret() {
             @Override public void setSelectionVisible(boolean visible) {
                 super.setSelectionVisible(true);
             }
         });
     }

     /**
      * Method of the KeyListener interface that is used to detect ENTER,
      * SHIFT+ENTER and the ESC key presses
      *
      * @param ke    the KeyEvent passed by in by the event producer
      */
     @Override public void keyPressed(KeyEvent ke) {
         // if ENTER has been pressed
         if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
             // if there are finds
             if (finds.size() > 0) {
                 if (ke.isShiftDown()) {
                     if (--index < 0)
                         index = finds.size() - 1;
                 } else
                     if (++index >= finds.size())
                         index = 0;

                 // highlight the matching text
                 comp.setCaretPosition(finds.get(index).x);
                 comp.moveCaretPosition(finds.get(index).y);
             }
         }
         // if ESC has been pressed
         if (ke.getKeyCode() == KeyEvent.VK_ESCAPE)
             // send a CloseEvent to all registered CloseListeners
             fireCloseEvent();
     }

     /**
      * Unused method of the KeyListener interface
      */
     @Override public void keyReleased(KeyEvent ke) {
     }

     /**
      * Unused method of the KeyListener interface
      */
     @Override public void keyTyped(KeyEvent ke) {
     }

     /**
      * Calls the search() method when an attribute changed
      */
     @Override public void changedUpdate(DocumentEvent de) {
         search();
     }

     /**
      * Calls the search() method when there was an insert into the document
      */
     @Override public void insertUpdate(DocumentEvent de) {
         search();
     }

     /**
      * Calls the search() method when part of the document was removed
      */
     @Override public void removeUpdate(DocumentEvent de) {
         search();
     }

     /**
      * Method to perform the actual search of the {@code TextComponent}
      */
     private void search() {
         try {
             Document doc = getDocument();
             // if the SearchField document has no text
             //  clear the finds,
             //  set the search index to 0,
             //  color the SearchField white,
             //  remove any highlighted text,
             //  and return
             if (doc.getLength() == 0) {
                 finds.clear();
                 index = 0;
                 setBackground(Color.WHITE);
                 comp.setCaretPosition(comp.getCaretPosition());
                 return;
             }

             // get the search string
             String str = doc.getText(0,doc.getLength());
             // create the Pattern and Matcher
             Pattern p = Pattern.compile(Pattern.quote(str),
              Pattern.CASE_INSENSITIVE);
             Matcher m = p.matcher(comp.getText());
             // clear the finds
             finds.clear();
             // look for and save all found locations of the search string
             while (m.find())
                 finds.add(new Point(m.start(),m.end()));

             // if matches were found
             if (finds.size() > 0) {
                 // set the SearchField background to green and
                 //  mark the first find
                 setBackground(LIGHT_GREEN);
                 comp.setCaretPosition(finds.get(0).x);
                 comp.moveCaretPosition(finds.get(0).y);
                 index = 0;
             // otherwise
             } else {
                 // set the SearchField background to red
                 setBackground(LIGHT_RED);
                 comp.setCaretPosition(comp.getCaretPosition());
             }
         } catch (BadLocationException ble) {
             ble.printStackTrace();
         }
     }

     /** list of CloseListeners */
     private final java.util.List<CloseListener> closeListeners =
      new ArrayList<>();

     /**
      * Adds a CloseListener to the list
      *
      * @param cl    CloseListener to add
      */
     public void addCloseListener(CloseListener cl) {
         closeListeners.add(cl);
     }

     /**
      * Removes a CloseListener from the list
      *
      * @param cl    CloseListener to remove
      */
     public void removeCloseListener(CloseListener cl) {
         closeListeners.remove(cl);
     }

     /**
      * Sends a CloseEvent to all CloseListeners in the list
      */
     protected void fireCloseEvent() {
         CloseEvent ce = new CloseEvent(this);

         for (CloseListener listener : closeListeners)
             listener.close(ce);
     }
}

package com.knutejohnson.classes;

import java.awt.*;
import java.util.*;

/**
  * The {@code CloseEvent} class is an event type to deliver a close message
  *
  * @author  Knute Johnson
  *
  * @see     CloseListener
  */

public class CloseEvent extends EventObject {
     /**
      * Constructs a new {@code CloseEvent}
      *
      * @param source    The Object generating the event
      */
     public CloseEvent(Object source) {
         super(source);
     }
}

package com.knutejohnson.classes;

/**
  * The {@code CloseListener} interface is implemented by classes wishing to
  * listen for a {@code CloseEvent}
  *
  * @author  Knute Johnson
  */

public interface CloseListener {
     /**
      * Override this method to receive {@code CloseEvent}s
      *
      * @param ce    The CloseEvent
      */
     public void close(CloseEvent ce);
}


-- 

Knute Johnson

Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Regex? Knute Johnson <eternal@knutejohnson.com> - 2014-06-19 21:39 -0700
  Re: Regex? Knute Johnson <eternal@knutejohnson.com> - 2014-06-19 22:03 -0700
    Re: Regex? Robert Klemme <shortcutter@googlemail.com> - 2014-06-20 09:25 +0200
      Re: Regex? Knute Johnson <eternal@knutejohnson.com> - 2014-06-20 08:06 -0700
        Re: Regex? Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-06-20 11:14 -0400
          Re: Regex? Knute Johnson <eternal@knutejohnson.com> - 2014-06-20 15:46 -0700
            Re: Regex? Roedy Green <see_website@mindprod.com.invalid> - 2014-06-25 08:15 -0700
              Re: Regex? Knute Johnson <eternal@knutejohnson.com> - 2014-06-25 18:10 -0700
                Re: Regex? Knute Johnson <eternal@knutejohnson.com> - 2014-06-30 09:52 -0700
    Re: Regex? Roedy Green <see_website@mindprod.com.invalid> - 2014-06-21 09:49 -0700
  Re: Regex? Roedy Green <see_website@mindprod.com.invalid> - 2014-08-01 02:45 -0700

csiph-web