001: /*
002: * $Id: List.java 2853 2007-06-25 13:28:34Z blowagie $
003: * $Name$
004: *
005: * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
006: *
007: * The contents of this file are subject to the Mozilla Public License Version 1.1
008: * (the "License"); you may not use this file except in compliance with the License.
009: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
010: *
011: * Software distributed under the License is distributed on an "AS IS" basis,
012: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013: * for the specific language governing rights and limitations under the License.
014: *
015: * The Original Code is 'iText, a free JAVA-PDF library'.
016: *
017: * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
018: * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
019: * All Rights Reserved.
020: * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
021: * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
022: *
023: * Contributor(s): all the names of the contributors are added in the source code
024: * where applicable.
025: *
026: * Alternatively, the contents of this file may be used under the terms of the
027: * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
028: * provisions of LGPL are applicable instead of those above. If you wish to
029: * allow use of your version of this file only under the terms of the LGPL
030: * License and not to allow others to use your version of this file under
031: * the MPL, indicate your decision by deleting the provisions above and
032: * replace them with the notice and other provisions required by the LGPL.
033: * If you do not delete the provisions above, a recipient may use your version
034: * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
035: *
036: * This library is free software; you can redistribute it and/or modify it
037: * under the terms of the MPL as stated above or under the terms of the GNU
038: * Library General Public License as published by the Free Software Foundation;
039: * either version 2 of the License, or any later version.
040: *
041: * This library is distributed in the hope that it will be useful, but WITHOUT
042: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
043: * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
044: * details.
045: *
046: * If you didn't download this code from the following link, you should check if
047: * you aren't using an obsolete version:
048: * http://www.lowagie.com/iText/
049: */
050:
051: package com.lowagie.text;
052:
053: import java.util.ArrayList;
054: import java.util.Iterator;
055:
056: import com.lowagie.text.factories.RomanAlphabetFactory;
057:
058: /**
059: * A <CODE>List</CODE> contains several <CODE>ListItem</CODE>s.
060: * <P>
061: * <B>Example 1:</B>
062: * <BLOCKQUOTE><PRE>
063: * <STRONG>List list = new List(true, 20);</STRONG>
064: * <STRONG>list.add(new ListItem("First line"));</STRONG>
065: * <STRONG>list.add(new ListItem("The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?"));</STRONG>
066: * <STRONG>list.add(new ListItem("Third line"));</STRONG>
067: * </PRE></BLOCKQUOTE>
068: *
069: * The result of this code looks like this:
070: * <OL>
071: * <LI>
072: * First line
073: * </LI>
074: * <LI>
075: * The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?
076: * </LI>
077: * <LI>
078: * Third line
079: * </LI>
080: * </OL>
081: *
082: * <B>Example 2:</B>
083: * <BLOCKQUOTE><PRE>
084: * <STRONG>List overview = new List(false, 10);</STRONG>
085: * <STRONG>overview.add(new ListItem("This is an item"));</STRONG>
086: * <STRONG>overview.add("This is another item");</STRONG>
087: * </PRE></BLOCKQUOTE>
088: *
089: * The result of this code looks like this:
090: * <UL>
091: * <LI>
092: * This is an item
093: * </LI>
094: * <LI>
095: * This is another item
096: * </LI>
097: * </UL>
098: *
099: * @see Element
100: * @see ListItem
101: */
102:
103: public class List implements TextElementArray {
104:
105: // constants
106:
107: /** a possible value for the numbered parameter */
108: public static final boolean ORDERED = true;
109: /** a possible value for the numbered parameter */
110: public static final boolean UNORDERED = false;
111: /** a possible value for the lettered parameter */
112: public static final boolean NUMERICAL = false;
113: /** a possible value for the lettered parameter */
114: public static final boolean ALPHABETICAL = true;
115: /** a possible value for the lettered parameter */
116: public static final boolean UPPERCASE = false;
117: /** a possible value for the lettered parameter */
118: public static final boolean LOWERCASE = true;
119:
120: // member variables
121:
122: /** This is the <CODE>ArrayList</CODE> containing the different <CODE>ListItem</CODE>s. */
123: protected ArrayList list = new ArrayList();
124:
125: /** Indicates if the list has to be numbered. */
126: protected boolean numbered = false;
127: /** Indicates if the listsymbols are numerical or alphabetical. */
128: protected boolean lettered = false;
129: /** Indicates if the listsymbols are lowercase or uppercase. */
130: protected boolean lowercase = false;
131: /** Indicates if the indentation has to be set automatically. */
132: protected boolean autoindent = false;
133: /** Indicates if the indentation of all the items has to be aligned. */
134: protected boolean alignindent = false;
135:
136: /** This variable indicates the first number of a numbered list. */
137: protected int first = 1;
138: /** This is the listsymbol of a list that is not numbered. */
139: protected Chunk symbol = new Chunk("- ");
140:
141: /** The indentation of this list on the left side. */
142: protected float indentationLeft = 0;
143: /** The indentation of this list on the right side. */
144: protected float indentationRight = 0;
145: /** The indentation of the listitems. */
146: protected float symbolIndent = 0;
147:
148: // constructors
149:
150: /** Constructs a <CODE>List</CODE>. */
151: public List() {
152: this (false, false);
153: }
154:
155: /**
156: * Constructs a <CODE>List</CODE>.
157: * @param numbered a boolean
158: */
159: public List(boolean numbered) {
160: this (numbered, false);
161: }
162:
163: /**
164: * Constructs a <CODE>List</CODE>.
165: * @param numbered a boolean
166: * @param lettered has the list to be 'numbered' with letters
167: */
168: public List(boolean numbered, boolean lettered) {
169: this .numbered = numbered;
170: this .lettered = lettered;
171: this .autoindent = true;
172: this .alignindent = true;
173: }
174:
175: /**
176: * Constructs a <CODE>List</CODE>.
177: * <P>
178: * Remark: the parameter <VAR>symbolIndent</VAR> is important for instance when
179: * generating PDF-documents; it indicates the indentation of the listsymbol.
180: * It is not important for HTML-documents.
181: *
182: * @param numbered a boolean
183: * @param symbolIndent the indentation that has to be used for the listsymbol
184: */
185: public List(boolean numbered, float symbolIndent) {
186: this (numbered, false, symbolIndent);
187: }
188:
189: /**
190: * Creates a list
191: * @param numbered has the list to be numbered?
192: * @param lettered has the list to be 'numbered' with letters
193: * @param symbolIndent the indentation of the symbol
194: */
195: public List(boolean numbered, boolean lettered, float symbolIndent) {
196: this .numbered = numbered;
197: this .lettered = lettered;
198: this .symbolIndent = symbolIndent;
199: }
200:
201: // implementation of the Element-methods
202:
203: /**
204: * Processes the element by adding it (or the different parts) to an
205: * <CODE>ElementListener</CODE>.
206: *
207: * @param listener an <CODE>ElementListener</CODE>
208: * @return <CODE>true</CODE> if the element was processed successfully
209: */
210: public boolean process(ElementListener listener) {
211: try {
212: for (Iterator i = list.iterator(); i.hasNext();) {
213: listener.add((Element) i.next());
214: }
215: return true;
216: } catch (DocumentException de) {
217: return false;
218: }
219: }
220:
221: /**
222: * Gets the type of the text element.
223: *
224: * @return a type
225: */
226: public int type() {
227: return Element.LIST;
228: }
229:
230: /**
231: * Gets all the chunks in this element.
232: *
233: * @return an <CODE>ArrayList</CODE>
234: */
235: public ArrayList getChunks() {
236: ArrayList tmp = new ArrayList();
237: for (Iterator i = list.iterator(); i.hasNext();) {
238: tmp.addAll(((Element) i.next()).getChunks());
239: }
240: return tmp;
241: }
242:
243: // methods to set the membervariables
244:
245: /**
246: * Adds an <CODE>Object</CODE> to the <CODE>List</CODE>.
247: *
248: * @param o the object to add.
249: * @return true if adding the object succeeded
250: */
251: public boolean add(Object o) {
252: if (o instanceof ListItem) {
253: ListItem item = (ListItem) o;
254: if (numbered || lettered) {
255: Chunk chunk;
256: int index = first + list.size();
257: if (lettered)
258: chunk = new Chunk(RomanAlphabetFactory.getString(
259: index, lowercase), symbol.getFont());
260: else
261: chunk = new Chunk(String.valueOf(index), symbol
262: .getFont());
263: chunk.append(". ");
264: item.setListSymbol(chunk);
265: } else {
266: item.setListSymbol(symbol);
267: }
268: item.setIndentationLeft(symbolIndent, autoindent);
269: item.setIndentationRight(0);
270: return list.add(item);
271: } else if (o instanceof List) {
272: List nested = (List) o;
273: nested.setIndentationLeft(nested.getIndentationLeft()
274: + symbolIndent);
275: first--;
276: return list.add(nested);
277: } else if (o instanceof String) {
278: return this .add(new ListItem((String) o));
279: }
280: return false;
281: }
282:
283: // extra methods
284:
285: /** Makes sure all the items in the list have the same indentation. */
286: public void normalizeIndentation() {
287: float max = 0;
288: Element o;
289: for (Iterator i = list.iterator(); i.hasNext();) {
290: o = (Element) i.next();
291: if (o instanceof ListItem) {
292: max = Math
293: .max(max, ((ListItem) o).getIndentationLeft());
294: }
295: }
296: for (Iterator i = list.iterator(); i.hasNext();) {
297: o = (Element) i.next();
298: if (o instanceof ListItem) {
299: ((ListItem) o).setIndentationLeft(max);
300: }
301: }
302: }
303:
304: // setters
305:
306: /**
307: * @param numbered the numbered to set
308: */
309: public void setNumbered(boolean numbered) {
310: this .numbered = numbered;
311: }
312:
313: /**
314: * @param lettered the lettered to set
315: */
316: public void setLettered(boolean lettered) {
317: this .lettered = lettered;
318: }
319:
320: /**
321: * @param uppercase the uppercase to set
322: */
323: public void setLowercase(boolean uppercase) {
324: this .lowercase = uppercase;
325: }
326:
327: /**
328: * @param autoindent the autoindent to set
329: */
330: public void setAutoindent(boolean autoindent) {
331: this .autoindent = autoindent;
332: }
333:
334: /**
335: * @param alignindent the alignindent to set
336: */
337: public void setAlignindent(boolean alignindent) {
338: this .alignindent = alignindent;
339: }
340:
341: /**
342: * Sets the number that has to come first in the list.
343: *
344: * @param first a number
345: */
346: public void setFirst(int first) {
347: this .first = first;
348: }
349:
350: /**
351: * Sets the listsymbol.
352: *
353: * @param symbol a <CODE>Chunk</CODE>
354: */
355: public void setListSymbol(Chunk symbol) {
356: this .symbol = symbol;
357: }
358:
359: /**
360: * Sets the listsymbol.
361: * <P>
362: * This is a shortcut for <CODE>setListSymbol(Chunk symbol)</CODE>.
363: *
364: * @param symbol a <CODE>String</CODE>
365: */
366: public void setListSymbol(String symbol) {
367: this .symbol = new Chunk(symbol);
368: }
369:
370: /**
371: * Sets the indentation of this paragraph on the left side.
372: *
373: * @param indentation the new indentation
374: */
375: public void setIndentationLeft(float indentation) {
376: this .indentationLeft = indentation;
377: }
378:
379: /**
380: * Sets the indentation of this paragraph on the right side.
381: *
382: * @param indentation the new indentation
383: */
384: public void setIndentationRight(float indentation) {
385: this .indentationRight = indentation;
386: }
387:
388: /**
389: * @param symbolIndent the symbolIndent to set
390: */
391: public void setSymbolIndent(float symbolIndent) {
392: this .symbolIndent = symbolIndent;
393: }
394:
395: // methods to retrieve information
396:
397: /**
398: * Gets all the items in the list.
399: *
400: * @return an <CODE>ArrayList</CODE> containing <CODE>ListItem</CODE>s.
401: */
402: public ArrayList getItems() {
403: return list;
404: }
405:
406: /**
407: * Gets the size of the list.
408: *
409: * @return a <CODE>size</CODE>
410: */
411: public int size() {
412: return list.size();
413: }
414:
415: /**
416: * Returns <CODE>true</CODE> if the list is empty.
417: *
418: * @return <CODE>true</CODE> if the list is empty
419: */
420: public boolean isEmpty() {
421: return list.isEmpty();
422: }
423:
424: /**
425: * Gets the leading of the first listitem.
426: *
427: * @return a <CODE>leading</CODE>
428: */
429: public float getTotalLeading() {
430: if (list.size() < 1) {
431: return -1;
432: }
433: ListItem item = (ListItem) list.get(0);
434: return item.getTotalLeading();
435: }
436:
437: // getters
438:
439: /**
440: * Checks if the list is numbered.
441: * @return <CODE>true</CODE> if the list is numbered, <CODE>false</CODE> otherwise.
442: */
443:
444: public boolean isNumbered() {
445: return numbered;
446: }
447:
448: /**
449: * Checks if the list is lettered.
450: * @return <CODE>true</CODE> if the list is lettered, <CODE>false</CODE> otherwise.
451: */
452: public boolean isLettered() {
453: return lettered;
454: }
455:
456: /**
457: * Checks if the list lettering is lowercase.
458: * @return <CODE>true</CODE> if it is lowercase, <CODE>false</CODE> otherwise.
459: */
460: public boolean isLowercase() {
461: return lowercase;
462: }
463:
464: /**
465: * Checks if the indentation of list items is done automatically.
466: * @return the autoindent
467: */
468: public boolean isAutoindent() {
469: return autoindent;
470: }
471:
472: /**
473: * Checks if all the listitems should be aligned.
474: * @return the alignindent
475: */
476: public boolean isAlignindent() {
477: return alignindent;
478: }
479:
480: /**
481: * Gets the first number .
482: * @return a number
483: */
484: public int getFirst() {
485: return first;
486: }
487:
488: /**
489: * Gets the Chunk containing the symbol.
490: * @return a Chunk with a symbol
491: */
492: public Chunk getSymbol() {
493: return symbol;
494: }
495:
496: /**
497: * Gets the indentation of this paragraph on the left side.
498: * @return the indentation
499: */
500: public float getIndentationLeft() {
501: return indentationLeft;
502: }
503:
504: /**
505: * Gets the indentation of this paragraph on the right side.
506: * @return the indentation
507: */
508: public float getIndentationRight() {
509: return indentationRight;
510: }
511:
512: /**
513: * Gets the symbol indentation.
514: * @return the symbol indentation
515: */
516: public float getSymbolIndent() {
517: return symbolIndent;
518: }
519:
520: // deprecated constructor and methods
521: /**
522: * Returns a <CODE>List</CODE> that has been constructed taking in account
523: * the value of some <VAR>attributes</VAR>.
524: *
525: * @param attributes Some attributes
526: * @deprecated use ElementFactory.getList(attributes);
527: */
528:
529: public List(java.util.Properties attributes) {
530: this ();
531: List l = com.lowagie.text.factories.ElementFactory
532: .getList(attributes);
533: this .list = l.list;
534: this .numbered = l.numbered;
535: this .lettered = l.lettered;
536: this .lowercase = l.lowercase;
537: this .autoindent = l.autoindent;
538: this .alignindent = l.alignindent;
539: this .first = l.first;
540: this .symbol = l.symbol;
541: this .indentationLeft = l.indentationLeft;
542: this .indentationRight = l.indentationRight;
543: this .symbolIndent = l.symbolIndent;
544: }
545:
546: /**
547: * Checks if the list lettering is lowercase.
548: * @return <CODE>true</CODE> if it is lowercase, <CODE>false</CODE> otherwise.
549: * @deprecated use isLowercase();
550: */
551: public boolean isLowerCase() {
552: return isLowercase();
553: }
554:
555: /**
556: * Gets the first number .
557: * @return a number
558: * @deprecated use getFirst();
559: */
560: public int first() {
561: return getFirst();
562: }
563:
564: /**
565: * Gets the Chunk containing the symbol.
566: * @return a Chunk with a symbol
567: * @deprecated use getSymbol();
568: */
569: public Chunk symbol() {
570: return getSymbol();
571: }
572:
573: /**
574: * Gets the indentation of this paragraph on the left side.
575: * @return the indentation
576: * @deprecated use getIndentationLeft();
577: */
578:
579: public float indentationLeft() {
580: return indentationLeft;
581: }
582:
583: /**
584: * Gets the indentation of this paragraph on the right side.
585: * @return the indentation
586: * @deprecated use getIndentationRight();
587: */
588:
589: public float indentationRight() {
590: return getIndentationRight();
591: }
592:
593: /**
594: * Gets the symbol indentation.
595: * @return the symbol indentation
596: * @deprecated use getSymbolIndent();
597: */
598: public float symbolIndent() {
599: return getSymbolIndent();
600: }
601: }
|