be.nbb.demetra.dfm.DfmExecViewTopComponent.java Source code

Java tutorial

Introduction

Here is the source code for be.nbb.demetra.dfm.DfmExecViewTopComponent.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 be.nbb.demetra.dfm;

import static be.nbb.demetra.dfm.DfmController.DFM_STATE_PROPERTY;
import be.nbb.demetra.dfm.DfmController.DfmState;
import ec.nbdemetra.ui.DemetraUI;
import ec.nbdemetra.ui.DemetraUiIcon;
import ec.nbdemetra.ui.NbComponents;
import ec.nbdemetra.ui.nodes.ExceptionNode;
import ec.nbdemetra.ui.notification.MessageType;
import ec.nbdemetra.ui.notification.NotifyUtil;
import ec.nbdemetra.ui.properties.OpenIdePropertySheetBeanEditor;
import ec.nbdemetra.ws.WorkspaceItem;
import ec.tss.dfm.DfmDocument;
import ec.tss.dfm.DfmProcessingFactory;
import ec.tss.dfm.VersionedDfmDocument;
import ec.tstoolkit.algorithm.CompositeResults;
import ec.tstoolkit.algorithm.IProcessingHook;
import ec.tstoolkit.algorithm.IProcessingNode;
import ec.tstoolkit.dfm.DfmEstimationSpec;
import ec.tstoolkit.dfm.DfmSpec;
import ec.util.chart.ColorScheme;
import ec.util.chart.swing.Charts;
import ec.util.chart.swing.SwingColorSchemeSupport;
import ec.util.various.swing.JCommand;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.SwingWorker;
import org.jfree.chart.ChartPanel;
import org.jfree.data.time.DynamicTimeSeriesCollection;
import org.jfree.data.time.Second;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.Cancellable;
import static org.openide.util.ImageUtilities.createDisabledIcon;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.TopComponent;

/**
 * Top component which displays something.
 */
@ConvertAsProperties(dtd = "-//be.nbb.demetra.dfm//DfmExecView//EN", autostore = false)
@TopComponent.Description(preferredID = "DfmExecViewTopComponent",
        //iconBase="SET/PATH/TO/ICON/HERE", 
        persistenceType = TopComponent.PERSISTENCE_NEVER)
@TopComponent.Registration(mode = "editor", openAtStartup = false)
@Messages({ "CTL_DfmExecViewAction=DfmExecView", "CTL_DfmExecViewTopComponent=DfmExecView Window",
        "HINT_DfmExecViewTopComponent=This is a DfmExecView window" })
public final class DfmExecViewTopComponent extends AbstractDfmDocumentTopComponent {

    private DynamicTimeSeriesCollection dataset;
    private ChartPanel sparkline;

    public DfmExecViewTopComponent() {
        this(null, new DfmController());
    }

    DfmExecViewTopComponent(WorkspaceItem<VersionedDfmDocument> document, DfmController controller) {
        super(document, controller);
        initComponents();
        setToolTipText(Bundle.HINT_DfmExecViewTopComponent());

        jEditorPane1.setEditable(false);

        dataset = new DynamicTimeSeriesCollection(1, 200, new Second());
        dataset.setTimeBase(new Second());
        dataset.addSeries(new float[] {}, 0, "loglikelihood");
    }

    /**
     * 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() {

        jScrollPane1 = NbComponents.newJScrollPane();
        jEditorPane1 = new javax.swing.JEditorPane();

        setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.LINE_AXIS));

        jScrollPane1.setViewportView(jEditorPane1);

        add(jScrollPane1);
    }// </editor-fold>//GEN-END:initComponents

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JEditorPane jEditorPane1;
    private javax.swing.JScrollPane jScrollPane1;

    // End of variables declaration//GEN-END:variables
    void writeProperties(java.util.Properties p) {
    }

    void readProperties(java.util.Properties p) {
    }

    @Override
    public JComponent getToolbarRepresentation() {
        JToolBar toolBar = NbComponents.newInnerToolbar();
        toolBar.addSeparator();
        toolBar.add(Box.createRigidArea(new Dimension(5, 0)));

        JToggleButton startStop = (JToggleButton) toolBar
                .add(new JToggleButton(StartStopCommand.INSTANCE.toAction(this)));
        startStop.setIcon(DemetraUiIcon.COMPILE_16);
        startStop.setDisabledIcon(createDisabledIcon(startStop.getIcon()));
        startStop.setToolTipText("Start/Stop");

        JButton edit = toolBar.add(EditSpecCommand.INSTANCE.toAction(this));
        edit.setIcon(DemetraUiIcon.PREFERENCES);
        edit.setDisabledIcon(createDisabledIcon(edit.getIcon()));
        edit.setToolTipText("Specification");

        JButton clear = toolBar.add(ClearCommand.INSTANCE.toAction(this));
        clear.setIcon(DemetraUiIcon.EDIT_CLEAR_16);
        clear.setDisabledIcon(createDisabledIcon(clear.getIcon()));
        clear.setToolTipText("Clear");

        SwingColorSchemeSupport colorSchemeSupport = SwingColorSchemeSupport
                .from(DemetraUI.getInstance().getColorScheme());
        sparkline = (ChartPanel) toolBar
                .add(Charts.avoidScaling(new ChartPanel(Charts.createSparkLineChart(null))));
        sparkline.setPreferredSize(new Dimension(150, 16));
        sparkline.setMaximumSize(new Dimension(150, 16));
        sparkline.getChart().getXYPlot().setDataset(dataset);
        sparkline.getChart().getXYPlot().getRenderer()
                .setBasePaint(colorSchemeSupport.getLineColor(ColorScheme.KnownColor.GREEN));
        sparkline.setBackground(colorSchemeSupport.getPlotColor());
        sparkline.setBorder(BorderFactory.createLineBorder(colorSchemeSupport.getGridColor()));
        sparkline.setToolTipText("loglikelihood");

        return toolBar;
    }

    //</editor-fold>
    private void appendText(String text) {
        jEditorPane1.setText(jEditorPane1.getText() + text);
    }

    private ProgressHandle progressHandle;
    private SwingWorkerImpl swingWorker;

    @Override
    protected void onDfmStateChange() {
        switch (controller.getDfmState()) {
        case CANCELLED:
            appendText("\nCANCELLED");
            progressHandle.finish();
            break;
        case DONE:
            appendText("\nDONE");
            if (progressHandle != null) {
                progressHandle.finish();
            }
            break;
        case FAILED:
            appendText("\nFAILED");
            if (progressHandle != null) {
                progressHandle.finish();
            }
            break;
        case READY:
            jEditorPane1.setText("");
            break;
        case STARTED:
            swingWorker = new SwingWorkerImpl();
            progressHandle = ProgressHandleFactory.createHandle(getName(), new Cancellable() {
                @Override
                public boolean cancel() {
                    swingWorker.cancel(false);
                    return true;
                }
            }, new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    DfmExecViewTopComponent.this.open();
                    DfmExecViewTopComponent.this.requestActive();
                }
            });
            progressHandle.start();
            swingWorker.execute();
            break;
        case CANCELLING:
            swingWorker.cancel(false);
            break;
        }
        super.onDfmStateChange();
    }

    private void reportException(Exception ex) {
        new ExceptionNode(ex).getPreferredAction().actionPerformed(null);
    }

    private final class SwingWorkerImpl extends
            SwingWorker<CompositeResults, IProcessingHook.HookInformation<IProcessingNode, DfmProcessingFactory.EstimationInfo>>
            implements IProcessingHook<IProcessingNode, DfmProcessingFactory.EstimationInfo> {

        @Override
        protected CompositeResults doInBackground() throws Exception {
            DfmProcessingFactory processor = (DfmProcessingFactory) getDocument().getElement().getCurrent()
                    .getProcessor();
            try {
                processor.register(this);
                CompositeResults rslt = getDocument().getElement().getCurrent().getResults();
                return rslt;
            } finally {
                processor.unregister(this);
            }
        }

        @Override
        protected void done() {
            if (isCancelled()) {
                NotifyUtil.show("Cancelled !", "Processing has been cancelled", MessageType.WARNING, null, null,
                        null);
                controller.setDfmState(DfmState.CANCELLED);
            } else {
                try {
                    CompositeResults results = get();
                    NotifyUtil.show("Done !", "Processing has completed successfuly", MessageType.SUCCESS, null,
                            createChartImage(), null);
                    controller.setDfmState(DfmState.DONE);
                } catch (InterruptedException | ExecutionException ex) {
                    if (ex instanceof ExecutionException) {
                        if (ex.getCause() != null && ex.getCause() instanceof Exception) {
                            reportException((Exception) ex.getCause());
                        } else {
                            reportException(ex);
                        }
                    } else {
                        reportException(ex);
                    }
                    controller.setDfmState(DfmState.FAILED);
                }
            }
        }

        @Override
        public void process(HookInformation<IProcessingNode, DfmProcessingFactory.EstimationInfo> info,
                boolean cancancel) {
            if (isCancelled()) {
                info.cancel = true;
            }
            publish(info);
        }

        @Override
        protected void process(List<HookInformation<IProcessingNode, DfmProcessingFactory.EstimationInfo>> chunks) {
            for (HookInformation<IProcessingNode, DfmProcessingFactory.EstimationInfo> info : chunks) {
                progressHandle.progress(info.message);
                StringBuilder txt = new StringBuilder();
                txt.append(info.source.getName()).append('\t').append(info.message).append('\t')
                        .append(info.information.loglikelihood);
                txt.append("\r\n");
                appendText(txt.toString());

                dataset.advanceTime();
                dataset.appendData(new float[] { (float) info.information.loglikelihood });
            }
        }

        private JLabel createChartImage() {
            return new JLabel(new ImageIcon(sparkline.getChart().createBufferedImage(150, 16)));
        }
    }

    //<editor-fold defaultstate="collapsed" desc="Commands">
    private static abstract class DfmExecCommand extends JCommand<DfmExecViewTopComponent> {

        @Override
        public JCommand.ActionAdapter toAction(DfmExecViewTopComponent c) {
            return super.toAction(c).withWeakPropertyChangeListener(c, DFM_STATE_PROPERTY);
        }
    }

    private static final class StartStopCommand extends DfmExecCommand {

        public static final StartStopCommand INSTANCE = new StartStopCommand();

        @Override
        public void execute(DfmExecViewTopComponent c) throws Exception {
            if (c.controller.getDfmState() == DfmState.STARTED) {
                c.controller.setDfmState(DfmState.CANCELLING);
            } else {
                c.controller.setDfmState(DfmState.STARTED);
            }
        }

        @Override
        public boolean isEnabled(DfmExecViewTopComponent c) {
            return c.controller.getDfmState() != DfmState.CANCELLING;
        }

        @Override
        public boolean isSelected(DfmExecViewTopComponent c) {
            return c.controller.getDfmState() == DfmState.STARTED;
        }
    }

    private static final class EditSpecCommand extends DfmExecCommand {

        public static final EditSpecCommand INSTANCE = new EditSpecCommand();

        @Override
        public void execute(DfmExecViewTopComponent c) throws Exception {
            DfmDocument doc = c.getDocument().getElement().getCurrent();
            DfmSpec spec = doc.getSpecification();
            DfmEstimationSpec newValue = spec.getEstimationSpec().clone();
            if (OpenIdePropertySheetBeanEditor.editSheet(DfmSheets.onDfmEstimationSpec(newValue), "Edit spec",
                    null)) {
                doc.forceSpecification(newValue);
            }
        }

        @Override
        public boolean isEnabled(DfmExecViewTopComponent c) {
            return c.controller.getDfmState() != DfmState.STARTED
                    && c.controller.getDfmState() != DfmState.CANCELLING;
        }
    }

    private static final class ClearCommand extends DfmExecCommand {

        public static final ClearCommand INSTANCE = new ClearCommand();

        @Override
        public void execute(DfmExecViewTopComponent c) throws Exception {
            DfmDocument current = c.getDocument().getElement().getCurrent();
            DfmSpec spec = current.getSpecification();
            if (spec.getModelSpec().isSpecified()) {
                NotifyDescriptor nd = new NotifyDescriptor.Confirmation(CLEAR_MESSAGE,
                        NotifyDescriptor.OK_CANCEL_OPTION);
                if (DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.OK_OPTION) {
                    current.forceFullComputation();
                    c.controller.setDfmState(DfmState.READY);
                }
            }
        }

        @Override
        public boolean isEnabled(DfmExecViewTopComponent c) {
            return c.controller.getDfmState().isFinished();
        }
    }

    //</editor-fold>
    public static final String CLEAR_MESSAGE = "The model has already been computed. Are you sure you want to clear the results?";
}