org.pmedv.blackboard.dialogs.PartDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.pmedv.blackboard.dialogs.PartDialog.java

Source

/**
    
   BlackBoard breadboard designer
   Written and maintained by Matthias Pueski 
       
   Copyright (c) 2010-2011 Matthias Pueski
       
   This program 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 2
   of the License, or (at your option) any later version.
       
   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    
 */
package org.pmedv.blackboard.dialogs;

import static org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
import javax.swing.ListSelectionModel;
import javax.swing.SwingWorker;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.divxdede.swing.busy.JBusyComponent;
import org.fife.ui.autocomplete.AutoCompletion;
import org.fife.ui.autocomplete.BasicCompletion;
import org.fife.ui.autocomplete.CompletionProvider;
import org.fife.ui.autocomplete.DefaultCompletionProvider;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.jdesktop.beansbinding.BeanProperty;
import org.jdesktop.beansbinding.BindingGroup;
import org.jdesktop.beansbinding.Bindings;
import org.jdesktop.swingx.JXTable;
import org.pmedv.blackboard.commands.CreatePartCommand;
import org.pmedv.blackboard.commands.DeletePartCommand;
import org.pmedv.blackboard.components.Part;
import org.pmedv.blackboard.filter.PartFilter;
import org.pmedv.blackboard.models.PartTableModel;
import org.pmedv.blackboard.panels.PartPanel;
import org.pmedv.blackboard.tools.PartFactory;
import org.pmedv.core.context.AppContext;
import org.pmedv.core.dialogs.AbstractNiceDialog;
import org.pmedv.core.gui.ApplicationWindow;
import org.pmedv.core.services.ResourceService;
import org.pmedv.core.util.ErrorUtils;
import org.pmedv.core.util.FileUtils;

/**
 * This is the main part browser dialog, it displays a filterable list on the left side
 * as well as a part preview and the part details on the right side.
 * 
 * @author Matthias Pueski (13.01.2011)
 *
 */
public class PartDialog extends AbstractNiceDialog {

    private static final long serialVersionUID = 1429247746599672970L;

    private static final String title = resources.getResourceByKey("PartDialog.title");
    private static final String subTitle = resources.getResourceByKey("PartDialog.subtitle");
    private static final String editTitle = resources.getResourceByKey("PartDialog.edittitle");
    private static final String editSubTitle = resources.getResourceByKey("PartDialog.editsubtitle");

    private static final ResourceService resourceService = ctx.getBean(ResourceService.class);

    private PartPanel partPanel;
    private ArrayList<Part> selectedParts;
    private PartTableModel model;

    private static ImageIcon icon = resourceService.getIcon("icon.dialog.part");
    private static final Log log = LogFactory.getLog(PartDialog.class);
    private JBusyComponent<PartPanel> partBusyPanel;

    private Part currentPart = null;
    private int selectedRow;

    private RSyntaxTextArea textArea;
    private JTabbedPane tabbedPane;

    private JPopupMenu tablePopupMenu;

    public PartDialog() {
        super(title, subTitle, icon, true, true, true, true,
                AppContext.getContext().getBean(ApplicationWindow.class), null);
    }

    @Override
    protected void initializeComponents() {

        partPanel = new PartPanel();
        partBusyPanel = new JBusyComponent<PartPanel>(partPanel);

        setSize(new Dimension(900, 750));

        textArea = new RSyntaxTextArea();
        textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML);
        RTextScrollPane textScrollPane = new RTextScrollPane(textArea);

        CompletionProvider provider = createCompletionProvider();
        AutoCompletion ac = new AutoCompletion(provider);
        ac.install(textArea);

        JPopupMenu popup = textArea.getPopupMenu();
        popup.addSeparator();
        popup.add(new JMenuItem(new SaveAction()));

        tabbedPane = new JTabbedPane(JTabbedPane.BOTTOM);
        tabbedPane.addTab("Parts", partBusyPanel);
        tabbedPane.addTab("Part Editor", textScrollPane);
        tabbedPane.setEnabledAt(1, false);
        getContentPanel().add(tabbedPane);

        tablePopupMenu = new JPopupMenu();

        // We do the part loading in background and display a busy panel while loading

        SwingWorker<ArrayList<Part>, Void> w = new SwingWorker<ArrayList<Part>, Void>() {

            @Override
            protected ArrayList<Part> doInBackground() {
                partBusyPanel.setBusy(true);
                try {
                    return AppContext.getContext().getBean(PartFactory.class).getAvailableParts();
                } catch (Exception e) {
                    ErrorUtils.showErrorDialog(e);
                    return new ArrayList<Part>();
                }
            }

            @Override
            protected void done() {
                log.info("Done loading parts.");
                try {
                    model = new PartTableModel(get());
                    partPanel.getPartTable().setModel(model);
                } catch (Exception e) {
                    ErrorUtils.showErrorDialog(e);
                }
                partBusyPanel.setBusy(false);
                partPanel.transferFocus();
            }
        };

        getOkButton().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JXTable table = partPanel.getPartTable();
                result = OPTION_OK;
                selectedParts = new ArrayList<Part>();
                int rows[] = partPanel.getPartTable().getSelectedRows();
                try {
                    for (int i = 0; i < rows.length; i++) {
                        selectedParts.add(AppContext.getContext().getBean(PartFactory.class).createPart(
                                model.getParts().get(table.convertRowIndexToModel(rows[i])).getFilename()));
                    }
                } catch (Exception e1) {
                    ErrorUtils.showErrorDialog(e1);
                }
                setVisible(false);
            }
        });

        getCancelButton().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                result = OPTION_CANCEL;
                setVisible(false);
            }
        });

        getNewButton().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                AppContext.getContext().getBean(CreatePartCommand.class).execute(e);
            }
        });

        partPanel.getPartTable().getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                JXTable table = partPanel.getPartTable();
                int[] rows = table.getSelectedRows();
                if (rows.length == 1) {
                    if (model == null)
                        return;
                    Part selectedPart = model.getParts().get(table.convertRowIndexToModel(rows[0]));
                    currentPart = selectedPart;
                    selectedRow = table.convertRowIndexToModel(rows[0]);
                    partPanel.getImageLabel().setIcon(new ImageIcon(selectedPart.getImage()));
                    partPanel.getImageLabel().setText(null);
                    partPanel.getPartNameField().setText(selectedPart.getName());
                    partPanel.getDescriptionPane().setText(selectedPart.getDescription());
                    partPanel.getPackageTypeField().setText(selectedPart.getPackageType());
                    partPanel.getAuthorField().setText(selectedPart.getAuthor());
                    partPanel.getLicenseField().setText(selectedPart.getLicense());
                    tabbedPane.setEnabledAt(1, true);
                    textArea.setText(selectedPart.getXmlContent());
                } else {
                    currentPart = null;
                    partPanel.getImageLabel().setText(resources.getResourceByKey("PartDialog.selectmsg"));
                    partPanel.getImageLabel().setIcon(null);
                    tabbedPane.setEnabledAt(1, false);
                    textArea.setText("");
                }
            }
        });

        tabbedPane.addChangeListener(new ChangeListener() {
            // This method is called whenever the selected tab changes
            public void stateChanged(ChangeEvent evt) {
                JTabbedPane pane = (JTabbedPane) evt.getSource();
                int index = pane.getSelectedIndex();
                if (index == 0) {
                    getTitleLabel().setText(title);
                    getSubTitleLabel().setText(subTitle);
                } else {
                    getTitleLabel().setText(editTitle);
                    getSubTitleLabel().setText(editSubTitle + " : " + currentPart.getName());
                }
            }
        });

        partPanel.getPartTable().addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                handlePopupTrigger(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                handlePopupTrigger(e);
            }
        });

        tablePopupMenu.add(ctx.getBean(DeletePartCommand.class));

        // this is the filter configuration for the filter text box on the top
        PartFilter filter = new PartFilter(partPanel.getPartTable());
        BindingGroup filterGroup = new BindingGroup();
        // bind filter JTextBox's text attribute to part tables filterString
        // attribute
        filterGroup.addBinding(Bindings.createAutoBinding(READ, partPanel.getFilterPanel().getFilterTextField(),
                BeanProperty.create("text"), filter, BeanProperty.create("filterString")));
        filterGroup.bind();
        w.execute();

    }

    private void handlePopupTrigger(MouseEvent e) {
        if (e.isPopupTrigger() && model.getParts().size() >= 1) {
            Point p = e.getPoint();
            // get the row index that contains that coordinate
            int rowNumber = partPanel.getPartTable().rowAtPoint(p);
            // Get the ListSelectionModel of the JTable
            ListSelectionModel model = partPanel.getPartTable().getSelectionModel();
            // set the selected interval of rows. Using the "rowNumber"
            // variable for the beginning and end selects only that one row.
            model.setSelectionInterval(rowNumber, rowNumber);
            tablePopupMenu.show(e.getComponent(), e.getX(), e.getY());
        }
    }

    /**
     * @return the selectedParts
     */
    public ArrayList<Part> getSelectedParts() {
        return selectedParts;
    }

    /**
     * @return the model
     */
    public PartTableModel getModel() {
        return model;
    }

    private class SaveAction extends AbstractAction {

        public SaveAction() {
            putValue(Action.NAME, resources.getResourceByKey("msg.save"));
        }

        @Override
        public void actionPerformed(ActionEvent e) {

            JXTable table = partPanel.getPartTable();
            int[] rows = table.getSelectedRows();
            if (rows.length == 1) {
                if (model == null)
                    return;
                int index = table.convertRowIndexToModel(rows[0]);
                Part selectedPart = model.getParts().get(index);
                String content = textArea.getText();
                String name = selectedPart.getFilename();
                File workDir = new File(System.getProperty("user.home"), "." + AppContext.getName());
                File partDir = new File(workDir + "/parts/");
                File partFile = new File(partDir, name);
                FileUtils.writeFile(partFile, content);
                try {
                    model.getParts().set(index,
                            AppContext.getContext().getBean(PartFactory.class).createPart(name));
                } catch (Exception e1) {
                    ErrorUtils.showErrorDialog(e1);
                }
            }
        }

    }

    @Override
    public void setVisible(boolean b) {
        super.setVisible(b);
        tabbedPane.setSelectedIndex(0);
    }

    private CompletionProvider createCompletionProvider() {

        DefaultCompletionProvider provider = new DefaultCompletionProvider();

        provider.addCompletion(new BasicCompletion(provider, "<part></part>"));
        provider.addCompletion(new BasicCompletion(provider, "<author></author>"));
        provider.addCompletion(new BasicCompletion(provider, "<license></license>"));
        provider.addCompletion(new BasicCompletion(provider, "<width></width>"));
        provider.addCompletion(new BasicCompletion(provider, "<height></height>"));
        provider.addCompletion(new BasicCompletion(provider, "<xLoc></xLoc>"));
        provider.addCompletion(new BasicCompletion(provider, "<yLoc></yLoc>"));
        provider.addCompletion(new BasicCompletion(provider, "<name></name>"));
        provider.addCompletion(new BasicCompletion(provider, "<imageName></imageName>"));
        provider.addCompletion(new BasicCompletion(provider, "<description></description>"));
        provider.addCompletion(new BasicCompletion(provider, "<packageType></packageType>"));
        provider.addCompletion(new BasicCompletion(provider, "<rotation></rotation>"));
        provider.addCompletion(new BasicCompletion(provider, "<designator></designator>"));
        provider.addCompletion(new BasicCompletion(provider, "<connections></connections>"));
        provider.addCompletion(new BasicCompletion(provider, "<pin></pin>"));
        provider.addCompletion(new BasicCompletion(provider, "<num></num>"));

        return provider;

    }

    /**
     * @return the currentPart
     */
    public Part getCurrentPart() {
        return currentPart;
    }

    /**
     * @return the selectedRow
     */
    public int getSelectedRow() {
        return selectedRow;
    }

}