All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mq5.0-source.src.share.java.examples.monitoring.MultiColumnPrinter Maven / Gradle / Ivy

There is a newer version: 5.1
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2000-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

import java.util.Enumeration;
import java.util.Vector;
import java.util.Map;
import java.util.TreeMap;
import java.util.Iterator;

/**
 * Utility class for printing aligned collumns of text. How/where
 * the text is printed is determined by the abstract methods
 * doPrint(String) and doPrintln(String). The typical case is to 
 * create a subclass and make these methods print the string to standard 
 * out or error.
 * 

* This class allows you to specify: *

    *
  • The number of collumns in the output. This will determine * the dimension of the string arrays passed to add(String[]) * or addTitle(String[]). *
  • spacing/gap between columns *
  • character to use for title border (null means no border) *
  • column alignment. Only LEFT/CENTER is supported for now. *
* *

* Example usage: *

 *	MyPrinter	mp = new MyPrinter(3, 2, "-");
 *	String		oneRow[] = new String [ 3 ];
 *	oneRow[0] = "User Name";
 *	oneRow[1] = "Email Address";
 *	oneRow[2] = "Phone Number";
 *	mp.addTitle(oneRow);
 *
 *	oneRow[0] = "Bob";
 *	oneRow[1] = "[email protected]";
 *	oneRow[2] = "123-4567";
 *	mp.add(oneRow);
 *
 *	oneRow[0] = "John";
 *	oneRow[1] = "[email protected]";
 *	oneRow[2] = "456-7890";
 *	mp.add(oneRow);
 *	mp.print();
 * 
* *

* The above would print: *

*

 *	--------------------------------------
 *	User Name  Email Address  Phone Number
 *	--------------------------------------
 *	Bob        [email protected]    123-4567
 *	John       [email protected]   456-7890
 * 
* *

* This class also supports multi-row titles and having title * strings spanning multiple collumns. Example usage: *

 *     TestPrinter	tp = new TestPrinter(4, 2, "-");
 *     String		oneRow[] = new String [ 4 ];
 *     int[]		span = new int[ 4 ];
 *
 *     span[0] = 2; // spans 2 collumns
 *     span[1] = 0; // spans 0 collumns
 *     span[2] = 2; // spans 2 collumns
 *     span[3] = 0; // spans 0 collumns
 *
 *     tp.setTitleAlign(CENTER);
 *     oneRow[0] = "Name";
 *     oneRow[1] = "";
 *     oneRow[2] = "Contact";
 *     oneRow[3] = "";
 *     tp.addTitle(oneRow, span);
 * 
 *     oneRow[0] = "First";
 *     oneRow[1] = "Last";
 *     oneRow[2] = "Email";
 *     oneRow[3] = "Phone";
 *     tp.addTitle(oneRow);
 * 
 *     oneRow[0] = "Bob";
 *     oneRow[1] = "Jones";
 *     oneRow[2] = "[email protected]";
 *     oneRow[3] = "123-4567";
 *     tp.add(oneRow);
 * 
 *     oneRow[0] = "John";
 *     oneRow[1] = "Doe";
 *     oneRow[2] = "[email protected]";
 *     oneRow[3] = "456-7890";
 *     tp.add(oneRow);
 * 
 *     tp.println();
 * 
* *

* The above would print: *

*

 *      ------------------------------------
 *          Name             Contact          
 *      First  Last      Email       Phone  
 *      ------------------------------------
 *      Bob    Jones  [email protected]   123-4567
 *      John   Doe    [email protected]  456-7890
 * 
* */ public abstract class MultiColumnPrinter { final public static int LEFT = 0; final public static int CENTER = 1; /* * Sets the default sorting behavior. * When set to true, the table entries are sorted unless otherwise * specified in a constructor. */ final private static boolean DEFAULT_SORT = true; private int numCol = 2; private int gap = 4; private int align = CENTER; private int titleAlign = CENTER; private String border = null; private Vector table = null; private Vector titleTable = null; private Vector titleSpanTable = null; private int curLength[]; private boolean sortNeeded = DEFAULT_SORT; private int[] keyCriteria = null; /** * Creates a new MultiColumnPrinter class. * * @param numCol number of columns * @param gap gap between each column * @param border character used to frame the titles * @param align type of alignment within columns * @param sort true if the output is sorted; false otherwise * * REVISIT: Possibly adding another argument that specifies which ones can * be truncated (xxx...) */ public MultiColumnPrinter(int numCol, int gap, String border, int align, boolean sort) { table = new Vector(); titleTable = new Vector(); titleSpanTable = new Vector(); curLength = new int[numCol]; this.numCol = numCol; this.gap = gap; this.border = border; this.align = align; this.titleAlign = LEFT; this.sortNeeded = sort; } /** * Creates a new sorted MultiColumnPrinter class. * * @param numCol number of columns * @param gap gap between each column * @param border character used to frame the titles * @param align type of alignment within columns */ public MultiColumnPrinter(int numCol, int gap, String border, int align) { this(numCol, gap, border, align, DEFAULT_SORT); } /** * Creates a sorted new MultiColumnPrinter class using LEFT alignment. * * @param numCol number of columns * @param gap gap between each column * @param border character used to frame the titles */ public MultiColumnPrinter(int numCol, int gap, String border) { this(numCol, gap, border, LEFT); } /** * Creates a sorted new MultiColumnPrinter class using LEFT alignment * and with no title border. * * @param numCol number of columns * @param gap gap between each column */ public MultiColumnPrinter(int numCol, int gap) { this(numCol, gap, null, LEFT); } /** * Adds to the row of strings to be used as the title for the table. * * @param row Array of strings to print in one row of title. */ public void addTitle(String[] row) { if (row == null) return; int[] span = new int [ row.length ]; for (int i = 0; i < row.length; i++) { span[i] = 1; } addTitle(row, span); } /** * Adds to the row of strings to be used as the title for the table. * Also allows for certain title strings to span multiple collumns * The span parameter is an array of integers which indicate how * many collumns the corresponding title string will occupy. * For a row that is 4 collumns wide, it is possible to have some * title strings in a row to 'span' multiple collumns: * *

*

     * ------------------------------------
     *     Name             Contact          
     * First  Last      Email       Phone  
     * ------------------------------------
     * Bob    Jones  [email protected]   123-4567
     * John   Doe    [email protected]  456-7890
     * 
* * In the example above, the title row has a string 'Name' that * spans 2 collumns. The string 'Contact' also spans 2 collumns. * The above is done by passing in to addTitle() an array that * contains: * *
     *    span[0] = 2; // spans 2 collumns
     *    span[1] = 0; // spans 0 collumns, ignore
     *    span[2] = 2; // spans 2 collumns
     *    span[3] = 0; // spans 0 collumns, ignore
     * 
*

* A span value of 1 is the default. * The method addTitle(String[] row) basically does: * *

     *   int[] span = new int [ row.length ];
     *   for (int i = 0; i < row.length; i++) {
     *       span[i] = 1;
     *   }
     *   addTitle(row, span);
     * 
* * @param row Array of strings to print in one row of title. * @param span Array of integers that reflect the number of collumns * the corresponding title string will occupy. */ public void addTitle(String[] row, int span[]) { // Need to create a new instance of it, otherwise the new values will // always overwrite the old values. String[] rowInstance = new String[(row.length)]; for (int i = 0; i < row.length; i++) { rowInstance[i] = row[i]; } titleTable.addElement(rowInstance); titleSpanTable.addElement(span); } /** * Set alignment for title strings * * @param titleAlign */ public void setTitleAlign(int titleAlign) { this.titleAlign = titleAlign; } /** * Adds one row of text to output. * * @param row Array of strings to print in one row. */ public void add(String[] row) { // Need to create a new instance of it, otherwise the new values will // always overwrite the old values. String[] rowInstance = new String[(row.length)]; for (int i = 0; i < row.length; i++) { rowInstance[i] = row[i]; } table.addElement(rowInstance); } /** * Clears title strings. */ public void clearTitle() { titleTable.clear(); titleSpanTable.clear(); } /** * Clears strings. */ public void clear() { table.clear(); if (curLength != null) { for (int i = 0; i < curLength.length; ++i) { curLength[i] = 0; } } } /** * Prints the multi-column table, including the title. */ public void print() { print(true); } /** * Prints the multi-column table. * * @param printTitle Specifies if the title rows should be printed. */ public void print(boolean printTitle) { // REVISIT: // Make sure you take care of curLength and row being null value cases. // Get the longest string for each column and store in curLength[] // Scan through title rows Enumeration elm = titleTable.elements(); Enumeration spanEnum = titleSpanTable.elements(); int rowNum = 0; while (elm.hasMoreElements()) { String[] row = (String[])elm.nextElement(); int[] curSpan = (int[])spanEnum.nextElement(); for (int i = 0; i < numCol; i++) { // Fix for 4627901: NullPtrException seen when // execute 'jmqcmd list dur' // This happens when a field to be listed is null. // None of the fields should be null, but if it // happens to be so, replace it with "-". if (row[i] == null) row[i] = "-"; int len = row[i].length(); /* * If a title string spans multiple collumns, then * the space it occupies in each collumn is at most * len/span (since we have gap to take into account * as well). */ int span = curSpan[i], rem = 0; if (span > 1) { rem = len % span; len = len/span; } if (curLength[i] < len) { curLength[i] = len; if ((span > 1) && ((i+span) <= numCol)) { for (int j=i+1; j<(i+span); ++j) { curLength[j] = len; } /* * Add remainder to last collumn in span * to avoid round-off errors. */ curLength[(i+span)-1] += rem; } } } ++rowNum; } // Scan through rest of rows elm = table.elements(); while (elm.hasMoreElements()) { String[] row = (String[])elm.nextElement(); for (int i = 0; i < numCol; i++) { // Fix for 4627901: NullPtrException seen when // execute 'jmqcmd list dur' // This happens when a field to be listed is null. // None of the fields should be null, but if it // happens to be so, replace it with "-". if (row[i] == null) row[i] = "-"; if (curLength[i] < row[i].length()) curLength[i] = row[i].length(); } } /* * Print title */ if (printTitle) { printBorder(); elm = titleTable.elements(); spanEnum = titleSpanTable.elements(); while (elm.hasMoreElements()) { String[] row = (String[])elm.nextElement(); int[] curSpan = (int[])spanEnum.nextElement(); for (int i = 0; i < numCol; i++) { int availableSpace = 0, span = curSpan[i]; if (span == 0) continue; availableSpace = curLength[i]; if ((span > 1) && ((i+span) <= numCol)) { for (int j=i+1; j<(i+span); ++j) { availableSpace += gap; availableSpace += curLength[j]; } } if (titleAlign == CENTER) { int space_before, space_after; space_before = (availableSpace-row[i].length())/2; space_after = availableSpace-row[i].length() - space_before; printSpaces(space_before); doPrint(row[i]); printSpaces(space_after); if (i < numCol-1) printSpaces(gap); } else { doPrint(row[i]); if (i < numCol-1) printSpaces(availableSpace-row[i].length()+gap); } } doPrintln(""); } printBorder(); } if (sortNeeded) printSortedTable(); else printUnsortedTable(); } /* * Prints the table entries in the sorted order. */ private void printSortedTable() { // Sort the table entries TreeMap sortedTable = new TreeMap(); Enumeration elm = table.elements(); while (elm.hasMoreElements()) { String[] row = (String[])elm.nextElement(); // If keyCriteria contains valid info use that // to create the key; otherwise, use the default row[0] // for the key. if (keyCriteria != null && keyCriteria.length > 0) { String key = getKey(row); if (key != null) sortedTable.put(key, row); else sortedTable.put(row[0], row); } else { sortedTable.put(row[0], row); } } // Iterate through the table entries Iterator iterator = sortedTable.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry)iterator.next(); String[] row = ((String[])entry.getValue()); printRow(row); } } /* * Creates the key for the current row based on the * criteria specified by setKeyCriteria(). * If key cannot be created by the criteria, it simply returns * null. * * Examples: * String[] row = {"foo", "bar", "hello"); * * int[] keyCriteria = {0}; * key = "foo"; * * int[] keyCriteria = {0, 1}; * key = "foobar"; * * int[] keyCriteria = {2, 1}; * key = "hellobar"; * * int[] keyCriteria = {4}; * key = null; */ private String getKey(String[] row) { String key = ""; for (int i = 0; i < keyCriteria.length; i++) { int content = keyCriteria[i]; try { key = key + row[content]; } catch (ArrayIndexOutOfBoundsException ae) { // Happens when keyCriteria[] contains an index that // does not exist in 'row'. return null; } } return key; } /* * Prints the table entries in the order they were entered. */ private void printUnsortedTable() { Enumeration elm = table.elements(); while (elm.hasMoreElements()) { String[] row = (String[])elm.nextElement(); printRow(row); } } private void printRow(String[] row) { for (int i = 0; i < numCol; i++) { if (align == CENTER) { int space1, space2; space1 = (curLength[i]-row[i].length())/2; space2 = curLength[i]-row[i].length() - space1; printSpaces(space1); doPrint(row[i]); printSpaces(space2); if (i < numCol-1) printSpaces(gap); } else { doPrint(row[i]); if (i < numCol-1) printSpaces(curLength[i]-row[i].length()+gap); } } doPrintln(""); } /** * Prints the multi-column table, with a carriage return. */ public void println() { print(); doPrintln(""); } private void printSpaces(int count) { for (int i = 0; i < count; ++i) { doPrint(" "); } } private void printBorder() { int colNum = 1; if (border == null) return; // For the value in each column for (int i = 0; i < numCol; i++) { for (int j = 0; j < curLength[i]; j++) { doPrint(border); } } // For the gap between each column for (int i = 0; i < numCol-1; i++) { for (int j = 0; j < gap; j++) { doPrint(border); } } doPrintln(""); } /* * Sets the criteria for the key. * new int[] {0, 1} means use the first and the second * elements of the array. */ public void setKeyCriteria(int[] criteria) { this.keyCriteria = criteria; } /** * Method that does the actual printing. Override this method to * print to your destination of choice (stdout, stream, etc). * * @param str String to print. */ public abstract void doPrint(String str); /** * Method that does the actual printing. Override this method to * print to your destination of choice (stdout, stream, etc). * * This method also prints a newline at the end of the string. * * @param str String to print. */ public abstract void doPrintln(String str); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy