com.scudata.app.common.StringUtils2 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of esproc Show documentation
Show all versions of esproc Show documentation
SPL(Structured Process Language) A programming language specially for structured data computing.
package com.scudata.app.common;
import java.awt.FontMetrics;
import java.util.ArrayList;
import com.scudata.common.ArgumentTokenizer;
import com.scudata.common.StringUtils;
/**
* Tool class for processing String. Solve some functions that are not
* implemented in StringUtils.
*/
public class StringUtils2 {
/**
* Do the display line break of the expression. Only the width is
* considered, and the input characters such as \r\n\t are not processed.
* But the carriage return and line feed are handled.
*
* @param text
* Text to wrap
* @param fm
* FontMetrics
* @param w
* Line width
* @param maxRowCount
* Maximum number of rows
* @return
*/
public static ArrayList wrapExpString(String text, FontMetrics fm,
float w, boolean wrapChar, int maxRowCount) {
ArrayList al = new ArrayList();
ArgumentTokenizer at = new ArgumentTokenizer(text, '\n', true, true,
true, true);
while (at.hasNext()) {
String line = at.next();
if (at.hasNext()) {
line += "\n";
}
int len = line.length();
String tmp = "";
for (int i = 0; i < len; i++) {
char c = line.charAt(i);
tmp += String.valueOf(c);
int wid = fm.stringWidth(tmp);
if (wid > w) {
int cut = cutLine(tmp, c, wrapChar);
al.add(tmp.substring(0, cut));
if (maxRowCount > 0 && al.size() > maxRowCount) {
return al;
}
tmp = tmp.substring(cut);
}
}
al.add(tmp);
}
return al;
}
/**
* Wrap the string
*
* @param text
* Text to wrap
* @param fm
* FontMetrics
* @param w
* Line width
* @param wrapChar
* Newline symbol
* @param maxRowCount
* Maximum number of rows
* @return
*/
public static ArrayList wrapString(String text, FontMetrics fm,
float w, boolean wrapChar, int maxRowCount) {
ArrayList al = new ArrayList();
text = replace(text, "\\n", "\n");
text = StringUtils.replace(text, "\\r", "\r");
text = StringUtils.replace(text, "\r\n", "\n");
text = StringUtils.replace(text, "\r", "\n");
/* The new construction method in Argumenttokenizer is used here. */
ArgumentTokenizer at = new ArgumentTokenizer(text, '\n', true, true,
true, true);
while (at.hasNext()) {
String line = at.next();
if (at.hasNext()) {
line += "\n";
}
int len = line.length();
String tmp = "";
for (int i = 0; i < len; i++) {
char c = line.charAt(i);
tmp += String.valueOf(c);
int wid = fm.stringWidth(tmp);
if (wid > w) {
/*
* It cannot be judged by the character width alone. Also
* need to consider the rules of line breaks such as kinsoku
* and other lines.
*/
int cut = cutLine(tmp, c, wrapChar);
al.add(tmp.substring(0, cut));
if (maxRowCount > 0 && al.size() > maxRowCount) {
return al;
}
tmp = tmp.substring(cut);
}
}
al.add(tmp);
}
return al;
}
/**
* Replace the string
*
* @param src
* Source string
* @param findString
* The string to replace
* @param replaceString
* The string to replace with
* @return
*/
private static String replace(String src, String findString,
String replaceString) {
if (src == null) {
return src;
}
int len = src.length();
if (len == 0) {
return src;
}
if (findString == null) {
return src;
}
int len1 = findString.length();
if (len1 == 0) {
return src;
}
if (replaceString == null) {
return src;
}
int start = 0;
StringBuffer sb = null;
while (true) {
int pos = src.indexOf(findString, start);
if (pos >= 0) {
if (sb == null) {
sb = new StringBuffer(len + 100);
}
for (int i = start; i < pos; i++) {
sb.append(src.charAt(i));
}
sb.append(replaceString);
start = pos + len1;
} else {
if (sb != null) {
for (int i = start; i < len; i++) {
sb.append(src.charAt(i));
}
}
break;
}
}
if (sb != null) {
return sb.toString();
}
return src;
}
/**
* Split line
*
* @param s
* @param c
* @param wrapChar
* @return
*/
private static int cutLine(String s, char c, boolean wrapChar) {
/*
* If the current wrap length len is known, it will not be calculated.
* Otherwise, calculate the number of characters in the first line of
* the current line break.
*/
int len = s.length() - 1;
if (wrapChar) {
return len;
}
/*
* If the trailing character c is known, there is no need to calculate
* it. Otherwise, the last character is calculated.
*/
if (c == 0) {
c = s.charAt(len);
}
boolean canBeHead = canBeHead(c);
boolean isEnglishChar = isEnglishChar(c);
if (!canBeHead && isEnglishChar) {
/*
* Since consecutive English characters need to be treated as a word
* to wrap together. Therefore, it is necessary to determine whether
* the line is all continuous English characters.
*/
int seek = len - 1;
int loc = 0;
boolean hasHead = canBeHead(c);
boolean letterbreak = false;
while (seek >= 0 && loc == 0) {
char seekChar = s.charAt(seek);
if (!isEnglishChar(seekChar)) {
letterbreak = true;
if (!hasHead) {
if (canBeHead(seekChar)) {
/*
* If non-avoidance characters appear in this line
* (excluding the first word). Then set the first
* word to true.
*/
hasHead = true;
}
seek--;
} else {
/*
* If non-English characters appear in this line. Then
* determine whether the character is a kinsoku
* character.
*/
if (canBeFoot(seekChar)) {
/*
* If it is a non-kinsoku character, just wrap the
* line after this character.
*/
loc = seek + 1;
} else {
if (canBeHead(seekChar)) {
hasHead = true;
} else {
hasHead = false;
}
seek--;
}
}
} else if (letterbreak) {
/*
* If an English character is found after the kinsoku
* character appears, it is good to disconnect from the
* English character.
*/
loc = seek + 1;
} else {
if (canBeHead(seekChar)) {
hasHead = true;
} else {
hasHead = false;
}
seek--;
}
}
if (loc > 0) {
/* If there are non-English characters in this line */
return loc;
} else {
/*
* If the line is all English characters or consecutive kinsoku
* characters, then it is divided normally.
*/
return len;
}
} else if (!canBeHead) {
/* If c is to avoid the first character. */
int seek = len - 1;
int loc = 0;
boolean hasHead = false;
/* Find the first non-avoidance character */
while (seek >= 0 && loc == 0) {
char seekChar = s.charAt(seek);
if (!hasHead) {
if (canBeHead(seekChar)) {
/*
* If non-avoidance characters appear in this line
* (excluding the first word), then set the first word
* to true.
*/
hasHead = true;
}
seek--;
} else {
if (isEnglishChar(seekChar)) {
/*
* For alphanumeric characters, search forward to the
* first non-consecutive alphanumeric character.
*/
int eseek = seek;
boolean eng = true;
while (eng && seek > 0) {
seek--;
eng = isEnglishChar(s.charAt(seek));
}
/*
* If there are consecutive English characters from the
* current character to the first, then the line breaks
* before the last alphanumeric character.
*/
if (seek == 0) {
loc = eseek + 1;
}
}
/*
* If there is an initial character, then judge whether to
* kinsoku.
*/
else if (canBeFoot(seekChar)) {
/*
* If there is no kinsoku, the line breaks after the
* character.
*/
loc = seek + 1;
} else {
/* Need to be kinked */
seek--;
}
}
}
if (loc > 0) {
/* If the line can be broken normally in this line */
return loc;
} else {
/*
* If all the characters in this line are slashing or
* consecutive slashing characters. Then split normally.
*/
return len;
}
}
/* Determine whether c is an English character */
else if (isEnglishChar) {
/*
* Since consecutive English characters need to be treated as a word
* to wrap together. Therefore, it is necessary to determine whether
* the line is all continuous English characters.
*/
int seek = len - 1;
int loc = 0;
boolean hasHead = canBeHead(c);
boolean letterbreak = false;
while (seek >= 0 && loc == 0) {
char seekChar = s.charAt(seek);
if (!isEnglishChar(seekChar)) {
/*
* When wrapping lines, first judge whether the current
* first character is avoiding the first
*/
letterbreak = true;
if (!hasHead) {
if (canBeHead(seekChar)) {
hasHead = true;
}
seek--;
}
/*
* If a non-English character appears in this line, then
* determine whether the character is a kinsoku character.
*/
else if (canBeFoot(seekChar)) {
/*
* If it is a non-kinsoku character, then wrap the line
* after this character.
*/
loc = seek + 1;
} else {
if (canBeHead(seekChar)) {
hasHead = true;
} else {
hasHead = false;
}
seek--;
}
} else if (letterbreak) {
/*
* If an English character is found after the kinsoku
* character appears, it will be disconnected from the
* English character.
*/
loc = seek + 1;
} else {
/* If the first character is avoided in English */
if (canBeHead(seekChar)) {
hasHead = true;
} else {
hasHead = false;
}
seek--;
}
}
if (loc > 0) {
/* If there are non-English characters in this line. */
return loc;
} else {
/*
* If the line is all English characters or consecutive kinsoku
* characters, then it is divided normally.
*/
return len;
}
}
return seekCanBeFoot(s.substring(0, len), len);
}
/**
* Break the string from the last character that can be placed at the end of
* the line. Returns the number of characters in this line after
* disconnection.
*
* @param s
* @param len
* @return
*/
private static int seekCanBeFoot(String s, int len) {
if (len == -1) {
len = s.length();
}
if (len <= 1) {
return len;
}
int seek = len - 1;
int loc = 0;
while (seek >= 0 && loc == 0) {
char seekChar = s.charAt(seek);
if (canBeFoot(seekChar)) {
loc = seek + 1;
} else {
seek--;
}
}
if (loc > 0) {
return loc;
}
return len;
}
/**
* Can a character be used as the end of a line
*
* @param c
* @return
*/
private static boolean canBeFoot(char c) {
String cannotFoot = "([{?????????????????????????ۣ??꣤";
return cannotFoot.indexOf(c) < 0;
}
/**
* Can a character be the beginning of a line
*
* @param c
* @return
*/
private static boolean canBeHead(char c) {
String cannotHead = "%??!),.:;?]}?????????D?????????á????????????????????????????????????????ݣ????????";
return cannotHead.indexOf(c) < 0;
}
/**
* Whether English character
*
* @param c
* @return
*/
private static boolean isEnglishChar(char c) {
return (c <= '~' && c > ' ');
}
/**
* Get the height of the text
*
* @param fm
* @return
*/
public static int getTextRowHeight(FontMetrics fm) {
int tmpH = (int) Math.ceil(fm.getFont().getSize() * 1.28);
int textH = fm.getHeight();
if (tmpH < textH) {
return textH;
}
int dh = tmpH - textH;
if (dh % 2 == 0) {
/*
* In order to ensure that the height of the text area is always
* centered on the line height. Ensure that dh is always an even
* number.
*/
return tmpH;
}
return tmpH + 1;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy