Showing posts with label JAVA. Show all posts
Showing posts with label JAVA. Show all posts

Friday, October 9, 2009

Date and Big Decimal utilities

Problem Description

We need various small utilities regardign numbers and dates.
This code snippet has included some of the common conversions for convenience.



Solution Description

There are two separate classes "DateUtils" and "NumberUtils". MyMain class shows the usage.



Code Snippet


NumberUtils.java



import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;


public class NumberUtils {

    /**
     * Method takes Object as parameter and returns decimal number.
     * if argument is float or double and contains tailing zeros
     * it removes them. If argument is float or double then no change in return type.
     * Change the Format of the Number by changing the String Pattern
     */
    public static String changeToDecimalFormat(Object number) {

        BigDecimal bdNumber = new BigDecimal(number.toString());
        bdNumber = bdNumber.stripTrailingZeros();           //Returns a BigDecimal with any trailing zero's removed
        String pattern = "###,##0.0###########";        //To apply formatting when the number of digits in input equals the pattern
        DecimalFormat newFormat = new DecimalFormat(pattern, new DecimalFormatSymbols(Locale.US));
        return newFormat.format(bdNumber);

    }

    /* Method takes Object as parameter and removes commas from the parameter */
    public static double removeCommasFromNumber(Object number) {
        try {
            StringBuffer inputNo = new StringBuffer(number.toString());
            if (inputNo.length() > 0) {
                while (inputNo.indexOf(",") != -1) {
                    inputNo.deleteCharAt(inputNo.indexOf(","));
                }
            } else {
                return 0.0;
            }
            return Double.parseDouble(inputNo.toString());

        } catch (NumberFormatException e) {
            return 0.0;
        }
    }

    /* Some times its required to have a fixed set of decimal places for a
     * number. We can set that by changing the precision number for a particular
     * input BigDecimal Input String
     */
    public static String changeToRequiredDecimals(String bigDecimalString,
            int precision) {
        String newFormattedString = null;
        String afterDecimal = null;
        if (bigDecimalString == null || bigDecimalString.length() == 0) {
            return "0.0";
        }
        if (bigDecimalString.contains(".")) {
            afterDecimal = bigDecimalString.substring(bigDecimalString
                    .indexOf(".") + 1);
            int length = Math.abs((afterDecimal.length() - precision));
            if (afterDecimal.length() < precision) {
                newFormattedString = bigDecimalString;
                for (int i = 0; i < length; i++) {
                    newFormattedString = newFormattedString + "0";
                }
            } else if (afterDecimal.length() > precision) {
                newFormattedString = bigDecimalString.substring(0,
                        bigDecimalString.length() - length);
                if (precision == 0) {
                    newFormattedString = newFormattedString.substring(0,
                            newFormattedString.indexOf("."));
                } else {
                    newFormattedString = bigDecimalString;
                }

            } else {
                    if (precision > 0)
                        newFormattedString = bigDecimalString + ".";
                    else
                        newFormattedString = bigDecimalString;
                    for (int i = 0; i < precision; i++) {
                        newFormattedString = newFormattedString + "0";
                    }
            }
        }
        return newFormattedString;
    }

}


DateUtils.java



import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;


public class DateUtils {

    public static Date getNthFromCurrentDate(int field, int nValue) {
        Calendar current = Calendar.getInstance();
        current.setLenient(true);
        current.add(field, nValue);
        return current.getTime();
    }
   
    public static Date convertStringToDate(String dateString, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return sdf.parse(dateString);
        } catch (ParseException e) {
            return null;
        }
    }
    public static Date convertStringToTimestamp(String dateString, String pattern) {
        return new Timestamp(convertStringToDate(dateString, pattern).getTime());
    }
}


MyMain.java



import java.math.BigDecimal;


/**
 *
 */
public class MyMain {

    /**
     *Method
     * @param args
     */
    public static void main(String[] args) {

       
        System.out.println(DateUtils.convertStringToDate("11.10.2010", "dd.MM.yyyy"));
        System.out.println(DateUtils.convertStringToTimestamp("11.10.2010", "dd.MM.yyyy"));
        System.out.println(DateUtils.getNthFromCurrentDate(1,2));
       
        int intVar = 10;
        double doubleVar = 10.504000;
        float floatVar = 343534534348.5687654F;
        String commaString = "343,534,535,000.0";
        BigDecimal bdNumber = new BigDecimal("1234.8765");
       
       
        System.out.println(NumberUtils.changeToDecimalFormat(new Integer(intVar)));
        System.out.println(NumberUtils.changeToDecimalFormat(new Double(doubleVar)));
        System.out.println(NumberUtils.changeToDecimalFormat(new Float(floatVar)));
       
        System.out.println(NumberUtils.removeCommasFromNumber(commaString));
       
        System.out.println(NumberUtils.changeToRequiredDecimals(bdNumber.toString(), 8));

    }


}






Thursday, October 8, 2009

Drawing multiple XY graphs using JFreechart

Problem Description
There are sometimes requirement to draw multiple plots against time in any java application. JFreechart provides an excellent API for this purpose. But knowing and remembering all the methods in this API is painfull and time consuming






Solution Description
My code draws multiple X-Y charts using the data provided. The source comes with all the jar files necessary for this purpose. It does two things.
1) Saves the chart in some specified location of local machine as JPG image.
2) Draws the chart on the screen using Swing API.

Dependencies
jfreechart-1.0.4.jar
jcommon-1.0.9.jar








Sample Code


MyMain.java





package graph;


/**
* Helper class. Used to testing purpose
*
*/
public class Mymain {


/**
*
* @param args
*/
public static void main(String[] args) {
System.out.println("MAIN : START");
Graph graph = new Graph();
Value value;
Value localvalues[]= new Value[names.length];
graph.setNames(names);
for (int i=0;i
value = new Value();
value.setI(values[i]);
localvalues[i] = value;
}
graph.setValues(localvalues);
new MyGraphs().createChart(graph,GraphConstants.PERIOD_TYPE_MONTHLY);


System.out.println("MAIN : END");


}

protected final static Integer values[][] = {
{12,1,123,10,200,12,45,15},
{1,12,10,112,0,122,15},
{121,34,21,13,90,6,78},
{5,67,15,104,2,123,4}
};
protected final static String names[] = {
"Report1",
"Report2",
"Report3",
"Report4"
};


}


Graph.java





package graph;


/**
*
*
*/
public class Graph {
String names[];
Value values[];
/**
*
* @return names
*/
public String[] getNames() {
return names;
}
/**
*
* @param names
*/
public void setNames(String[] names) {
this.names = names;
}
/**
*
* @return values
*/
public Value[] getValues() {
return values;
}
/**
*
* @param values
*/
public void setValues(Value[] values) {
this.values = values;
}


}



GraphConstants.java



package graph;


/**


* Constant file


*


*/


public interface GraphConstants {





/**period type if weekly*/


public final int PERIOD_TYPE_WEEKLY = 0;


/**period type if monthly*/


public final int PERIOD_TYPE_MONTHLY = 1;


/**period type if monthly*/


public final int PERIOD_TYPE_QUATERLY = 2;






/** the location of the file to be stored*/


public static final String FILE_PATH = "d:\\chart.jpg";





/**plotting details : width of x-axis*/


public static final int X_AXIS_WIDTH = 500;


/**plotting details : width of y-axis*/


public static final int Y_AXIS_WIDTH = 300;





/**graph name : This part should be moved to property file*/


public static final String GRAPH_NAME = "Graph Name";


/**x-axis label : This part should be moved to property file*/


public static final String X_AXIS = "X Axis";


/**y-axis label : This part should be moved to property file*/


public static final String Y_AXIS = "Y Axis";


/** Sample data error. This part should be moved to property file*/


public static final String ERROR_MESSAGE = "Name and values must be equal in number";





/** Null string*/


public static final String NULL = null;






}


MyGraphs.java




package graph;


import java.awt.BorderLayout;


import java.io.File;


import java.io.IOException;


import javax.swing.JPanel;


import org.jfree.chart.ChartFactory;


import org.jfree.chart.ChartPanel;


import org.jfree.chart.ChartUtilities;


import org.jfree.chart.JFreeChart;


import org.jfree.chart.labels.XYToolTipGenerator;


import org.jfree.chart.plot.XYPlot;


import org.jfree.chart.renderer.xy.XYItemRenderer;


import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;


import org.jfree.data.time.Month;


import org.jfree.data.time.Quarter;


import org.jfree.data.time.RegularTimePeriod;


import org.jfree.data.time.TimeSeries;


import org.jfree.data.time.TimeSeriesCollection;


import org.jfree.data.time.Week;


import org.jfree.data.xy.XYDataset;


import org.jfree.ui.ApplicationFrame;


import org.jfree.ui.RefineryUtilities;










/**


* This class is responsible for creating the graph using the data provided.


*


*/


public class MyGraphs extends ApplicationFrame implements XYToolTipGenerator{








/**


*


*/


private static final long serialVersionUID = -4019769545419857920L;






/** JFreeChart */


private JFreeChart chart;





/** Time series collection */


private TimeSeriesCollection dataset;


/**


* no-arg constructor


*/


public MyGraphs(){


this(GraphConstants.GRAPH_NAME);


}


/**


*


* @param title


*/


public MyGraphs(String title){


super(title);


}


/**


* This method takes care of all the aspects of drawing the graph


* @param graph


* @param periodType


*/


protected void createChart(Graph graph,int periodType) {


dataset = new TimeSeriesCollection();






// Add series data from table model to chart


try{


addSeriesToChart(dataset, graph,periodType);






// Create chart


chart = ChartFactory.createTimeSeriesChart(GraphConstants.GRAPH_NAME,GraphConstants.X_AXIS,GraphConstants.Y_AXIS,


dataset, true, true, false);






XYPlot plot = (XYPlot) chart.getPlot();





//Configured the axis of the graph


configureAxis(plot);






//Configures the rendered


configureRenderer(plot);






//Saves the graph image at the mentioned file path


saveChart();






//Draws the chart on screen using java swing


drawChart();


}catch (IOException ioe){


ioe.printStackTrace();


}catch(Exception e){


e.printStackTrace();


}






}





/**


* saves the chart as a jpg image at specified location.


*/


private void saveChart()throws IOException{


ChartUtilities.saveChartAsJPEG(new File(GraphConstants.FILE_PATH), chart, GraphConstants.X_AXIS_WIDTH, GraphConstants.Y_AXIS_WIDTH);


}





/**


* creates the graph on screen, with the aid of the class XYChartDemo.


*/


private void drawChart(){


this.setSize(new java.awt.Dimension(GraphConstants.X_AXIS_WIDTH,GraphConstants.Y_AXIS_WIDTH));


ChartPanel chartPanel = new ChartPanel(chart);








// size


chartPanel.setPreferredSize(new java.awt.Dimension(GraphConstants.X_AXIS_WIDTH,GraphConstants.Y_AXIS_WIDTH));






final JPanel main = new JPanel(new BorderLayout());


final JPanel optionsPanel = new JPanel();






main.add(optionsPanel, BorderLayout.SOUTH);


main.add(chartPanel);


setContentPane(main);


RefineryUtilities.centerFrameOnScreen(this);


setVisible(true);






}


/**


*


* @param dataset


* @param graph


* @param periodType


* @throws Exception


*/


protected void addSeriesToChart(TimeSeriesCollection dataset,Graph graph,int periodType)throws Exception{





int count_from = 0;


int count_to = graph.getNames().length;


if (graph.getNames().length!= graph.getValues().length){


throw new Exception(GraphConstants.ERROR_MESSAGE);


}


for (int j = count_from;j


TimeSeries g = new TimeSeries(graph.getNames()[j], getTimePeriod(periodType).getClass());


RegularTimePeriod start = getTimePeriod(periodType);


for (int i = 0; i


start = start.previous();


double value = (graph.getValues()[j].getI()[i]).doubleValue();


g.add(start,value);


}


dataset.addSeries(g);


}


}


/**


* @param xyPlot


*/


protected void configureAxis(XYPlot plot){


// Make crosshair visible for Range and Domain axis.


plot.setDomainCrosshairVisible(true);


plot.setRangeCrosshairVisible(true);






// Set upper margin of Domain axis for proper display of Item label.


plot.getDomainAxis().setUpperMargin(.05);






// Set margin of range axis for proper display of Item label.


plot.getRangeAxis().setUpperMargin(0.15);


plot.getRangeAxis().setLowerMargin(0.15);


//plot.getRangeAxis().setAutoRange(true);


}





/**


*


* @param plot


*/


protected void configureRenderer(XYPlot plot){


XYItemRenderer r = plot.getRenderer();






if (r instanceof XYLineAndShapeRenderer) {


XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;


renderer.setBaseShapesVisible(true);


renderer.setBaseShapesFilled(true);


}


}


/**


*


* @param periodType


* @return


*/


protected RegularTimePeriod getTimePeriod(int periodType){


switch(periodType){


case GraphConstants.PERIOD_TYPE_WEEKLY:


return new Week();


case GraphConstants.PERIOD_TYPE_MONTHLY:


return new Month();


case GraphConstants.PERIOD_TYPE_QUATERLY:


return new Quarter();


default:


return new Month();


}


}





/**


* @param dataset


* @param series


* @param item


* @return tooltip


*/


public String generateToolTip(XYDataset dataset, int series, int item) {


String tooltip;


if(item == 0){


tooltip = GraphConstants.NULL;


}else{


tooltip = " ";


}


return tooltip;


}






}



Wednesday, October 7, 2009

XWindows and Java

Often in our java code, we use AWT or SWING packages. The application runs fine in windows machines(usually development environments are in windows machines). But when we try to run those java applications in Linux/Unix box, we face problem in running. Because It uses the native graphics toolkits for rendering, but Linux/Unix doesn't have graphics toolkits installed.
XWindows is a package, when installed, gives the Linux/Unix the graphics toolkit ability.
But in most practical cases, you are not the ROOT user of the box. So you have to raise a request to infrastructure team for installing the XWindows package. And they will ask you hundreds of questions like:
why you need it?
are you sure you need it?
prove us, that XWindows will solve your problem etc etc...

You want to be very sure that installing XWindows will solve your problem. For this, you may follow these steps:
  1. CYGWIN is an application, using which you can simulate Linux like facilities in your windows machine. Install CYGWIN in your system from here. While installing, it will give you options regarding which packages you want to install. Make sure the X11 packages are all selected.
  2. Put your application jar into the remote machine, where your application is supposed to run.
  3. Open CYGWIN window and run "startxwin.bat". It will start the xserver and open a new window. Or you can directly open XWin Server from the start-menu under Cygwin-x.
  4. In the new window add the remote machine ip in the access control list. Using the command "xhost ". "xhost  /remote machine ip/ "
  5. In the remote machine set the DISPLAY property as: "export DISPLAY=/local machine ip/:0.0" . By doing this, you are directing the remote machine, to use the display of you local machine for rendering.
  6. Now run the application in you remote machine. It should run fine.
Now that you are able to run your application using XWINDOWS, you can confidently go and command Infra team, that this is exactly what you want.
If you face any issues, please post it here, I will try to help you out.
Hope this makes your life easier. Because I had a hard time convincing my Infra team.