jimaginary.machine.set.viewer.SetViewerTopComponent.java Source code

Java tutorial

Introduction

Here is the source code for jimaginary.machine.set.viewer.SetViewerTopComponent.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jimaginary.machine.set.viewer;

import com.digithree.codecs.midi.MidiCodec;
import com.digithree.codecs.midi.MidiPlayer;
import com.jimaginary.machine.api.Set;
import com.jimaginary.machine.api.SetData;
import java.awt.BorderLayout;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import javax.sound.midi.MidiSystem;
import jimaginary.machine.set.selector.SetItem;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYTextAnnotation;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.netbeans.api.settings.ConvertAsProperties;
import org.netbeans.spi.actions.AbstractSavable;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.StatusDisplayer;
import org.openide.filesystems.FileChooserBuilder;
import org.openide.util.Lookup;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;
import org.openide.windows.TopComponent;
import org.openide.util.NbBundle.Messages;
import org.openide.util.Utilities;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;

/**
 * Top component which displays something.
 */
@ConvertAsProperties(dtd = "-//jimaginary.machine.set.viewer//SetViewer//EN", autostore = false)
@TopComponent.Description(preferredID = "SetViewerTopComponent",
        //iconBase="SET/PATH/TO/ICON/HERE", 
        persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "output", openAtStartup = false)
@ActionID(category = "Window", id = "jimaginary.machine.set.viewer.SetViewerTopComponent")
@ActionReference(path = "Menu/Window" /*, position = 333 */)
@TopComponent.OpenActionRegistration(displayName = "#CTL_SetViewerAction", preferredID = "SetViewerTopComponent")
@Messages({ "CTL_SetViewerAction=SetViewer", "CTL_SetViewerTopComponent=SetViewer Window",
        "HINT_SetViewerTopComponent=This is a SetViewer window" })
public final class SetViewerTopComponent extends TopComponent implements LookupListener {

    private InstanceContent instanceContent = new InstanceContent();

    private Lookup.Result<SetItem> result = null;
    ChartPanel chartPanel;

    public SetViewerTopComponent() {
        initComponents();
        setName(Bundle.CTL_SetViewerTopComponent());
        setToolTipText(Bundle.HINT_SetViewerTopComponent());
        associateLookup(new AbstractLookup(instanceContent));
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanelChart = new javax.swing.JPanel();

        javax.swing.GroupLayout jPanelChartLayout = new javax.swing.GroupLayout(jPanelChart);
        jPanelChart.setLayout(jPanelChartLayout);
        jPanelChartLayout.setHorizontalGroup(jPanelChartLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 388, Short.MAX_VALUE));
        jPanelChartLayout.setVerticalGroup(jPanelChartLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 288, Short.MAX_VALUE));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup().addContainerGap().addComponent(jPanelChart,
                        javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addContainerGap()));
        layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup().addContainerGap().addComponent(jPanelChart,
                        javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addContainerGap()));
    }// </editor-fold>//GEN-END:initComponents

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel jPanelChart;

    // End of variables declaration//GEN-END:variables
    @Override
    public void componentOpened() {
        result = Utilities.actionsGlobalContext().lookupResult(SetItem.class);
        result.addLookupListener(this);
    }

    @Override
    public void componentClosed() {
        result.removeLookupListener(this);
    }

    void writeProperties(java.util.Properties p) {
        // better to version settings since initial version as advocated at
        // http://wiki.apidesign.org/wiki/PropertyFiles
        p.setProperty("version", "1.0");
        // TODO store your settings
    }

    void readProperties(java.util.Properties p) {
        String version = p.getProperty("version");
        // TODO read your settings according to their version
    }

    @Override
    public void resultChanged(LookupEvent le) {
        System.out.println("SetViewerTopComponent:resultChanged(lookup)");
        Collection<? extends SetItem> allItems = result.allInstances();
        if (!allItems.isEmpty()) {
            SetItem setItem = allItems.iterator().next();
            // TODO : don't just use midi, might be wav data
            createMidiChart(SetData.getInstance().getSetByName(setItem.getName()));
            //if( getLookup().lookup(SetSavable.class) == null) {
            instanceContent.add(new SetSavable(setItem.getName()));
            //}
        }
    }

    private void createMidiChart(Set set) {
        if (set == null) {
            return;
        }
        XYSeries series = new XYSeries("Distrbution");
        float setValues[] = set.getValues();
        for (int i = 0; i < setValues.length; i++) {
            if ((int) setValues[i] != 0) {
                series.add(i, (int) setValues[i]);
            }
        }
        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series);

        // Generate the graph
        JFreeChart chart = ChartFactory.createScatterPlot(set.getName(), "Position", "Note", dataset,
                PlotOrientation.VERTICAL, // Plot Orientation
                true, // Show Legend
                true, // Use tooltips
                false // Configure chart to generate URLs?
        );
        // add annotations if we have them
        XYPlot plot = chart.getXYPlot();
        for (int i = 0; i < setValues.length; i++) {
            XYTextAnnotation an = new XYTextAnnotation(MidiCodec.noteValToString((int) setValues[i]), i,
                    (int) setValues[i]);
            plot.addAnnotation(an);
        }

        if (chartPanel != null) {
            jPanelChart.remove(chartPanel);
        }
        chartPanel = new ChartPanel(chart);
        jPanelChart.setLayout(new java.awt.BorderLayout());
        jPanelChart.add(chartPanel, BorderLayout.CENTER);
        jPanelChart.validate();
    }

    //private static final Icon ICON = ImageUtilities.loadImageIcon("save.png", false);

    private class SetSavable extends AbstractSavable { //implements Icon 
        private final String name;

        SetSavable(String name) {
            this.name = name;
            register();
        }

        @Override
        protected String findDisplayName() {
            return name;
        }

        @Override
        protected void handleSave() throws IOException {
            tc().instanceContent.remove(this);
            unregister();
            // do save
            System.out.println("SetItem:save for " + name);
            Set set = SetData.getInstance().getSetByName(name);

            if (set != null) {
                /*
                FileSystem f = Repository.getDefault().getDefaultFileSystem();
                FileObject o = f.getRoot().getFileObject(name);
                */
                //The default dir to use if no value is stored
                File home = new File(System.getProperty("user.home"));
                //Now build a file chooser and invoke the dialog in one line of code
                //"libraries-dir" is our unique key
                File newFile = new FileChooserBuilder(SetItem.class).setTitle("Save " + name)
                        .setDefaultWorkingDirectory(home).setApproveText("Save").showSaveDialog();
                //Result will be null if the user clicked cancel or closed the dialog w/o OK
                if (newFile == null) {
                    System.out.println("new file is null");
                    StatusDisplayer.getDefault().setStatusText("Couldn't write file!");
                    return;
                }

                MidiPlayer midiPlayer = new MidiPlayer(set.getLen(), false);
                midiPlayer.addTrack(set);
                System.out.println("Trying to save file " + newFile.getPath());
                try {
                    int numBytes = MidiSystem.write(midiPlayer.getSequence(), 1, newFile);
                    //MidiSystem.write(midiPlayer.getSequence(),1,file);
                    if (numBytes > 0) {
                        System.out.println("Wrote " + numBytes + " bytes to " + newFile.getPath());
                        StatusDisplayer.getDefault().setStatusText("Saved file " + newFile.getPath());
                    } else {
                        System.out.println("Couldn't write file " + newFile.getPath());
                        StatusDisplayer.getDefault().setStatusText("Couldn't write file!");
                    }
                } catch (IOException e) {
                    System.out.println("Error writing midi sequence to file: " + e.toString());
                    StatusDisplayer.getDefault().setStatusText("Couldn't write file!");
                }
            }
        }

        SetViewerTopComponent tc() {
            return SetViewerTopComponent.this;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof SetSavable) {
                SetSavable m = (SetSavable) obj;
                return tc() == m.tc();
            }
            return false;
        }

        @Override
        public int hashCode() {
            return tc().hashCode();
        }

        /*
        @Override
        public void paintIcon(Component c, Graphics g, int x, int y) {
        ICON.paintIcon(c, g, x, y);
        }
            
        @Override
        public int getIconWidth() {
        return ICON.getIconWidth();
        }
            
        @Override
        public int getIconHeight() {
        return ICON.getIconHeight();
        }
        */
    }
}