24 Sept 2012

Computation area in TextArea

/* Computation area in TextArea */

public class TestReceipts {
    public static void main(String[] args) {
        new TestReceipts();
    }

    public TestReceipts() {
        EventQueue.invokeLater(new Runnable() {
            public void run() {

                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Bill me");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(600, 400);
                frame.setLocationRelativeTo(null);
                frame.setLayout(new BorderLayout());
                frame.add(new ReceiptPane());
                frame.setVisible(true);

            }
        });

    }

    protected class ReceiptPane extends JPanel {

        private JTextArea textArea;

        public ReceiptPane() {

            setLayout(new BorderLayout());
            textArea = new JTextArea();
            textArea.setEditable(false);
            add(new JScrollPane(textArea));

            List<Item> lstItems = new ArrayList<Item>(25);
            lstItems.add(new Item("Cakes", 1.5d, 5));
            lstItems.add(new Item("Cakes with cream", 2d, 5));
            lstItems.add(new Item("Cakes with chocolate", 2d, 5));
            lstItems.add(new Item("Cakes with chocolate & cream", 2.5d, 5));
            lstItems.add(new Item("Diet Coke (Can)", 2.5d, 5));

            generateReceipt(lstItems, 100d);

        }

        protected void generateReceipt(List<Item> lstItems, double amountTendered) {

            List<List<String>> lstRows = new ArrayList<List<String>>(25);

            int totalQty = 0;
            double subTotal = 0;

            NumberFormat nf = NumberFormat.getCurrencyInstance();

            for (Item item : lstItems) {
                String unit = nf.format(item.getUnitCost());
                String total = nf.format(item.getUnitCost() * item.getQty());

                lstRows.add(createRow(
                        Integer.toString(item.getQty()),
                        item.getDescription(),
                        unit,
                        total));

                subTotal += item.getUnitCost() * item.getQty();
            }

            int maxWidth = 60;
            int qtyWidth = 4;
            int unitWidth = 8;
            int totalWidth = 8;
            int descWidth = maxWidth - qtyWidth - unitWidth - totalWidth;

            StringBuilder sbHeader = new StringBuilder(maxWidth);
            sbHeader.append("Qty ");
            sbHeader.append(fillWith("Item", " ", descWidth));
            sbHeader.append(padWith("Cost", " ", unitWidth));
            sbHeader.append(padWith(" Total", " ", totalWidth));

            textArea.append(sbHeader.toString() + "\n");

            System.out.println(sbHeader.toString());

            for (List<String> row : lstRows) {
                StringBuilder sb = new StringBuilder(maxWidth);

                sb.append(padWith(row.get(0), " ", 3));
                sb.append(" ");
                String desc = row.get(1);
                if (desc.length() > descWidth) {

                    desc = desc.substring(0, descWidth);

                }
                sb.append(fillWith(desc, ".", descWidth));
                sb.append(padWith(row.get(2), " ", unitWidth));
                sb.append(padWith(row.get(3), " ", totalWidth));

                textArea.append(sb.toString() + "\n");
            }

            textArea.append(padWith("Sub-total " + padWith(nf.format(subTotal), " ", totalWidth), " ",      
            maxWidth) + "\n");

            double tax = subTotal * 0.1d;
            textArea.append(padWith("Tax " + padWith(nf.format(tax), " ", totalWidth), " ", maxWidth) + "\n");

            double total = tax + subTotal;
            textArea.append(padWith("Total "+padWith(nf.format(total)," ",totalWidth)," ",maxWidth)+"\n");

            textArea.append(padWith("Total "+padWith(nf.format(amountTendered)," ",totalWidth)," ", 
            maxWidth)+"\n");

            double change = amountTendered - total;
            textArea.append(padWith("Change " + padWith(nf.format(change), " ", totalWidth), " ", maxWidth) 
           + "\n");
        }

        protected List<String> createRow(String... columns) {
            return Arrays.asList(columns);
        }
    }

    public static String fillWith(String sValue, int width) {
        StringBuilder sb = new StringBuilder(width);
        for (int index = 0; index < width; index++) {
            sb.append(sValue);
        }
        return sb.toString();

    }

    public static String fillWith(String sValue, String fill, int width) {
        return sValue + fillWith(fill, width - sValue.length());
    }

    public static String pad(int iValue, int iMinLength) {
        return pad(Integer.toString(iValue), iMinLength);
    }

    public static String pad(String sValue, int iMinLength) {
        return padWith(sValue, "0", iMinLength);
    }

    public static String padWith(String value, String padding, int iMinLength) {
        StringBuilder sb = new StringBuilder(iMinLength);
        sb.append(value);

        while (sb.length() < iMinLength) {
            sb.insert(0, padding);
        }

        return sb.toString();
    }

    protected class Item {

        private String description;
        private double unitCost;
        private int qty;

        public Item(String description, double unitCost, int qty) {
            this.description = description;
            this.unitCost = unitCost;
            this.qty = qty;
        }

        public String getDescription() {
            return description;
        }

        public double getUnitCost() {
            return unitCost;
        }

        public int getQty() {
            return qty;
        }
    }
}