tdタグなどで半角文字が自動改行されない

いろいろ調べましたが、手っ取り早い解決策が見つかりませんでした。

IE限定でいいのなら

word-break:break-all;

normal:半角英数字のみ単語の切れ目で改行する
break-all:半角英数字、日本語共に単語の途中でも改行する
keep-all:半角英数字、日本語共に単語の切れ目で改行する

で、おーけー。


でも、firefoxにも対応したいから、カスタムタグで指定文字数で<br/>入れるの作った。

package jp.co.suusuke.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

import jp.co.suusuke.view.Bean;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.struts.taglib.TagUtils;

public class StringFormatTag extends TagSupport {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5198305638660948569L;
	private static final int MAX_NUM = 40;
	private static final int MULTIBYTE_MAX_NUM = 30;
	private String name;
	private boolean multibyte = false;

	public StringFormatTag() {
		super();
	}

	public int doStartTag() throws JspException {
		try {

			// HttpServletRequest request = (HttpServletRequest) pageContext
			// .getRequest();
			// String value = (String) request.getAttribute(name);

			Bean bean = (Bean) TagUtils
					.getInstance().lookup(pageContext, "bean",
							"session");

			String value = BeanUtils.getProperty(bean, name);

			if (value == null || "".equals(value)) {
				return SKIP_BODY;
			}
			String separator = System.getProperty("line.separator");

			String[] values = value.split(separator);

			int maxnum = multibyte ? MULTIBYTE_MAX_NUM : MAX_NUM;

			String br = "";
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < values.length; i++) {
				sb.append(br);
				sb.append(addNewLine(values[i], maxnum));
				br = "<br/>";
			}

			pageContext.getOut().write(sb.toString());

		} catch (IOException e) {
			throw new JspException("StringFormatTag#doStartTag", e);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return SKIP_BODY;
	}

	public int doEndTag() throws JspException {
		try {
			pageContext.getOut().write("");
		} catch (IOException e) {
			throw new JspException("StringFormatTag#doEndTag", e);
		}
		return EVAL_PAGE;
	}

	private String addNewLine(String src, int maxnum) {

		int length = src.length();
		int c = length / maxnum;

		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < c; i++) {
			sb.append(src.substring((1 * i) * maxnum, maxnum * (i + 1)));
			sb.append("<br/>");
		}
		sb.append(src.substring(c * maxnum));

		return sb.toString();
	}

	/**
	 * 属性nameのsetter
	 * 
	 * @param name
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 属性multibyteのsetter
	 * 
	 * @param multibyte
	 */
	public void setMultibyte(boolean multibyte) {
		this.multibyte = multibyte;
	}

}

入力⇒プレビューで使いたくて、入力にはテキストエリアがあるから、明示的に改行されたものは<br/>に変換する。それ以外は、使用する項目が2byte文字が多そうならmultibyte="true"にして、30文字で<br/>半角文字が多い場合は40文字で<br/>を入れるようにした。

javaだと、'A'でも'A'でもunicodeだから全部2byteで文字を保持してる。だから、substringはbyteで指定しても結局同じなんだよね。文字を分解して、shift_JISとかでbyte変換して1byteだったら、2byteだったらとしようともしたんだけど、逆にパフォーマンス悪くなりそうで、やめました。

firefoxでも「word-break:break-all」が使えたら良いんだけどな。