sirius.clustering.main.UtilizeClustererPane.java Source code

Java tutorial

Introduction

Here is the source code for sirius.clustering.main.UtilizeClustererPane.java

Source

/*==========================================================================
 SiriusPSB - A Generic System for Analysis of Biological Sequences
       http://compbio.ddns.comp.nus.edu.sg/~sirius/index.php
============================================================================
 Copyright (C) 2007 by Chuan Hock Koh
       
 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 3 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, see <http://www.gnu.org/licenses/>.
==========================================================================*/
package sirius.clustering.main;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.ObjectInputStream;
import java.util.StringTokenizer;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.filechooser.FileNameExtensionFilter;

import sirius.trainer.main.SiriusSettings;

import weka.clusterers.Clusterer;
import weka.core.Attribute;
import weka.core.Instances;
import weka.filters.Filter;
import weka.filters.unsupervised.attribute.Remove;

public class UtilizeClustererPane extends JComponent implements ActionListener {
    static final long serialVersionUID = sirius.Sirius.version;

    private Thread inputThread;
    private JButton inputFileButton;
    private JTextField inputFileTextField;
    private JButton outputFileButton;
    private JTextField outputFileTextField;
    private JButton bottomStartButton;
    private JButton bottomStopButton;
    private boolean run;
    private String inputFileName;
    private JLabel statusLabel;
    private JFrame parent;
    private JButton clustererButton;
    private JTextField clustererTextField;
    private Clusterer clusterer;
    private JTextArea outputTextArea;

    private JScrollPane outputScrollPane;
    private JComboBox m_ClassCombo = new JComboBox();

    public UtilizeClustererPane(JFrame mainFrame) {
        this.parent = mainFrame;

        JPanel clustererPanel = new JPanel(new BorderLayout());
        clustererPanel.setBorder(
                BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Choose Trained Clusterer"),
                        BorderFactory.createEmptyBorder(0, 5, 5, 5)));
        this.clustererButton = new JButton("Choose");
        this.clustererButton.addActionListener(this);
        this.clustererTextField = new JTextField();
        this.clustererTextField.setFocusable(false);
        clustererPanel.add(this.clustererButton, BorderLayout.WEST);
        clustererPanel.add(this.clustererTextField, BorderLayout.CENTER);

        JPanel outputPanel = new JPanel(new GridLayout(1, 1));
        outputPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Output"),
                BorderFactory.createEmptyBorder(0, 5, 5, 5)));
        this.outputTextArea = new JTextArea();
        this.outputTextArea.setFocusable(false);
        outputScrollPane = new JScrollPane(outputTextArea);
        outputPanel.add(outputScrollPane, BorderLayout.CENTER);

        JPanel inputFilePanel = new JPanel(new BorderLayout());
        inputFilePanel
                .setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Choose Input File"),
                        BorderFactory.createEmptyBorder(0, 5, 5, 5)));
        this.inputFileButton = new JButton("Choose");
        this.inputFileButton.addActionListener(this);
        this.inputFileTextField = new JTextField();
        this.inputFileTextField.setFocusable(false);
        inputFilePanel.add(this.inputFileButton, BorderLayout.WEST);
        inputFilePanel.add(this.inputFileTextField, BorderLayout.CENTER);

        JPanel outputFilePanel = new JPanel(new BorderLayout());
        outputFilePanel.setBorder(
                BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Choose Output Location"),
                        BorderFactory.createEmptyBorder(0, 5, 5, 5)));
        this.outputFileButton = new JButton("Choose");
        this.outputFileButton.addActionListener(this);
        this.outputFileTextField = new JTextField();
        this.outputFileTextField.setFocusable(false);
        outputFilePanel.add(this.outputFileButton, BorderLayout.WEST);
        outputFilePanel.add(this.outputFileTextField, BorderLayout.CENTER);

        JPanel startStopButtonsPanel = new JPanel(new GridLayout(1, 2, 5, 5));
        startStopButtonsPanel.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createTitledBorder("Controls"), BorderFactory.createEmptyBorder(0, 5, 5, 5)));
        this.bottomStartButton = new JButton("Start");
        this.bottomStartButton.addActionListener(this);
        this.bottomStopButton = new JButton("Stop");
        this.bottomStopButton.addActionListener(this);
        this.bottomStopButton.setEnabled(false);
        startStopButtonsPanel.add(this.bottomStartButton);
        startStopButtonsPanel.add(this.bottomStopButton);

        JPanel classIndexPanel = new JPanel(new BorderLayout());
        classIndexPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Settings"),
                BorderFactory.createEmptyBorder(0, 5, 5, 5)));
        JLabel classIndexLabel = new JLabel("Class: ");
        JPanel extraPanel = new JPanel(new BorderLayout());
        extraPanel.add(classIndexLabel, BorderLayout.WEST);
        extraPanel.add(this.m_ClassCombo, BorderLayout.CENTER);
        classIndexPanel.add(extraPanel, BorderLayout.NORTH);

        JPanel northPanel = new JPanel(new BorderLayout());
        northPanel.add(clustererPanel, BorderLayout.NORTH);
        northPanel.add(inputFilePanel, BorderLayout.CENTER);
        northPanel.add(outputFilePanel, BorderLayout.SOUTH);

        JPanel statusPanel = new JPanel(new GridLayout(1, 1));
        statusPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Status"),
                BorderFactory.createEmptyBorder(0, 5, 5, 5)));
        this.statusLabel = new JLabel(" ");
        statusPanel.add(this.statusLabel);

        JPanel emptyPanel1 = new JPanel();
        JPanel emptyPanel2 = new JPanel();

        JPanel centerNorthPanel = new JPanel(new GridLayout(1, 4, 5, 5));
        centerNorthPanel.add(classIndexPanel);
        centerNorthPanel.add(startStopButtonsPanel);
        centerNorthPanel.add(emptyPanel1);
        centerNorthPanel.add(emptyPanel2);

        JPanel centerPanel = new JPanel(new BorderLayout());
        centerPanel.add(outputPanel, BorderLayout.CENTER);
        centerPanel.add(centerNorthPanel, BorderLayout.NORTH);

        setLayout(new BorderLayout());
        //add(settingsPanel,BorderLayout.WEST);
        add(northPanel, BorderLayout.NORTH);
        add(centerPanel, BorderLayout.CENTER);
        add(statusPanel, BorderLayout.SOUTH);
    }

    private void setOutputLocation() {
        JFileChooser chooser;
        String lastLocation = SiriusSettings.getInformation("LastClusteringOutputLocation: ");
        if (lastLocation == null)
            chooser = new JFileChooser();
        else
            chooser = new JFileChooser(lastLocation);
        chooser.setDialogTitle("Set Working Directory");
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        chooser.setAcceptAllFileFilterUsed(false);
        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            this.outputFileTextField.setText(chooser.getSelectedFile().toString());
            SiriusSettings.updateInformation("LastCLusteringOutputLocation: ",
                    chooser.getSelectedFile().getAbsolutePath());
        } else {
            //no selection
        }
    }

    private void stop() {
        run = false;
    }

    private void loadClusterer() {
        String lastClassifierFileLocation = SiriusSettings.getInformation("LastClusteringOutputLocation: ");
        JFileChooser fc = new JFileChooser(lastClassifierFileLocation);
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Clusterer Files", "clusterer", "clusterer");
        fc.setFileFilter(filter);
        int returnVal = fc.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            try {
                statusLabel.setText(" Loading Clusterer..");
                File file = fc.getSelectedFile();
                SiriusSettings.updateInformation("LastClusteringOutputLocation: ", file.getAbsolutePath());
                FileInputStream fis = new FileInputStream(file);
                ObjectInputStream ois = new ObjectInputStream(fis);

                clusterer = (Clusterer) ois.readObject();
                ois.close();
                this.clustererTextField.setText(file.getAbsolutePath());
                statusLabel.setText(" Loading Clusterer..Done!");
            } catch (Exception e) {
                e.printStackTrace();
                statusLabel.setText(" Loading Clusterer..Error!");
            }
        }
    }

    private Instances removeClass(Instances inst) {//Copied directly from Weka's ClustererPanel.java
        Remove af = new Remove();
        Instances retI = null;
        try {
            if (inst.classIndex() < 0) {
                //do nothing since classindex is not set
                retI = inst;
            } else {
                //remove class attribute
                af.setAttributeIndices("" + (inst.classIndex() + 1));
                af.setInvertSelection(false);
                af.setInputFormat(inst);
                retI = Filter.useFilter(inst, af);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return retI;
    }

    private void start() {
        if (this.clustererTextField.getText().length() == 0) {
            JOptionPane.showMessageDialog(parent, "Please set clusterer!", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (this.inputFileTextField.getText().length() == 0) {
            JOptionPane.showMessageDialog(parent, "Please choose input file!", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (this.outputFileTextField.getText().length() == 0) {
            JOptionPane.showMessageDialog(parent, "Please choose output location!", "Error",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (inputThread != null) {
            JOptionPane.showMessageDialog(parent, "Cannot start because another is still running!", "Error",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }
        this.bottomStartButton.setEnabled(false);
        this.bottomStopButton.setEnabled(true);
        run = true;
        inputThread = (new Thread() {
            public void run() {
                try {
                    statusLabel.setText(" Evaluating Input File..");
                    BufferedWriter[] outputArray = new BufferedWriter[clusterer.numberOfClusters()];
                    int[] counter = new int[clusterer.numberOfClusters()];
                    for (int x = 0; x < clusterer.numberOfClusters(); x++) {
                        outputArray[x] = new BufferedWriter(new FileWriter(outputFileTextField.getText()
                                + File.separator + inputFileName + "_cluster" + x + ".arff"));
                    }
                    BufferedReader input = new BufferedReader(new FileReader(inputFileTextField.getText()));
                    String line;
                    while ((line = input.readLine()) != null) {
                        if (run == false)
                            break;
                        for (int x = 0; x < clusterer.numberOfClusters(); x++) {
                            outputArray[x].write(line);
                            outputArray[x].newLine();
                        }
                        if (line.equalsIgnoreCase("@data")) {
                            for (int x = 0; x < clusterer.numberOfClusters(); x++) {
                                outputArray[x].newLine();
                            }
                            break;
                        }
                    }
                    input.close();
                    Instances inst = new Instances(
                            new BufferedReader(new FileReader(inputFileTextField.getText())));
                    inst.setClassIndex(m_ClassCombo.getSelectedIndex());
                    if (inst.classAttribute().isNumeric()) {
                        JOptionPane.showMessageDialog(parent, "Class must be nominal!", "Error",
                                JOptionPane.ERROR_MESSAGE);
                    } else {
                        Instances instWithoutClass = removeClass(inst);
                        outputTextArea.setText("Number of Clusters: " + clusterer.numberOfClusters() + "\r\n");
                        outputTextArea.append("Number of Attributes: " + (inst.numAttributes() - 1) + "\r\n");
                        outputTextArea.append("Number of Instances: " + inst.numInstances() + "\r\n\r\n");
                        for (int x = 0; x < inst.numInstances(); x++) {
                            if (run == false)
                                break;
                            int clusterIndex = clusterer.clusterInstance(instWithoutClass.instance(x));
                            counter[clusterIndex]++;
                            outputArray[clusterIndex].write(inst.instance(x).toString());
                            outputArray[clusterIndex].newLine();
                        }
                        for (int x = 0; x < clusterer.numberOfClusters(); x++) {
                            outputArray[x].close();
                        }
                        inputThread = null;
                        bottomStartButton.setEnabled(true);
                        bottomStopButton.setEnabled(false);
                        if (run != false) {
                            statusLabel.setText(" Evaluating Input File..Done!");
                            for (int x = 0; x < clusterer.numberOfClusters(); x++) {
                                outputTextArea.append("Cluster " + x + ": " + counter[x] + "\r\n");
                            }
                        } else
                            statusLabel.setText(" Evaluating Input File..Interrupted!");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    JOptionPane.showMessageDialog(parent,
                            "Please ensure that the Trained Clusterer and Input File have same Attributes!",
                            "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        });
        inputThread.setPriority(Thread.MIN_PRIORITY); // UI has most priority
        inputThread.start();
    }

    private void loadInputFile() {
        try {
            //applicationData.hasLocationIndexBeenSet = false;
            JFileChooser fc;
            String lastLocation = SiriusSettings.getInformation("LastClusteringOutputLocation: ");
            if (lastLocation == null)
                fc = new JFileChooser();
            else
                fc = new JFileChooser(lastLocation);
            FileNameExtensionFilter filter = new FileNameExtensionFilter("Arff File", "arff");
            fc.setFileFilter(filter);
            int returnVal = fc.showOpenDialog(parent);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                File file = fc.getSelectedFile();
                SiriusSettings.updateInformation("LastClusteringOutputLocation: ", file.getAbsolutePath());
                this.inputFileTextField.setText(file.getAbsolutePath());
                StringTokenizer st = new StringTokenizer(file.getName(), ".");
                this.inputFileName = st.nextToken();
                Instances inst = new Instances(
                        new BufferedReader(new FileReader(this.inputFileTextField.getText())));
                setInstances(inst);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setInstances(Instances inst) {//Directly copied with slight modification from weka's ClustererPanel.java
        String[] attribNames = new String[inst.numAttributes()];
        for (int i = 0; i < inst.numAttributes(); i++) {
            String type = "";
            switch (inst.attribute(i).type()) {
            case Attribute.NOMINAL:
                type = "(Nom) ";
                break;
            case Attribute.NUMERIC:
                type = "(Num) ";
                break;
            case Attribute.STRING:
                type = "(Str) ";
                break;
            case Attribute.DATE:
                type = "(Dat) ";
                break;
            case Attribute.RELATIONAL:
                type = "(Rel) ";
                break;
            default:
                type = "(???) ";
            }
            String attnm = inst.attribute(i).name();
            attribNames[i] = type + attnm;
        }
        m_ClassCombo.setModel(new DefaultComboBoxModel(attribNames));
        if (inst.classIndex() == -1)
            m_ClassCombo.setSelectedIndex(attribNames.length - 1);
        else
            m_ClassCombo.setSelectedIndex(inst.classIndex());
    }

    public void actionPerformed(ActionEvent ae) {
        if (ae.getSource().equals(this.inputFileButton)) {
            loadInputFile();
        } else if (ae.getSource().equals(this.bottomStartButton)) {
            start();
        } else if (ae.getSource().equals(this.bottomStopButton)) {
            stop();
        } else if (ae.getSource().equals(this.outputFileButton)) {
            setOutputLocation();
        } else if (ae.getSource().equals(this.clustererButton)) {
            loadClusterer();
        }
    }
}