Substring replacement on AttributedString


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 7 of 7

Thread: Substring replacement on AttributedString

Hybrid View

  1. #1
    Join Date
    Mar 2006
    Posts
    16

    Question Substring replacement on AttributedString

    How can I replace a substring of an AttributedString with another string of characters? I have an application that allows the user to input text into a JTextPane and the text is then stored as an AttributedString. I'd like them to be able to type in something like "My name is %NAME%" and then be able to replace the characters %NAME% with a string from a database. I've been trying to use regular expressions to do this but the problem is that I need to be able to retain the character formatting. I can strip all the character attributes off and get String containing the characters of the AttributedString and then use a regx to replace the substring but then I have to put the attributes back on which is especially difficult if the length of the two substrings is different. i.e. %NAME% is 6 characters, Bob is 3. Any suggestions?

  2. #2
    Join Date
    Dec 2004
    Location
    San Bernardino County, California
    Posts
    1,468
    This is an interesting problem. The CharacterIterator/AttributedCharacterIterator methods just do not seem to offer any assistance - all about the attributes but nothing about the associated text.

    Based on what I have seen in my limited review of this, I think I would just create a new AttributedString if I had to modify the text. The Iterator methods are good enough to allow me to specifically set attributes based on the location of the name in the string.

  3. #3
    Join Date
    Mar 2006
    Posts
    16
    I can iterate over the AttributedString a character at a time to put the values into a new AttributedString but the problem is that the Iterator only processes 1 character at a time. I can't figure out how to determine if what it's processing is like %NAME% and not just a lone % (as in 30%). The other thing I was considering was using a regx (or something) to find the indexes of the characters I want to replace and splitting the string into pieces, storing them in an array, processing each relevant element in the array and then pieceing it all back together.
    Example:

    Begin with: My name is %NAME%. What's yours.
    Turn it into: [ "My name is ", "%NAME%", ". What's yours." ]
    Replace [1] with value from database
    Concatenate array values into a new AttributedString

    I'm just not good with regx's in Java (Perl - no prob so I'm not sure how I'd go about splitting up the string.

  4. #4
    Join Date
    Dec 2004
    Location
    San Bernardino County, California
    Posts
    1,468
    can't you determine the length of the "new" substring - and that is the number of loops you need to do for your substitution ... you already know the index of the start and end of the reserved area ... then delete anything from the original if the reserved area is longer than the new substring ... and just add stuff if you reach the end of the reserved area and still have new substring left unadded ...

    all substitution in a string works this way - the String class actually uses a Stringbuilder object since string objects are immutable - just most of the time it is going on under the covers ... here's your peek underneath ...
    Last edited by nspils; 04-13-2006 at 02:31 PM.

  5. #5
    Join Date
    Mar 2006
    Posts
    16
    Here's what I've got:
    (This is just my testing code, so there's no database or anything.)

    Code:
    Font newFont = new Font("Arial", Font.PLAIN, 12);
    	Hashtable map = new Hashtable();
    	map.put(TextAttribute.FONT, newFont);
    	AttributedString startString = new AttributedString("My name is %NAME%. Is your name %NAME% too?", map);
    		
    	String strippedText = "";
    	AttributedCharacterIterator iter = startString.getIterator();
    	while (iter.getIndex() < iter.getEndIndex()) {
    		strippedText = strippedText + iter.current();
    		iter.next();
    	}
    		
    	StringBuffer buffer = new StringBuffer(strippedText);
    	
    	Pattern myPattern = Pattern.compile("%.+%");
    	Matcher myMatcher = myPattern.matcher(buffer);
    		
    	ArrayList indexes = new ArrayList();
    	int counter = 0;
    		
    	while (myMatcher.find()) {
    		System.out.println("Found a match");
    		int[] a = { counter, myMatcher.start() };
    		int[] b = { myMatcher.start(), myMatcher.end() };
    		indexes.add(a);
    		indexes.add(b);
    		counter = myMatcher.end();
    	}
    		
    	int[] c = { counter, buffer.length() };
    	indexes.add(c);
    		
    	ArrayList pieces = new ArrayList();
    		
    	for (int i=0; i<indexes.size(); i++) {
    		int[] x = (int[])indexes.get(i);
    		if (i%2 == 0) { // Even
    			pieces.add(new AttributedString(iter, x[0], x[1]));
    		}
    		else { // Odd
    			iter.setIndex(x[0]);
    			Hashtable att = new Hashtable();
    			att.putAll(iter.getAttributes());
    			pieces.add(new AttributedString("Goofy", att));
    		}
    	}
    		
    	for (int i=0; i<pieces.size(); i++) {
    		AttributedString next = (AttributedString)pieces.get(i);
    		AttributedCharacterIterator iter2 = next.getIterator();
    		while(iter2.getIndex() < iter2.getEndIndex()) {
    			System.out.print(iter2.current());
    			iter2.next();
    		}
    		System.out.print("\n");
    	}
    The problem I'm having is that myMatcher.find() is only finding the first match.
    Try running this and see what you get...
    (Thanks for the responses, btw.)

  6. #6
    Join Date
    Mar 2006
    Posts
    16
    oh duh. %.+?% instead of %.+%
    Now, how do I concatenate the array of AttributedStrings I have?
    Last edited by doubleoseven; 04-13-2006 at 03:02 PM.

  7. #7
    Join Date
    Mar 2006
    Posts
    16
    Well, I figured it out. Here's my solution if anyone is interested.
    Comments?

    Code:
    String strippedText = "";
    	AttributedCharacterIterator iter = string.getIterator();
    	while (iter.getIndex() < iter.getEndIndex()) {
    		strippedText = strippedText + iter.current();
    		iter.next();
    	}
    	
    	StringBuffer buffer = new StringBuffer(strippedText);
    	
    	Pattern myPattern = Pattern.compile("%.+?%");
    	Matcher myMatcher = myPattern.matcher(buffer);
    	
    	ArrayList indexes = new ArrayList();
    	int counter = 0;
    	
    	while (myMatcher.find()) {
    		int[] a = { counter, myMatcher.start() };
    		int[] b = { myMatcher.start(), myMatcher.end() };
    		indexes.add(a);
    		indexes.add(b);
    		counter = myMatcher.end();
    	}
    	
    	int[] c = { counter, buffer.length() };
    	indexes.add(c);
    	
    	ArrayList pieces = new ArrayList();
    	
    	for (int i=0; i<indexes.size(); i++) {
    		int[] x = (int[])indexes.get(i);
    		if (i%2 == 0) { // Even
    			pieces.add(new AttributedString(iter, x[0], x1]));
    		}
    		else { // Odd
    			iter.setIndex(x[0]);
    			Hashtable att = new Hashtable();
    			att.putAll(iter.getAttributes());
    			
    			String databaseValue = "";
    			
    			String matchString = "";
    			while (iter.getIndex() < x[1]) {
    				matchString = matchString + iter.current();
    				iter.next();
    			}
    			
    // This is where I get the value from the database.  It happens to be stored in a DefaultTableModel in my program.
    			String colName = matchString.substring(1,matchString.length()-1);
    			for (int i2=0; i2<data.getColumnCount(); i2++) {
    				if (data.getColumnName(i2).equals(colName)) {
    					databaseValue = (String)data.getValueAt(Designer.curRecord-1, i2);
    				}
    			}
    				
    			pieces.add(new AttributedString(databaseValue, att));
    		}
    	}
    		
    	String newString = "";
    		
    	for (int i=0; i<pieces.size(); i++) {
    		AttributedString next = (AttributedString)pieces.get(i);
    		AttributedCharacterIterator iter2 = next.getIterator();
    		while(iter2.getIndex() < iter2.getEndIndex()) {
    			newString = newString + iter2.current();
    			iter2.next();
    		}
    	}
    		
    	AttributedString parsedString = new AttributedString(newString);
    	int counter2 = 0;
    		
    	for (int i=0; i<pieces.size(); i++) {
    		AttributedString next = (AttributedString)pieces.get(i);
    		AttributedCharacterIterator iter2 = next.getIterator();
    		while(iter2.getIndex() < iter2.getEndIndex()) {
    			parsedString.addAttributes(iter2.getAttributes(), counter2, counter2+1);
    			iter2.next();
    			counter2++;
    		}
    	}
    		
    	return parsedString;

Similar Threads

  1. Replies: 13
    Last Post: 10-03-2007, 08:47 AM
  2. substring until character found..
    By malleat in forum Java
    Replies: 2
    Last Post: 01-15-2006, 11:54 AM
  3. jEditorPane replacement
    By Alan Shiers in forum Java
    Replies: 0
    Last Post: 05-14-2001, 10:57 PM
  4. Replies: 3
    Last Post: 04-05-2001, 01:33 PM
  5. Replies: 0
    Last Post: 11-22-2000, 04:42 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center