AttributeSummaryPanel.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 12k
Category:

Windows Develop

Development Platform:

Java

  1. /*
  2.  *    This program is free software; you can redistribute it and/or modify
  3.  *    it under the terms of the GNU General Public License as published by
  4.  *    the Free Software Foundation; either version 2 of the License, or
  5.  *    (at your option) any later version.
  6.  *
  7.  *    This program is distributed in the hope that it will be useful,
  8.  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  *    GNU General Public License for more details.
  11.  *
  12.  *    You should have received a copy of the GNU General Public License
  13.  *    along with this program; if not, write to the Free Software
  14.  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15.  */
  16. /*
  17.  *    AttributeSummaryPanel.java
  18.  *    Copyright (C) 1999 Len Trigg
  19.  *
  20.  */
  21. package weka.gui;
  22. import weka.core.Attribute;
  23. import weka.core.Instances;
  24. import weka.core.AttributeStats;
  25. import java.awt.BorderLayout;
  26. import java.awt.GridBagLayout;
  27. import java.awt.GridBagConstraints;
  28. import java.awt.event.ActionListener;
  29. import java.awt.event.ActionEvent;
  30. import java.awt.event.WindowAdapter;
  31. import java.awt.event.WindowEvent;
  32. import javax.swing.JPanel;
  33. import javax.swing.JLabel;
  34. import javax.swing.JFrame;
  35. import javax.swing.JButton;
  36. import javax.swing.BorderFactory;
  37. import javax.swing.filechooser.FileFilter;
  38. import javax.swing.JFileChooser;
  39. import javax.swing.JOptionPane;
  40. import javax.swing.SwingConstants;
  41. import javax.swing.SwingUtilities;
  42. import javax.swing.JScrollPane;
  43. import javax.swing.JTable;
  44. import javax.swing.table.DefaultTableModel;
  45. /** 
  46.  * This panel displays summary statistics about an attribute: name, type
  47.  * number/% of missing/unique values, number of distinct values. For
  48.  * numeric attributes gives some other stats (mean/std dev), for nominal
  49.  * attributes gives counts for each attribute value.
  50.  *
  51.  * @author Len Trigg (trigg@cs.waikato.ac.nz)
  52.  * @version $Revision: 1.5 $
  53.  */
  54. public class AttributeSummaryPanel extends JPanel {
  55.   /** Message shown when no instances have been loaded and no attribute set */
  56.   protected final static String NO_SOURCE = "None";
  57.   /** Displays the name of the relation */
  58.   protected JLabel m_AttributeNameLab = new JLabel(NO_SOURCE);
  59.   
  60.   /** Displays the type of attribute */
  61.   protected JLabel m_AttributeTypeLab = new JLabel(NO_SOURCE);
  62.   
  63.   /** Displays the number of missing values */
  64.   protected JLabel m_MissingLab = new JLabel(NO_SOURCE);
  65.     
  66.   /** Displays the number of unique values */
  67.   protected JLabel m_UniqueLab = new JLabel(NO_SOURCE);
  68.     
  69.   /** Displays the number of distinct values */
  70.   protected JLabel m_DistinctLab = new JLabel(NO_SOURCE);
  71.   /** Displays other stats in a table */
  72.   protected JTable m_StatsTable = new JTable();
  73.   
  74.   /** The instances we're playing with */
  75.   protected Instances m_Instances;
  76.   /** Cached stats on the attributes we've summarized so far */
  77.   protected AttributeStats [] m_AttributeStats;
  78.   
  79.   /**
  80.    * Creates the instances panel with no initial instances.
  81.    */
  82.   public AttributeSummaryPanel() {
  83.     JPanel simple = new JPanel();
  84.     GridBagLayout gbL = new GridBagLayout();
  85.     simple.setLayout(gbL);
  86.     JLabel lab = new JLabel("Name:", SwingConstants.RIGHT);
  87.     lab.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
  88.     GridBagConstraints gbC = new GridBagConstraints();
  89.     gbC.anchor = GridBagConstraints.EAST;
  90.     gbC.fill = GridBagConstraints.HORIZONTAL;
  91.     gbC.gridy = 0;     gbC.gridx = 0;
  92.     gbL.setConstraints(lab, gbC);
  93.     simple.add(lab);
  94.     gbC = new GridBagConstraints();
  95.     gbC.anchor = GridBagConstraints.WEST;
  96.     gbC.fill = GridBagConstraints.HORIZONTAL;
  97.     gbC.gridy = 0;     gbC.gridx = 1;
  98.     gbC.weightx = 100; gbC.gridwidth = 3;
  99.     gbL.setConstraints(m_AttributeNameLab, gbC);
  100.     simple.add(m_AttributeNameLab);
  101.     m_AttributeNameLab.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 10));
  102.     
  103.     lab = new JLabel("Type:", SwingConstants.RIGHT);
  104.     lab.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
  105.     gbC = new GridBagConstraints();
  106.     gbC.anchor = GridBagConstraints.EAST;
  107.     gbC.fill = GridBagConstraints.HORIZONTAL;
  108.     gbC.gridy = 0;     gbC.gridx = 4;
  109.     gbL.setConstraints(lab, gbC);
  110.     simple.add(lab);
  111.     gbC = new GridBagConstraints();
  112.     gbC.anchor = GridBagConstraints.WEST;
  113.     gbC.fill = GridBagConstraints.HORIZONTAL;
  114.     gbC.gridy = 0;     gbC.gridx = 5;
  115.     gbC.weightx = 100;
  116.     gbL.setConstraints(m_AttributeTypeLab, gbC);
  117.     simple.add(m_AttributeTypeLab);
  118.     m_AttributeTypeLab.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 10));
  119.     // Put into a separate panel?
  120.     lab = new JLabel("Missing:", SwingConstants.RIGHT);
  121.     lab.setBorder(BorderFactory.createEmptyBorder(0, 10, 5, 0));
  122.     gbC = new GridBagConstraints();
  123.     gbC.anchor = GridBagConstraints.EAST;
  124.     gbC.fill = GridBagConstraints.HORIZONTAL;
  125.     gbC.gridy = 1;     gbC.gridx = 0;
  126.     gbL.setConstraints(lab, gbC);
  127.     simple.add(lab);
  128.     gbC = new GridBagConstraints();
  129.     gbC.anchor = GridBagConstraints.WEST;
  130.     gbC.fill = GridBagConstraints.HORIZONTAL;
  131.     gbC.gridy = 1;     gbC.gridx = 1;
  132.     gbC.weightx = 100;
  133.     gbL.setConstraints(m_MissingLab, gbC);
  134.     simple.add(m_MissingLab);
  135.     m_MissingLab.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 10));
  136.     lab = new JLabel("Distinct:", SwingConstants.RIGHT);
  137.     lab.setBorder(BorderFactory.createEmptyBorder(0, 10, 5, 0));
  138.     gbC = new GridBagConstraints();
  139.     gbC.anchor = GridBagConstraints.EAST;
  140.     gbC.fill = GridBagConstraints.HORIZONTAL;
  141.     gbC.gridy = 1;     gbC.gridx = 2;
  142.     gbL.setConstraints(lab, gbC);
  143.     simple.add(lab);
  144.     gbC = new GridBagConstraints();
  145.     gbC.anchor = GridBagConstraints.WEST;
  146.     gbC.fill = GridBagConstraints.HORIZONTAL;
  147.     gbC.gridy = 1;     gbC.gridx = 3;
  148.     gbC.weightx = 100;
  149.     gbL.setConstraints(m_DistinctLab, gbC);
  150.     simple.add(m_DistinctLab);
  151.     m_DistinctLab.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 10));
  152.     lab = new JLabel("Unique:", SwingConstants.RIGHT);
  153.     lab.setBorder(BorderFactory.createEmptyBorder(0, 10, 5, 0));
  154.     gbC = new GridBagConstraints();
  155.     gbC.anchor = GridBagConstraints.EAST;
  156.     gbC.fill = GridBagConstraints.HORIZONTAL;
  157.     gbC.gridy = 1;     gbC.gridx = 4;
  158.     gbL.setConstraints(lab, gbC);
  159.     simple.add(lab);
  160.     gbC = new GridBagConstraints();
  161.     gbC.anchor = GridBagConstraints.WEST;
  162.     gbC.fill = GridBagConstraints.HORIZONTAL;
  163.     gbC.gridy = 1;     gbC.gridx = 5;
  164.     gbC.weightx = 100;
  165.     gbL.setConstraints(m_UniqueLab, gbC);
  166.     simple.add(m_UniqueLab);
  167.     m_UniqueLab.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 10));
  168.     
  169.     setLayout(new BorderLayout());
  170.     add(simple, BorderLayout.NORTH);
  171.     add(new JScrollPane(m_StatsTable), BorderLayout.CENTER);
  172.   }
  173.   /**
  174.    * Tells the panel to use a new set of instances.
  175.    *
  176.    * @param inst a set of Instances
  177.    */
  178.   public void setInstances(Instances inst) {
  179.     
  180.     m_Instances = inst;
  181.     m_AttributeStats = new AttributeStats [inst.numAttributes()];
  182.     m_AttributeNameLab.setText(NO_SOURCE);
  183.     m_AttributeTypeLab.setText(NO_SOURCE);
  184.     m_MissingLab.setText(NO_SOURCE);
  185.     m_UniqueLab.setText(NO_SOURCE);
  186.     m_DistinctLab.setText(NO_SOURCE);
  187.     m_StatsTable.setModel(new DefaultTableModel());
  188.   }
  189.   /**
  190.    * Sets the attribute that statistics will be displayed for.
  191.    *
  192.    * @param index the index of the attribute to display
  193.    */
  194.   public void setAttribute(final int index) {
  195.     setHeader(index);
  196.     if (m_AttributeStats[index] == null) {
  197.       Thread t = new Thread() {
  198. public void run() {
  199.   m_AttributeStats[index] = m_Instances
  200.   .attributeStats(index);
  201.   SwingUtilities.invokeLater(new Runnable() {
  202.     public void run() {
  203.       setDerived(index);
  204.       m_StatsTable.sizeColumnsToFit(-1);
  205.       m_StatsTable.revalidate();
  206.       m_StatsTable.repaint();
  207.     }
  208.   });
  209. }
  210.       };
  211.       t.setPriority(Thread.MIN_PRIORITY);
  212.       t.start();
  213.     } else {
  214.       setDerived(index);
  215.     }
  216.   }
  217.   
  218.   /**
  219.    * Sets the gui elements for fields that are stored in the AttributeStats
  220.    * structure.
  221.    */
  222.   protected void setDerived(int index) {
  223.     
  224.     AttributeStats as = m_AttributeStats[index];
  225.     long percent = Math.round(100.0 * as.missingCount / as.totalCount);
  226.     m_MissingLab.setText("" + as.missingCount + " (" + percent + "%)");
  227.     percent = Math.round(100.0 * as.uniqueCount / as.totalCount);
  228.     m_UniqueLab.setText("" + as.uniqueCount + " (" + percent + "%)");
  229.     m_DistinctLab.setText("" + as.distinctCount);
  230.     setTable(as, index);
  231.   }
  232.   /**
  233.    * Creates a tablemodel for the attribute being displayed
  234.    */
  235.   protected void setTable(AttributeStats as, int index) {
  236.     if (as.nominalCounts != null) {
  237.       Attribute att = m_Instances.attribute(index);
  238.       Object [] colNames = {"Label", "Count"};
  239.       Object [][] data = new Object [as.nominalCounts.length][2];
  240.       for (int i = 0; i < as.nominalCounts.length; i++) {
  241. data[i][0] = att.value(i);
  242. data[i][1] = new Integer(as.nominalCounts[i]);
  243.       }
  244.       m_StatsTable.setModel(new DefaultTableModel(data, colNames));
  245.     } else if (as.numericStats != null) {
  246.       Object [] colNames = {"Statistic", "Value"};
  247.       Object [][] data = new Object [4][2];
  248.       data[0][0] = "Minimum"; data[0][1] = new Double(as.numericStats.min);
  249.       data[1][0] = "Maximum"; data[1][1] = new Double(as.numericStats.max);
  250.       data[2][0] = "Mean";    data[2][1] = new Double(as.numericStats.mean);
  251.       data[3][0] = "StdDev";  data[3][1] = new Double(as.numericStats.stdDev);
  252.       m_StatsTable.setModel(new DefaultTableModel(data, colNames));
  253.     } else {
  254.       m_StatsTable.setModel(new DefaultTableModel());
  255.     }
  256.   }
  257.   
  258.   /**
  259.    * Sets the labels for fields we can determine just from the instance
  260.    * header.
  261.    */
  262.   protected void setHeader(int index) {
  263.     
  264.     Attribute att = m_Instances.attribute(index);
  265.     m_AttributeNameLab.setText(att.name());
  266.     switch (att.type()) {
  267.     case Attribute.NOMINAL:
  268.       m_AttributeTypeLab.setText("Nominal");
  269.       break;
  270.     case Attribute.NUMERIC:
  271.       m_AttributeTypeLab.setText("Numeric");
  272.       break;
  273.     case Attribute.STRING:
  274.       m_AttributeTypeLab.setText("String");
  275.       break;
  276.     default:
  277.       m_AttributeTypeLab.setText("Unknown");
  278.       break;
  279.     }
  280.     m_MissingLab.setText("...");
  281.     m_UniqueLab.setText("...");
  282.     m_DistinctLab.setText("...");
  283.   }
  284.   /**
  285.    * Tests out the attribute summary panel from the command line.
  286.    *
  287.    * @param args optional name of dataset to load
  288.    */
  289.   public static void main(String [] args) {
  290.     try {
  291.       final javax.swing.JFrame jf = new javax.swing.JFrame("Attribute Panel");
  292.       jf.getContentPane().setLayout(new BorderLayout());
  293.       final AttributeSummaryPanel p = new AttributeSummaryPanel();
  294.       p.setBorder(BorderFactory.createTitledBorder("Attribute"));
  295.       jf.getContentPane().add(p, BorderLayout.CENTER);
  296.       final javax.swing.JComboBox j = new javax.swing.JComboBox();
  297.       j.setEnabled(false);
  298.       j.addActionListener(new java.awt.event.ActionListener() {
  299. public void actionPerformed(java.awt.event.ActionEvent e) {
  300.   p.setAttribute(j.getSelectedIndex());
  301. }
  302.       });
  303.       jf.getContentPane().add(j, BorderLayout.NORTH);
  304.       jf.addWindowListener(new java.awt.event.WindowAdapter() {
  305. public void windowClosing(java.awt.event.WindowEvent e) {
  306.   jf.dispose();
  307.   System.exit(0);
  308. }
  309.       });
  310.       jf.pack();
  311.       jf.setVisible(true);
  312.       if (args.length == 1) {
  313. java.io.Reader r = new java.io.BufferedReader(
  314.    new java.io.FileReader(args[0]));
  315. Instances inst = new Instances(r);
  316. p.setInstances(inst);
  317. p.setAttribute(0);
  318. String [] names = new String [inst.numAttributes()];
  319. for (int i = 0; i < names.length; i++) {
  320.   names[i] = inst.attribute(i).name();
  321. }
  322. j.setModel(new javax.swing.DefaultComboBoxModel(names));
  323. j.setEnabled(true);
  324.       }
  325.     } catch (Exception ex) {
  326.       ex.printStackTrace();
  327.       System.err.println(ex.getMessage());
  328.     }
  329.   }
  330. }