de.fub.maps.project.detector.model.inference.ui.EvaluationPanel.java Source code

Java tutorial

Introduction

Here is the source code for de.fub.maps.project.detector.model.inference.ui.EvaluationPanel.java

Source

/*
 * Copyright 2013 Serdar.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.fub.maps.project.detector.model.inference.ui;

import de.fub.maps.project.detector.model.inference.EvaluationDetailPanel;
import de.fub.maps.project.detector.model.inference.processhandler.InferenceModelProcessHandler;
import de.fub.maps.project.detector.model.inference.ui.charts.PrecisionRecallBarChartPanel;
import de.fub.utilsmodule.components.CustomOutlineView;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
import java.util.List;
import javax.swing.JLabel;
import org.jfree.data.category.DefaultCategoryDataset;
import org.netbeans.swing.outline.Outline;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.view.OutlineView;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.PropertySupport;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import weka.classifiers.Evaluation;
import weka.core.Instances;

/**
 *
 * @author Serdar
 */
@NbBundle.Messages({ "CLT_TransportMode_Label_Text=Transport Mode" })
public class EvaluationPanel extends javax.swing.JPanel implements ExplorerManager.Provider {

    private static final String NUMBER_PATTERN = "{0, number, 000.00} %";
    private static final long serialVersionUID = 1L;
    private transient final ExplorerManager explorerManager = new ExplorerManager();
    private transient Evaluation evaluation;
    private transient InferenceModelProcessHandler processHandler;

    /**
     * Creates new form EvaluationPanel
     */
    public EvaluationPanel() {
        initComponents();
        outlineView.getActionMap().clear();
        Outline outline = outlineView.getOutline();
        outline.getActionMap().clear();
        outline.setRootVisible(false);
    }

    public EvaluationPanel(InferenceModelProcessHandler processHandler) {
        this();
        this.processHandler = processHandler;
    }

    public PrecisionRecallBarChartPanel getBarChartPanel() {
        return barChartPanel;
    }

    public OutlineView getOutlineView() {
        return outlineView;
    }

    public JLabel getTitle() {
        return title;
    }

    public JLabel getCorrectClassifiedInstances() {
        return correctClassifiedInstances;
    }

    public JLabel getIncorrectClassifiedInstances() {
        return incorrectClassifiedInstances;
    }

    /**
     * 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.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel2 = new javax.swing.JPanel();
        jPanel6 = new javax.swing.JPanel();
        barChartPanel = new de.fub.maps.project.detector.model.inference.ui.charts.PrecisionRecallBarChartPanel();
        outlineView = new CustomOutlineView(NbBundle.getMessage(EvaluationPanel.class, "CLT_Doman_Axis_Name"));
        jPanel3 = new javax.swing.JPanel();
        title = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        jPanel4 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        correctClassifiedInstances = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        incorrectClassifiedInstances = new javax.swing.JLabel();
        jPanel5 = new javax.swing.JPanel();
        toolBar = new javax.swing.JToolBar();
        filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0),
                new java.awt.Dimension(32767, 0));
        infoButton = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JSeparator();
        jSeparator2 = new javax.swing.JSeparator();

        setBackground(new java.awt.Color(255, 255, 255));
        setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(102, 102, 102), 2));
        setMaximumSize(new java.awt.Dimension(2147483647, 350));
        setMinimumSize(new java.awt.Dimension(0, 300));
        setPreferredSize(new java.awt.Dimension(0, 300));
        setLayout(new java.awt.BorderLayout(0, 8));

        jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 4, 8, 4));
        jPanel2.setMinimumSize(new java.awt.Dimension(0, 32));
        jPanel2.setOpaque(false);
        jPanel2.setPreferredSize(new java.awt.Dimension(0, 429));

        jPanel6.setMinimumSize(new java.awt.Dimension(0, 10));
        jPanel6.setPreferredSize(new java.awt.Dimension(0, 420));
        jPanel6.setLayout(new java.awt.BorderLayout());

        barChartPanel.setPreferredSize(new java.awt.Dimension(0, 420));
        jPanel6.add(barChartPanel, java.awt.BorderLayout.CENTER);

        outlineView.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(213, 213, 213)));
        outlineView.setPropertyColumns(new String[] { "precision", "Precision", "recall", "Recall" });
        outlineView.setWheelScrollingEnabled(false);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout
                .setHorizontalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel2Layout.createSequentialGroup()
                                .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, 657, Short.MAX_VALUE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(outlineView, javax.swing.GroupLayout.PREFERRED_SIZE, 281,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addContainerGap()));
        jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, 210,
                        javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(outlineView, javax.swing.GroupLayout.PREFERRED_SIZE, 210,
                        javax.swing.GroupLayout.PREFERRED_SIZE));

        add(jPanel2, java.awt.BorderLayout.CENTER);

        jPanel3.setBackground(new java.awt.Color(255, 216, 178));
        jPanel3.setBorder(
                javax.swing.BorderFactory.createMatteBorder(0, 0, 2, 0, new java.awt.Color(204, 204, 204)));
        jPanel3.setMinimumSize(new java.awt.Dimension(0, 32));
        jPanel3.setPreferredSize(new java.awt.Dimension(0, 32));
        jPanel3.setLayout(new java.awt.BorderLayout());

        title.setFont(new java.awt.Font("Tahoma", 1, 24)); // NOI18N
        title.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        org.openide.awt.Mnemonics.setLocalizedText(title,
                org.openide.util.NbBundle.getMessage(EvaluationPanel.class, "EvaluationPanel.title.text")); // NOI18N
        title.setPreferredSize(new java.awt.Dimension(0, 29));
        jPanel3.add(title, java.awt.BorderLayout.CENTER);

        add(jPanel3, java.awt.BorderLayout.NORTH);

        jPanel1.setBackground(new java.awt.Color(204, 204, 204));
        jPanel1.setBorder(
                javax.swing.BorderFactory.createMatteBorder(2, 0, 0, 0, new java.awt.Color(204, 204, 204)));
        jPanel1.setMaximumSize(new java.awt.Dimension(32767, 32));
        jPanel1.setMinimumSize(new java.awt.Dimension(10, 32));
        jPanel1.setPreferredSize(new java.awt.Dimension(10, 32));
        jPanel1.setLayout(new java.awt.BorderLayout());

        jPanel4.setBackground(new java.awt.Color(255, 216, 178));
        jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 8, 1, 8));
        jPanel4.setPreferredSize(new java.awt.Dimension(0, 41));

        jLabel1.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(jLabel1,
                org.openide.util.NbBundle.getMessage(EvaluationPanel.class, "EvaluationPanel.jLabel1.text")); // NOI18N

        correctClassifiedInstances.setFont(new java.awt.Font("Monospaced", 0, 11)); // NOI18N
        correctClassifiedInstances.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        org.openide.awt.Mnemonics.setLocalizedText(correctClassifiedInstances, org.openide.util.NbBundle
                .getMessage(EvaluationPanel.class, "EvaluationPanel.correctClassifiedInstances.text")); // NOI18N
        correctClassifiedInstances.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 8));

        jLabel2.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(jLabel2,
                org.openide.util.NbBundle.getMessage(EvaluationPanel.class, "EvaluationPanel.jLabel2.text")); // NOI18N

        incorrectClassifiedInstances.setFont(new java.awt.Font("Monospaced", 0, 11)); // NOI18N
        incorrectClassifiedInstances.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        org.openide.awt.Mnemonics.setLocalizedText(incorrectClassifiedInstances, org.openide.util.NbBundle
                .getMessage(EvaluationPanel.class, "EvaluationPanel.incorrectClassifiedInstances.text")); // NOI18N
        incorrectClassifiedInstances.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 8));

        jPanel5.setOpaque(false);
        jPanel5.setLayout(new java.awt.BorderLayout());

        toolBar.setFloatable(false);
        toolBar.setRollover(true);
        toolBar.setOpaque(false);
        toolBar.add(filler1);

        org.openide.awt.Mnemonics.setLocalizedText(infoButton,
                org.openide.util.NbBundle.getMessage(EvaluationPanel.class, "EvaluationPanel.infoButton.text")); // NOI18N
        infoButton.setFocusable(false);
        infoButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        infoButton.setMaximumSize(new java.awt.Dimension(24, 30));
        infoButton.setOpaque(false);
        infoButton.setPreferredSize(new java.awt.Dimension(32, 21));
        infoButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        infoButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                infoButtonActionPerformed(evt);
            }
        });
        toolBar.add(infoButton);

        jPanel5.add(toolBar, java.awt.BorderLayout.CENTER);

        jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);

        jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL);

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(jPanel4Layout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel4Layout.createSequentialGroup()
                        .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 162,
                                javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(correctClassifiedInstances)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(incorrectClassifiedInstances)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, 449, Short.MAX_VALUE)));
        jPanel4Layout
                .setVerticalGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel4Layout.createSequentialGroup().addGroup(jPanel4Layout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(correctClassifiedInstances, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(incorrectClassifiedInstances, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, 28,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jSeparator1).addComponent(jSeparator2)).addContainerGap()));

        jPanel1.add(jPanel4, java.awt.BorderLayout.CENTER);

        add(jPanel1, java.awt.BorderLayout.SOUTH);
    }// </editor-fold>//GEN-END:initComponents

    private void infoButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_infoButtonActionPerformed
        if (evaluation != null) {
            DialogDescriptor descriptor = new DialogDescriptor(new EvaluationDetailPanel(evaluation),
                    "Detail Evaluation Statistics"); //NO18N
            DialogDisplayer.getDefault().createDialog(descriptor).setVisible(true);
        }
    }//GEN-LAST:event_infoButtonActionPerformed
     // Variables declaration - do not modify//GEN-BEGIN:variables

    private de.fub.maps.project.detector.model.inference.ui.charts.PrecisionRecallBarChartPanel barChartPanel;
    private javax.swing.JLabel correctClassifiedInstances;
    private javax.swing.Box.Filler filler1;
    private javax.swing.JLabel incorrectClassifiedInstances;
    private javax.swing.JButton infoButton;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private org.openide.explorer.view.OutlineView outlineView;
    private javax.swing.JLabel title;
    private javax.swing.JToolBar toolBar;
    // End of variables declaration//GEN-END:variables

    @Override
    public ExplorerManager getExplorerManager() {
        return explorerManager;
    }

    public void updatePanel(Evaluation evaluation) {
        DefaultCategoryDataset dataset = getBarChartPanel().getDataset();
        dataset.clear();

        this.evaluation = evaluation;
        double correct = evaluation.pctCorrect();
        double incorrect = evaluation.pctIncorrect();

        getCorrectClassifiedInstances().setText(MessageFormat.format(NUMBER_PATTERN, correct));
        getIncorrectClassifiedInstances().setText(MessageFormat.format(NUMBER_PATTERN, incorrect));

        int numClasses = evaluation.getHeader().numClasses();
        for (int classIndex = 0; classIndex < numClasses; classIndex++) {
            double precision = evaluation.precision(classIndex) * 100;
            double recall = evaluation.recall(classIndex) * 100;
            dataset.addValue(precision,
                    NbBundle.getMessage(EvaluationPanel.class, "EvaluationPanel.CLT_Precision_Text"),
                    evaluation.getHeader().classAttribute().value(classIndex));
            dataset.addValue(recall, NbBundle.getMessage(EvaluationPanel.class, "EvaluationPanel.CLT_Recall_Text"),
                    evaluation.getHeader().classAttribute().value(classIndex));
        }

        getExplorerManager()
                .setRootContext(new AbstractNode(Children.create(new EvaluationNodeFactory(evaluation), true)));
        repaint();
    }

    private static class EvaluationNodeFactory extends ChildFactory<SimpleEvaluationNode> {

        private final Evaluation evaluation;

        public EvaluationNodeFactory(Evaluation evaluation) {
            this.evaluation = evaluation;
        }

        @Override
        protected boolean createKeys(List<SimpleEvaluationNode> toPopulate) {
            Instances header = evaluation.getHeader();
            int numClasses = header.numClasses();
            for (int index = 0; index < numClasses; index++) {
                toPopulate.add(new SimpleEvaluationNode(evaluation, index));
            }

            return true;
        }

        @Override
        protected Node createNodeForKey(SimpleEvaluationNode node) {
            return node;
        }
    }

    private static class SimpleEvaluationNode extends AbstractNode implements Comparable<SimpleEvaluationNode> {

        private final Evaluation evaluation;
        private final int classIndex;
        private static final Image EMPTY_IMAGE = getEmptyImage();

        public SimpleEvaluationNode(Evaluation evaluation, int classIndex) {
            super(Children.LEAF);
            this.evaluation = evaluation;
            this.classIndex = classIndex;
            setDisplayName(evaluation.getHeader().classAttribute().value(classIndex));
        }

        @Override
        protected Sheet createSheet() {
            Sheet sheet = Sheet.createDefault();
            Sheet.Set set = Sheet.createPropertiesSet();
            sheet.put(set);

            Property<?> property = new PropertySupport.ReadOnly<Double>("precision", Double.class,
                    NbBundle.getMessage(EvaluationPanel.class, "EvaluationPanel.CLT_Precision_Text"),
                    "The precision value that this classifier obtained for the given label.") {
                @Override
                public Double getValue() throws IllegalAccessException, InvocationTargetException {
                    double precision = evaluation.precision(classIndex) * 100;
                    String formatedString = MessageFormat.format("{0, number, 000.00}", precision).replaceAll(",",
                            "\\.");
                    Double result = Double.valueOf(formatedString);
                    return result;
                }
            };
            set.put(property);

            property = new PropertySupport.ReadOnly<Double>("recall", Double.class,
                    NbBundle.getMessage(EvaluationPanel.class, "EvaluationPanel.CLT_Recall_Text"),
                    "The recall value that this classifier obtained for the given label.") {
                @Override
                public Double getValue() throws IllegalAccessException, InvocationTargetException {
                    double recall = evaluation.recall(classIndex) * 100;
                    String formatedString = MessageFormat.format("{0, number, 000.00}", recall).replaceAll(",",
                            "\\.");
                    Double result = Double.valueOf(formatedString);
                    return result;
                }
            };
            set.put(property);

            return sheet;
        }

        @Override
        public Image getIcon(int type) {
            return EMPTY_IMAGE;
        }

        @Override
        public Image getOpenedIcon(int type) {
            return getIcon(type);
        }

        @Override
        public int compareTo(SimpleEvaluationNode evaluationNode) {
            return getDisplayName().compareToIgnoreCase(evaluationNode.getDisplayName());
        }

        private static Image getEmptyImage() {
            BufferedImage bufferedImage = new BufferedImage(16, 16, BufferedImage.TYPE_4BYTE_ABGR);
            Graphics2D g2d = bufferedImage.createGraphics();
            g2d.setPaint(new Color(255, 255, 255, 0));
            g2d.fill(new Rectangle(bufferedImage.getWidth(), bufferedImage.getHeight()));
            g2d.dispose();
            return bufferedImage;
        }
    }

    private static class MyOutlineView extends OutlineView {

        private static final long serialVersionUID = 1L;

        public MyOutlineView() {
            getActionMap().clear();
        }

        public MyOutlineView(String nodesColumnLabel) {
            super(nodesColumnLabel);
            getActionMap().clear();
        }
    }
}