Nov 15

The BigDecimal constructors do not take the Locale into account when parsing number strings.
This means the following code will throw a NumberFormatException

Locale.setDefault(new Locale("nl", "NL"));
String s =  "2.343.298,09324798";
BigDecimal bd = new BigDecimal(s);

To parse localized strings as BigDecimal we instead need to use the DecimalFormat class

		Locale.setDefault(new Locale("nl", "NL"));
		String s =  "2.343.298,09324798";
		DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
		df.setParseBigDecimal(true);
		BigDecimal bd = (BigDecimal) df.parse(s);

written by objects \\ tags: , , , ,

Apr 15

Rendering of table cells is handled by instances of TableCellRenderer. By default JTable uses a DefaultTableCellRenderer to render all of its cells.
To control the number of decimal places used we just need to subclass DefaultTableCellRenderer and format the cell double value before passing the (formatted) value to to the parent (DefaultTableCellRenderer) class.
To get the table to use that class we tell the JTable to use it for a given column.

Following example illustrates what is required.

import java.awt.*;
import java.text.DecimalFormat;
import javax.swing.*;
import javax.swing.table.*;
 
public class DecimalPlacesInTable extends JFrame {
	public static void main( String[] args ) {
		DecimalPlacesInTable frame = new DecimalPlacesInTable();
		frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
		frame.pack();
		frame.setVisible( true );
	}
 
	public DecimalPlacesInTable() {
		Object[] columnNames = { "A", "B", "C" };
		Object[][] data = {
				{ "abc", new Double( 850.503 ), 5 },
				{ "def", new Double( 36.23254 ), 6 },
				{ "ghi", new Double( 8.3 ), 7 },
				{ "jkl", new Double( 246.0943 ), 23 }};
 
		JTable table = new JTable(data, columnNames);

                // Tell the table what to use to render our column of doubles

		table.getColumnModel().getColumn(1).setCellRenderer(new DecimalFormatRenderer() );
		getContentPane().add(new JScrollPane(table));
	}

        /**
         Here is our class to handle the formatting of the double values
         */

	static class DecimalFormatRenderer extends DefaultTableCellRenderer {
		private static final DecimalFormat formatter = new DecimalFormat( "#.00" );
 
		public Component getTableCellRendererComponent(
			JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                        // First format the cell value as required

			value = formatter.format((Number)value);

                        // And pass it on to parent class 

			return super.getTableCellRendererComponent(
				table, value, isSelected, hasFocus, row, column );
		} 
	}
}

written by objects \\ tags: , , ,

Feb 24

Standard rounding provided by BigDecimal and DecimalFormat rounds to the nearest 0 or 1. If you instead want to round to 0, 1 or 0.5 then you need to do a little work

For example to round up to 4 decimal places to the nearest 0, 1, or .5 you could use the following code.

BigDecimal bd = new BigDecimal((d * 2.0) + 0.0005)
   .setScale(3, BigDecimal.ROUND_HALF_UP);
bd = new BigDecimal(bd.doubleValue()/2.0)
   .setScale(4, BigDecimal.ROUND_HALF_UP);
String rounded = bd.toString();

written by objects \\ tags: , , ,