PadFormat.java 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package gnu.kawa.format;
  2. import java.text.*;
  3. import java.text.FieldPosition;
  4. import java.io.Writer;
  5. import gnu.kawa.io.CharArrayOutPort;
  6. /** Given a Format, pad the formatted result to a specified width. */
  7. public class PadFormat extends ReportFormat
  8. {
  9. /** Minimum width. */
  10. int minWidth;
  11. char padChar;
  12. /** What percentage of padding appears after the data.
  13. * -1 means internal padding (after initial '-' or '+' or '0x' or '0X'). */
  14. int where;
  15. Format fmt;
  16. public PadFormat(Format fmt, int minWidth, char padChar, int where)
  17. {
  18. this.fmt = fmt;
  19. this.minWidth = minWidth;
  20. this.padChar = padChar;
  21. this.where = where;
  22. }
  23. public PadFormat(Format fmt, int minWidth)
  24. {
  25. this(fmt, minWidth, ' ', 100);
  26. }
  27. public int format(Object[] args, int start, Appendable dst, FieldPosition fpos)
  28. throws java.io.IOException
  29. {
  30. return format(fmt, args, start, dst, padChar, minWidth, 1, 0, where, fpos);
  31. }
  32. public static int padNeeded(int actualWidth,
  33. int minWidth, int colInc, int minPad)
  34. {
  35. int total = actualWidth + minPad;
  36. if (colInc <= 1)
  37. colInc = minWidth - total;
  38. while (total < minWidth)
  39. total += colInc;
  40. return total - actualWidth;
  41. }
  42. public static int format(Format fmt, Object[] args, int start, Appendable dst, char padChar, int minWidth, int colInc, int minPad, int where, FieldPosition fpos)
  43. throws java.io.IOException
  44. {
  45. /*
  46. if (where == 100)
  47. {
  48. int oldLength = sbuf.length();
  49. fmt.format(obj, sbuf, fpos);
  50. int newLength = sbuf.length();
  51. int pad = padNeeded(newLength - oldLength, minWidth, colInc, minPad);
  52. while (--pad >= 0)
  53. sbuf.append(padChar);
  54. return start + ?;
  55. }
  56. */
  57. String text;
  58. if (fmt instanceof ReportFormat) {
  59. CharArrayOutPort sport = new CharArrayOutPort();
  60. start = ((ReportFormat)fmt).format(args, start, sport, fpos);
  61. text = sport.toString();
  62. } else {
  63. StringBuffer tbuf = new StringBuffer(200);
  64. if (fmt instanceof MessageFormat) {
  65. // FIXME - only correct if start == 0.
  66. fmt.format(args, tbuf, fpos);
  67. start = args.length;
  68. } else {
  69. fmt.format(args[start], tbuf, fpos);
  70. start++;
  71. }
  72. text = tbuf.toString();
  73. }
  74. int len = text.length();
  75. int pad = padNeeded(len, minWidth, colInc, minPad);
  76. int prefix = 0;
  77. if (pad > 0)
  78. {
  79. if (where == -1)
  80. {
  81. if (len > 0)
  82. {
  83. char ch = text.charAt(0);
  84. if (ch == '-' || ch == '+')
  85. {
  86. prefix++;
  87. dst.append(ch);
  88. }
  89. if (len - prefix > 2 && text.charAt(prefix) == '0')
  90. {
  91. dst.append('0');
  92. ch = text.charAt(++prefix);
  93. if (ch == 'x' || ch == 'X')
  94. {
  95. prefix++;
  96. dst.append(ch);
  97. }
  98. }
  99. if (prefix > 0)
  100. text = text.substring(prefix);
  101. }
  102. where = 0;
  103. }
  104. int padAfter = (pad * where) / 100;
  105. int padBefore = pad - padAfter;
  106. /*
  107. if (fpos != null && padBefore > 0)
  108. {
  109. // This is still broken in JDK 1.2 beta2. Check beta3. FIXME.
  110. fpos.setBeginIndex(fpos.getBeginIndex() + padBefore);
  111. fpos.setEndIndex(fpos.getEndIndex() + padBefore);
  112. }
  113. */
  114. while (--padBefore >= 0)
  115. dst.append(padChar);
  116. dst.append(text);
  117. while (--padAfter >= 0)
  118. dst.append(padChar);
  119. }
  120. else
  121. {
  122. dst.append(text);
  123. }
  124. return start;
  125. }
  126. }