me.philnate.textmanager.windows.MainWindow.java Source code

Java tutorial

Introduction

Here is the source code for me.philnate.textmanager.windows.MainWindow.java

Source

/**
 *   textManager, a GUI for managing bills for texter jobs
 *
 *   Copyright (C) 2013 philnate
 *
 *   This file is part of textManager.
 *
 *   textManager is free software: you can redistribute it and/or modify it under the terms of the
 *   GNU General Public License as published by the Free Software Foundation, either version 3 of the
 *   License, or (at your option) any later version.
 *
 *   textManager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *   without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 *   See the GNU General Public License for more details. You should have received a copy of the GNU
 *   General Public License along with textManager. If not, see <http://www.gnu.org/licenses/>.
 */
package me.philnate.textmanager.windows;

import static java.lang.String.format;
import static me.philnate.textmanager.utils.DB.pdf;
import static me.philnate.textmanager.utils.I18N.getCaption;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import me.philnate.textmanager.entities.Bill;
import me.philnate.textmanager.entities.BillingItem;
import me.philnate.textmanager.entities.Customer;
import me.philnate.textmanager.entities.Document;
import me.philnate.textmanager.entities.Setting;
import me.philnate.textmanager.utils.DB;
import me.philnate.textmanager.utils.FileDrop;
import me.philnate.textmanager.utils.GitRepositoryState;
import me.philnate.textmanager.utils.ImageRegistry;
import me.philnate.textmanager.utils.NotifyingThread;
import me.philnate.textmanager.utils.PDFCreator;
import me.philnate.textmanager.utils.ThreadCompleteListener;
import me.philnate.textmanager.windows.ImportWindow.ImportListener;
import me.philnate.textmanager.windows.components.BillingItemTable;
import me.philnate.textmanager.windows.components.CustomerComboBox;
import me.philnate.textmanager.windows.helper.DocXFileChooser;
import net.miginfocom.swing.MigLayout;

import org.apache.commons.lang.StringUtils;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mongodb.MongoException.DuplicateKey;
import com.toedter.calendar.JMonthChooser;
import com.toedter.calendar.JYearChooser;

public class MainWindow {
    private JFrame frame;
    private BillingItemTable billLines;
    private JScrollPane jScrollPane;
    private JMonthChooser monthChooser;
    private JYearChooser yearChooser;
    private ChangeListener changeListener;
    private List<BillingItem> curBill;
    private CustomerComboBox customers;
    private JTextField billNo;
    private Bill bill;
    private JButton build;
    private JButton view;
    private Thread runningThread;
    private JPanel statusBar;

    private static Logger LOG = LoggerFactory.getLogger(MainWindow.class);

    /**
     * on value change load different bill into table
     * 
     * @author philnate
     * 
     */
    private class ChangeListener implements PropertyChangeListener, ItemListener {

        @Override
        public void itemStateChanged(ItemEvent arg0) {
            fillTableModel();
        }

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            fillTableModel();
        }

    }

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    MainWindow window = new MainWindow();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the window.
     */
    public MainWindow() {
        initialize();
    }

    public void show() {
        frame.setVisible(true);
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        changeListener = new ChangeListener();

        frame = new JFrame();
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                Starter.shutdown();
            }
        });
        frame.setBounds(100, 100, 1197, 500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new MigLayout("", "[grow]", "[][grow][::16px]"));

        customers = new CustomerComboBox();
        customers.addItemListener(changeListener);

        frame.getContentPane().add(customers, "flowx,cell 0 0,growx");

        jScrollPane = new JScrollPane();
        billLines = new BillingItemTable(frame, true);

        jScrollPane.setViewportView(billLines);
        frame.getContentPane().add(jScrollPane, "cell 0 1,grow");

        // for each file added through drag&drop create a new lineItem
        new FileDrop(jScrollPane, new FileDrop.Listener() {

            @Override
            public void filesDropped(File[] files) {
                for (File file : files) {
                    addNewBillingItem(Document.loadAndSave(file));
                }
            }
        });

        monthChooser = new JMonthChooser();
        monthChooser.addPropertyChangeListener(changeListener);
        frame.getContentPane().add(monthChooser, "cell 0 0");

        yearChooser = new JYearChooser();
        yearChooser.addPropertyChangeListener(changeListener);
        frame.getContentPane().add(yearChooser, "cell 0 0");

        JButton btnAddLine = new JButton();
        btnAddLine.setIcon(ImageRegistry.getImage("load.gif"));
        btnAddLine.setToolTipText(getCaption("mw.tooltip.add"));
        btnAddLine.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                addNewBillingItem();
            }
        });

        frame.getContentPane().add(btnAddLine, "cell 0 0");

        JButton btnMassAdd = new JButton();
        btnMassAdd.setIcon(ImageRegistry.getImage("load_all.gif"));
        btnMassAdd.setToolTipText(getCaption("mw.tooltip.massAdd"));
        btnMassAdd.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                JFileChooser file = new DocXFileChooser();
                switch (file.showOpenDialog(frame)) {
                case JFileChooser.APPROVE_OPTION:
                    File[] files = file.getSelectedFiles();
                    if (null != files) {
                        for (File fl : files) {
                            addNewBillingItem(Document.loadAndSave(fl));
                        }
                    }
                    break;
                default:
                    return;
                }
            }
        });

        frame.getContentPane().add(btnMassAdd, "cell 0 0");

        billNo = new JTextField();
        // enable/disable build button based upon text in billNo
        billNo.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void removeUpdate(DocumentEvent arg0) {
                setButtonStates();
            }

            @Override
            public void insertUpdate(DocumentEvent arg0) {
                setButtonStates();
            }

            @Override
            public void changedUpdate(DocumentEvent arg0) {
                setButtonStates();
            }

            private void setButtonStates() {
                boolean notBlank = StringUtils.isNotBlank(billNo.getText());
                build.setEnabled(notBlank);
                view.setEnabled(pdf.find(billNo.getText() + ".pdf").size() == 1);
            }
        });
        frame.getContentPane().add(billNo, "cell 0 0");
        billNo.setColumns(10);

        build = new JButton();
        build.setEnabled(false);// disable build Button until there's some
        // billNo entered
        build.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (runningThread == null) {
                    try {
                        // check that billNo isn't empty or already used within
                        // another Bill
                        if (billNo.getText().trim().equals("")) {
                            JOptionPane.showMessageDialog(frame, getCaption("mw.dialog.error.billNoBlank.msg"),
                                    getCaption("mw.dialog.error.billNoBlank.title"), JOptionPane.ERROR_MESSAGE);
                            return;
                        }
                        try {
                            bill.setBillNo(billNo.getText()).save();
                        } catch (DuplicateKey e) {
                            // unset the internal value as this is already used
                            bill.setBillNo("");
                            JOptionPane.showMessageDialog(frame,
                                    format(getCaption("mw.error.billNoUsed.msg"), billNo.getText()),
                                    getCaption("mw.dialog.error.billNoBlank.title"), JOptionPane.ERROR_MESSAGE);
                            return;
                        }
                        PDFCreator pdf = new PDFCreator(bill);
                        pdf.addListener(new ThreadCompleteListener() {

                            @Override
                            public void threadCompleted(NotifyingThread notifyingThread) {
                                build.setToolTipText(getCaption("mw.tooltip.build"));
                                build.setIcon(ImageRegistry.getImage("build.png"));
                                runningThread = null;
                                view.setEnabled(DB.pdf.find(billNo.getText() + ".pdf").size() == 1);
                            }
                        });
                        runningThread = new Thread(pdf);
                        runningThread.start();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    build.setToolTipText(getCaption("mw.tooltip.build.cancel"));
                    build.setIcon(ImageRegistry.getImage("cancel.gif"));
                } else {
                    runningThread.interrupt();
                    runningThread = null;
                    build.setToolTipText(getCaption("mw.tooltip.build"));
                    build.setIcon(ImageRegistry.getImage("build.png"));

                }
            }
        });
        build.setToolTipText(getCaption("mw.tooltip.build"));
        build.setIcon(ImageRegistry.getImage("build.png"));
        frame.getContentPane().add(build, "cell 0 0");

        view = new JButton();
        view.setToolTipText(getCaption("mw.tooltip.view"));
        view.setIcon(ImageRegistry.getImage("view.gif"));
        view.setEnabled(false);
        view.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                File file = new File(System.getProperty("user.dir"),
                        format("template/%s.tmp.pdf", billNo.getText()));
                try {
                    pdf.findOne(billNo.getText() + ".pdf").writeTo(file);
                    new ProcessBuilder(Setting.find("pdfViewer").getValue(), file.getAbsolutePath()).start()
                            .waitFor();
                    file.delete();
                } catch (IOException | InterruptedException e1) {
                    // TODO Auto-generated catch block
                    LOG.warn("Error while building PDF", e1);
                }
            }
        });
        frame.getContentPane().add(view, "cell 0 0");

        statusBar = new JPanel();
        statusBar.setBorder(new BevelBorder(BevelBorder.LOWERED));
        statusBar.setLayout(new BoxLayout(statusBar, BoxLayout.X_AXIS));
        GitRepositoryState state = DB.state;
        JLabel statusLabel = new JLabel(String.format("textManager Version v%s build %s",
                state.getCommitIdDescribe(), state.getBuildTime()));
        statusLabel.setHorizontalAlignment(SwingConstants.LEFT);
        statusBar.add(statusLabel);
        frame.add(statusBar, "cell 0 2,growx");

        JMenuBar menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);

        JMenu menu = new JMenu(getCaption("mw.menu.edit"));
        JMenuItem itemCust = new JMenuItem(getCaption("mw.menu.edit.customer"));
        itemCust.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                new CustomerWindow(customers);
            }
        });
        menu.add(itemCust);

        JMenuItem itemSetting = new JMenuItem(getCaption("mw.menu.edit.settings"));
        itemSetting.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                new SettingWindow();
            }
        });
        menu.add(itemSetting);

        JMenuItem itemImport = new JMenuItem(getCaption("mw.menu.edit.import"));
        itemImport.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                new ImportWindow(new ImportListener() {

                    @Override
                    public void entriesImported(List<BillingItem> items) {
                        for (BillingItem item : items) {
                            item.setCustomerId(customers.getSelectedCustomer().getId())
                                    .setMonth(monthChooser.getMonth()).setYear(yearChooser.getYear());
                            item.save();
                            billLines.addRow(item);
                        }
                    }
                }, frame);
            }
        });
        menu.add(itemImport);

        menuBar.add(menu);

        customers.loadCustomer();
        fillTableModel();
    }

    /**
     * Creates a new BillingItem and returns it. BillingItem is initialized with
     * current selected customer, month and year.
     * 
     * @return BillingItem newly created BillingItem with basic Initialization
     */
    private BillingItem addNewBillingItem() {
        BillingItem item = new BillingItem().setCustomerId(customers.getSelectedCustomer().getId())
                .setMonth(monthChooser.getMonth()).setYear(yearChooser.getYear());
        billLines.addRow(item);
        item.save();
        return item;
    }

    private BillingItem addNewBillingItem(Document document) {
        BillingItem item = addNewBillingItem().addDocument(document);
        item.save();
        return item;
    }

    private void fillTableModel() {
        if (null == billLines) {
            return;
        }
        billLines.flushRows();
        Customer c = customers.getSelectedCustomer();
        if (null == c) {
            return;
        }
        curBill = BillingItem.find(c.getId(), yearChooser.getYear(), monthChooser.getMonth());
        for (BillingItem item : curBill) {
            billLines.addRow(item);
        }

        bill = checkBillExists(monthChooser.getMonth(), yearChooser.getYear(), c);
        billNo.setText(bill.getBillNo());
    }

    private Bill checkBillExists(int month, int year, Customer customer) {
        Bill bill = Bill.find(customer.getId(), year, month);
        if (bill == null) {
            Bill b = new Bill().setMonth(month).setYear(year).setCustomer(customer.getId()).setId(new ObjectId());
            b.save();
            return b;
        } else {
            return bill;
        }
    }
}