Log in Help
Print
Homereleasesgate-8.0-build4825-ALLpluginsTermRaidersrcgatetermraidergui 〉 TermbankViewer.java
 
/*
 *  Copyright (c) 2008--2014, The University of Sheffield. See the file
 *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
 *
 *  This file is part of GATE (see http://gate.ac.uk/), and is free
 *  software, licenced under the GNU Library General Public License,
 *  Version 2, June 1991 (in the distribution as file licence.html,
 *  and also available at http://gate.ac.uk/gate/licence.html).
 *
 *  $Id: TermbankViewer.java 17968 2014-05-11 16:37:34Z ian_roberts $
 */
package gate.termraider.gui;

import gate.Resource;
import gate.creole.ANNIEConstants;
import gate.creole.AbstractVisualResource;
import gate.creole.metadata.CreoleResource;
import gate.creole.metadata.GuiType;
import gate.event.ProgressListener;
import gate.gui.MainFrame;
import gate.swing.JMenuButton;
import gate.swing.XJFileChooser;
import gate.termraider.bank.AbstractTermbank;
import gate.termraider.bank.HyponymyTermbank;
import gate.termraider.gui.ColorMenu.Callback;
import gate.termraider.output.CloudGenerator;
import gate.termraider.util.ScoreType;
import gate.termraider.util.Term;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.AbstractTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import org.xhtmlrenderer.simple.XHTMLPanel;


@CreoleResource(name = "Termbank Viewer",
        comment = "viewer for the TermRaider Termbank",
        helpURL = "http://gate.ac.uk/userguide/sec:creole:termraider",
        guiType = GuiType.LARGE,
        mainViewer = true,
        resourceDisplayed = "gate.termraider.bank.AbstractTermbank")
public class TermbankViewer 
  extends AbstractVisualResource 
  implements ANNIEConstants, ProgressListener {

  private static final long serialVersionUID = 8894861995037230059L;
  
  private JPanel controlPanel;
  private SliderPanel sliderPanel;
  private JScrollPane treeScrollPane, freqScrollPane, miscScrollPane;
  private AbstractTermbank termbank;
  private JTree tree;
  private JTable termbankTable, miscTable;
  private JTabbedPane tabbedPane;
  private TermbankTableModel termbankTableModel;
  
  private XHTMLPanel termCloud = new XHTMLPanel();
  private JComboBox cloudType;
  private JSlider cloudSize = new JSlider();
  private List<ScoreType> scoreTypes;
  
  private CloudGenerator cloudGenerator = null;
  private ColorMenu fontColorMenu, backgroundColorMenu;
  
  private JPopupMenu mnuLanguages = new JPopupMenu();
  private JMenuButton menuLanguageButton = new JMenuButton(mnuLanguages);
  
  private JPopupMenu mnuTypes = new JPopupMenu();
  private JMenuButton menuTypesButton = new JMenuButton(mnuTypes);
  
  @Override
  public Resource init() {
    initGuiComponents();
    return this;
  }


  protected void populateTree(DefaultMutableTreeNode root, AbstractTermbank termbank) {
    List<Term> typeSortedTerms = termbank.getTermsByDescendingScore();
    Map<Term, Number> typeTermScores = termbank.getDefaultScores();
    Map<Term, Set<String>> typeTermDocuments = termbank.getTermDocuments();
    
    DefaultMutableTreeNode node1, node2;
    int minScore = sliderPanel.getValue();
    
    for (Term term : typeSortedTerms) {
      Number score = typeTermScores.get(term);
      if (score.intValue() >= minScore) {
        node1 = new DefaultMutableTreeNode(term + "  " + score.toString());
        root.add(node1);
        
        for (String document : typeTermDocuments.get(term)) {
          node2 = new DefaultMutableTreeNode(document);
          node1.add(node2);
        }
      }
      else {  // the rest must be lower
        break;
      }
    }
  }

  
  
  private void initGuiComponents() {
    setLayout(new BorderLayout());
    generateEmptyTree();
    tabbedPane = new JTabbedPane();
    JPanel treeTab = new JPanel(new BorderLayout());
    tabbedPane.addTab("Tree", treeTab);
    JPanel tableTab = new JPanel(new BorderLayout());
    tabbedPane.addTab("Details", tableTab);
    JPanel miscTab = new JPanel(new BorderLayout());
    tabbedPane.addTab("Miscellaneous", miscTab);

    JPanel cloudTab = new JPanel(new BorderLayout());
    tabbedPane.addTab("Term Cloud", cloudTab);
    
    controlPanel = new JPanel();
    treeTab.add(controlPanel, BorderLayout.NORTH);
    treeScrollPane = new JScrollPane(tree, 
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    treeTab.add(treeScrollPane, BorderLayout.CENTER);
    controlPanel.validate();
    controlPanel.repaint();
    
    termbankTable = new JTable();
    termbankTable.setAutoCreateRowSorter(true);
    // Set the table model later, because the specific type of termbank
    // will determine the number of columns
    freqScrollPane = new JScrollPane(termbankTable, 
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    tableTab.add(freqScrollPane, BorderLayout.CENTER);
    
    miscTable = new JTable();
    miscTable.setAutoCreateRowSorter(true);
    miscScrollPane = new JScrollPane(miscTable, 
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    miscTab.add(miscScrollPane, BorderLayout.CENTER);

    
    JScrollPane cloudScrollPane = new JScrollPane(termCloud,
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    JToolBar cloudBar = new JToolBar();
    cloudBar.setFloatable(false);
    JButton btnExport = new JButton(MainFrame.getIcon("Download"));
    
    cloudType = new JComboBox();
    
    Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer,JLabel>();
    labelTable.put(0, new JLabel(MainFrame.getIcon("Sunny")));
    labelTable.put(50, new JLabel(MainFrame.getIcon("Cloudy")));
    labelTable.put(100, new JLabel(MainFrame.getIcon("Overcast")));
    
    cloudSize.setOpaque(false);
    cloudSize.setLabelTable(labelTable);
    cloudSize.setPaintLabels(true);
    
    btnExport.setToolTipText("Export Cloud As HTML");
    btnExport.addActionListener(new ActionListener() {
      
      @Override
      public void actionPerformed(ActionEvent arg0) {
        XJFileChooser fileChooser = MainFrame.getFileChooser();
        fileChooser.setResource("HTMLTermCloud");
        fileChooser.setFileFilter(new FileNameExtensionFilter("HTML Files", "html"));
        
        if (fileChooser.showSaveDialog(MainFrame.getInstance()) != XJFileChooser.APPROVE_OPTION) return;
        
        String html = cloudGenerator.getHTML(cloudSize.getValue());
        
        PrintWriter out = null;
        try {
          out = new PrintWriter(new FileWriter(fileChooser.getSelectedFile()));
          
          out.println(html);
          out.flush();
        }
        catch (Exception e) {
          e.printStackTrace();
        }
        finally {
          if (out != null) {
            try {
              out.close();
            }
            catch (Exception e) {
              //ignore this
            }
          }
        }                
      }
    });
    
    JPopupMenu mnuFontColor = new JPopupMenu("Font Colour");
    fontColorMenu = new ColorMenu(mnuFontColor, false, false);
    fontColorMenu.setColor(Color.BLACK);
    fontColorMenu.setCallback(new Callback(){
      @Override
      public void colorChange(Color c) {
        if (cloudGenerator != null && !cloudGenerator.getForeground().equals(c)) {
          cloudGenerator.setForeground(c);
          displayCloud();
        }
      }
    });
    JMenuButton menuButton = new JMenuButton(mnuFontColor);
    menuButton.setIcon(MainFrame.getIcon("FontColour"));
    menuButton.setToolTipText("Font Colour");
    
    JPopupMenu mnuBgColor = new JPopupMenu("Background Colour");
    backgroundColorMenu = new ColorMenu(mnuBgColor, false, false);
    backgroundColorMenu.setColor(Color.WHITE);
    backgroundColorMenu.setCallback(new Callback() {
      @Override
      public void colorChange(Color c) {
        if (cloudGenerator != null && !cloudGenerator.getBackground().equals(c)) {
          cloudGenerator.setBackground(c);
          displayCloud();
        }
      }
    });
    JMenuButton menuBGButton = new JMenuButton(mnuBgColor);
    menuBGButton.setIcon(MainFrame.getIcon("BackgroundColor"));
    menuBGButton.setToolTipText("Background Colour");
    
    menuLanguageButton.setIcon(MainFrame.getIcon("Languages"));
    menuLanguageButton.setToolTipText("Set Displayed Languages");
    
    menuTypesButton.setIcon(MainFrame.getIcon("TermTypes"));
    menuTypesButton.setToolTipText("Set Displayed Term Types");
    
    cloudBar.add(btnExport);
    cloudBar.addSeparator();
    cloudBar.add(menuButton);
    cloudBar.add(menuBGButton);
    cloudBar.addSeparator();
    cloudBar.add(menuLanguageButton);
    cloudBar.add(menuTypesButton);
    cloudBar.addSeparator();
    cloudBar.add(new JLabel("Type: "));    
    cloudBar.add(cloudType);
    cloudBar.add(Box.createHorizontalStrut(15));
    cloudBar.add(new JLabel("Size:"));
    cloudBar.add(cloudSize);
    cloudBar.add(Box.createHorizontalGlue());
        
    cloudTab.add(cloudBar, BorderLayout.NORTH);
    cloudTab.add(cloudScrollPane, BorderLayout.CENTER);
    
    this.add(tabbedPane, BorderLayout.CENTER);
    tabbedPane.validate();
    tabbedPane.repaint();
  }
  
  
  private void populateControlPanel(JPanel controlPanel) {
    controlPanel.setLayout(new BorderLayout());
    sliderPanel = new SliderPanel(termbank, "display", false, this);
    controlPanel.add(sliderPanel, BorderLayout.CENTER);
    sliderPanel.reformat();
    termbankTableModel = new TermbankTableModel(this.termbank);
    termbankTable.setModel(termbankTableModel);
    miscTable.setModel(new MiscTableModel(termbank.getMiscDataForGui()));
  }


  public void processFinished() {
    setTarget(termbank);
  }

  public void progressChanged(int i) {
    // nothing?
  }  

  public void setTarget(Object target) {
    if(target == null || ! (target instanceof AbstractTermbank)) {
      throw new IllegalArgumentException("This Viewer cannot show a "
              + (target == null ? "null" : target.getClass().toString()));
    }
    
    termbank = (AbstractTermbank) target;
    populateControlPanel(controlPanel);

    if (this.termbank instanceof HyponymyTermbank) {
      tabbedPane.addTab("Hyponymy Debugger", new HyponymyDebugger((HyponymyTermbank) this.termbank));
    }
    
    Map<Term, ? extends Number> freq = null;
    scoreTypes = termbank.getScoreTypes();
    menuLanguageButton.setEnabled(termbank.getLanguages().size() > 1);
    
    for (ScoreType st : scoreTypes) {
      cloudType.addItem(st);
    }
    
    cloudType.setSelectedIndex(0);
    freq = termbank.getScores(scoreTypes.get(cloudType.getSelectedIndex()));
    
    cloudType.addActionListener(new ActionListener() {      
      @Override
      public void actionPerformed(ActionEvent arg0) {
        Map<Term, ? extends Number> freq = null;
        freq = termbank.getScores(scoreTypes.get(cloudType.getSelectedIndex()));
        cloudGenerator.setTerms(freq);
        displayCloud();        
      }
    });
    
    cloudSize.addChangeListener(new ChangeListener() {
      @Override
      public void stateChanged(ChangeEvent ce) {
        if (!cloudSize.getValueIsAdjusting()) {
          displayCloud();
        }
      }
    });
        
    ActionListener languageChanger = new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        JCheckBoxMenuItem cb = (JCheckBoxMenuItem)e.getSource();
        cloudGenerator.includeLanguage(cb.getText(), cb.isSelected());
        displayCloud();
      }
    };
    
    if (menuLanguageButton.isEnabled()) {
      mnuLanguages.removeAll();
      
      for (String lang : termbank.getLanguages()) {
        JCheckBoxMenuItem cb = new JCheckBoxMenuItem(lang,true);
        cb.addActionListener(languageChanger);
        mnuLanguages.add(cb);
      }
    }
    
    menuTypesButton.setEnabled(termbank.getTypes().size() > 1);
    
    ActionListener typesChanger = new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        JCheckBoxMenuItem cb = (JCheckBoxMenuItem)e.getSource();
        cloudGenerator.includeTermType(cb.getText(), cb.isSelected());
        displayCloud();
      }
    };
    
    if (menuTypesButton.isEnabled()) {
      mnuTypes.removeAll();
      
      for (String type : termbank.getTypes()) {
        JCheckBoxMenuItem cb = new JCheckBoxMenuItem(type,true);
        cb.addActionListener(typesChanger);
        mnuTypes.add(cb);
      }
    }
    
    cloudGenerator = new CloudGenerator(freq);
    cloudGenerator.setLanguages(termbank.getLanguages());
    cloudGenerator.setTermTypes(termbank.getTypes());
    cloudGenerator.setForeground(fontColorMenu.getColor());
    cloudGenerator.setBackground(backgroundColorMenu.getColor());

    regenerateTree();
    displayCloud();
  }
  
  private void displayCloud() {
    try {
      termCloud.setDocument(new ByteArrayInputStream(cloudGenerator.getHTML(cloudSize.getValue()).getBytes()),"http://term-cloud.com");
    }catch (Exception e) {
      e.printStackTrace();
    }
  }

  public String getHTML() {
    return cloudGenerator.getHTML(cloudSize.getValue());
  }
  
  protected void regenerateTree() {
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("Terms");
    populateTree(root, termbank);
    tree.setModel(new DefaultTreeModel(root));
    controlPanel.repaint();
  }
  
  
  protected void generateEmptyTree() {
    tree = new JTree();
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("Use the controls above to set the thresholds and generate this tree.");
    tree.setModel(new DefaultTreeModel(root));
  }

}


class MiscTableModel extends AbstractTableModel {
  private static final long serialVersionUID = -1610308603693793731L;
  
  private Map<String, String> contents;
  private List<String> keys;
  
  public MiscTableModel(Map<String, String> map) {
    this.contents = map;
    this.keys = new ArrayList<String>(map.keySet());
    Collections.sort(keys);
  }
  
  @Override
  public int getRowCount() {
    return contents.size();
  }

  @Override
  public int getColumnCount() {
    return 2;
  }

  @Override
  public Object getValueAt(int rowIndex, int columnIndex) {
    if (columnIndex == 0) {
      return keys.get(rowIndex);
    }
    else {
      return contents.get(keys.get(rowIndex));
    }
  }
  
}