Package net.sourceforge.javautil.ui.cli.widget

Source Code of net.sourceforge.javautil.ui.cli.widget.TextTable

package net.sourceforge.javautil.ui.cli.widget;

import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.reflect.Array;

import net.sourceforge.javautil.common.StringUtil;
import net.sourceforge.javautil.ui.cli.CommandLineContext;
import net.sourceforge.javautil.ui.cli.CommandLineInterface;
import net.sourceforge.javautil.ui.model.UITableModel;
import net.sourceforge.javautil.ui.widget.UIWidgetAbstract;

/**
* A table expressed in text. This will recognized the following attributes:<br/><br/>
*
* <b>caption</b>: An optional caption for the table. The string form of the value will be
* used for the display of the caption<br/><br/>
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: TextTable.java 1581 2009-12-22 18:45:09Z ponderator $
*/
public class TextTable extends UIWidgetAbstract implements TextWidget {
 
  /**
   * The model for the table
   */
  private UITableModel model;
 
  /**
   * Padding between columns
   */
  private int padding = 2;
 
  /**
   * Border between columns
   */
  private int border = 1;
 
  public TextTable() {}
  public TextTable(UITableModel model) {
    this.model = model;
  }

  /**
   * @return The {@link #model}
   */
  public UITableModel getModel() { return model; }
  public void setModel(UITableModel model) { this.model = model; }

  public void render (PrintStream writer) {
   
    UITableModel model = this.model;
    int[] widths = this.calculateRealColumnWidths(model);
    int totalWidth = this.calculateTotalWidth(widths);
   
    Object caption = model.getAttribute("caption");
    if (caption != null) {
      this.renderBorderHorizontal(writer, totalWidth);
      this.renderSingleColumnRow(writer, String.valueOf(caption), totalWidth, UITableModel.CENTER);
    }
   
    if (model.isShowHeaders())
      this.renderHeaders(writer, model, totalWidth, widths);
    else
      this.renderBorderHorizontal(writer, widths);
   
    for (int r=0; r<model.getRowCount(); r++) {
      this.renderColumns(writer, model, r, widths);
      this.renderBorderHorizontal(writer, widths);
    }
   
  }
 
  /**
   * @param model The model in question
   * @param column The column to get alignment for
   * @return The specified alignment or the default
   */
  protected int getAlignment (UITableModel model, int column) {
    return model.getAlignment(column) == -1 ? UITableModel.LEFT : model.getAlignment(column);
  }
 
  /**
   * Render all the columns in a single row
   * 
   * @param out The output stream
   * @param model The table model
   * @param row The row to render
   * @param widths The column widths
   */
  protected void renderColumns (PrintStream out, UITableModel model, int row, int... widths) {
    out.print("|");
    for (int c=0; c<model.getColumnCount(); c++) {
      Object value = model.getValueAt(row, c);
     
      if (value instanceof byte[]) value = new String( (byte[]) value );
      else if (value instanceof char[]) value = new String( (char[]) value );
      else if (value != null && value.getClass().isArray()) {
        value = Array.getLength(value) + " " + value.getClass().getComponentType();
      }
     
      String text = model.getValueAt(row, c) == null ? "" : value.toString();
      this.renderColumnData(out, text, widths[c], this.getAlignment(model, c));
    }
    out.println();
  }
 
  /**
   * Render a column of data.
   *
   * @param out The output stream
   * @param data The data for the column
   * @param width The max width of the column
   * @param alignment The alignment of the column
   */
  protected void renderColumnData (PrintStream out, String data, int width, int alignment) {
    out.print(" " + StringUtil.getStrictFixedWidthElipsis(data, width, alignment) + " |");
  }
 
  /**
   * Render text on an entire row with all columns joined.
   *
   * @param out The output stream
   * @param data The data for the column
   * @param width The max width of the column
   * @param alignment The alignment of the column
   */
  protected void renderSingleColumnRow (PrintStream out, String data, int width, int alignment) {
    out.println("| " + StringUtil.getStrictFixedWidthElipsis(data, width, alignment) + " |");
  }
 
  /**
   * Render the table headers.
   *
   * @param out The output stream
   * @param model The table model
   * @param totalWidth The total width of the table
   * @param widths The column widths
   */
  protected void renderHeaders (PrintStream out, UITableModel model, int totalWidth, int[] widths) {
    this.renderBorderHorizontal(out, widths);
   
    out.print("|");
    for (int c=0; c<widths.length; c++)
      this.renderColumnData(out, model.getHeader(c), widths[c], this.getAlignment(model, c));
    out.println();
   
    this.renderBorderHorizontal(out, widths);
  }
 
  /**
   * Render a horizontal border.
   *
   * @param out The output stream
   * @param widths The column widths
   */
  protected void renderBorderHorizontal (PrintStream out, int... widths) {
    out.print("+");
    for (int width : widths) {
      out.print(StringUtil.repeat('-', width + padding) + "+");
    }
    out.println();
  }
 
  /**
   * @param widths The column widths
   * @return A total width including borders and padding
   */
  protected int calculateTotalWidth (int... widths) {
    int total = border;
    for (int w=0; w<widths.length; w++) {
      total += widths[w] + padding + border;
    }
    return total - ((border * 2) + padding);
  }
 
  /**
   * This calls {@link #calculateRealColumnWidth(TableModel, int)} for
   * each column.
   *
   * @param model The model for which to calculate widths
   * @return The array of widths corresponding to the coumns
   */
  protected int[] calculateRealColumnWidths (UITableModel model) {
    int[] widths = new int[model.getColumnCount()];
    for (int w=0; w<widths.length; w++) {
      widths[w] = this.calculateRealColumnWidth(model, w);
    }
    return widths;
  }
 
  /**
   * If the max width has been specified ({@link #setColumnWidths(int...)}) then
   * it will simply return that, otherwise it will calculate the greatest width
   * of each cell of the model. It will also take into account the width of any
   * {@link #columnHeaders} that may have been defined.
   *
   * @param model The model for which to calculate the width
   * @param column The column of the model
   * @return The max width
   */
  protected int calculateRealColumnWidth (UITableModel model, int column) {
    if (model.isHasFixedColumnWidths() && model.getWidth(column) > 0) {
      return model.getWidth(column);
    } else {
      int maxwidth = !"".equals(model.getHeader(column)) ? model.getHeader(column).length() : 1;
                     
      for (int r=0; r<model.getRowCount(); r++) {
        Object value = model.getValueAt(r, column);
        if (value != null) {
          String str = value.toString();
          if (str.length() > maxwidth) maxwidth = str.length();
        }
      }
      return maxwidth;
    }
  }
 
}
TOP

Related Classes of net.sourceforge.javautil.ui.cli.widget.TextTable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.