Java tutorial
/* Copyright 2010, 2011 Semantic Web Research Center, KAIST This file is part of JHanNanum. JHanNanum 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. JHanNanum 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 JHanNanum. If not, see <http://www.gnu.org/licenses/> */ package kr.ac.kaist.swrc.jhannanum.demo; import kr.ac.kaist.swrc.jhannanum.hannanum.Workflow; import kr.ac.kaist.swrc.jhannanum.plugin.MajorPlugin.MorphAnalyzer.ChartMorphAnalyzer.ChartMorphAnalyzer; import kr.ac.kaist.swrc.jhannanum.plugin.MajorPlugin.PosTagger.HmmPosTagger.HMMTagger; import kr.ac.kaist.swrc.jhannanum.plugin.SupplementPlugin.MorphemeProcessor.SimpleMAResult09.SimpleMAResult09; import kr.ac.kaist.swrc.jhannanum.plugin.SupplementPlugin.MorphemeProcessor.SimpleMAResult22.SimpleMAResult22; import kr.ac.kaist.swrc.jhannanum.plugin.SupplementPlugin.MorphemeProcessor.UnknownMorphProcessor.UnknownProcessor; import kr.ac.kaist.swrc.jhannanum.plugin.SupplementPlugin.PlainTextProcessor.InformalSentenceFilter.InformalSentenceFilter; import kr.ac.kaist.swrc.jhannanum.plugin.SupplementPlugin.PlainTextProcessor.SentenceSegmentor.SentenceSegmentor; import kr.ac.kaist.swrc.jhannanum.plugin.SupplementPlugin.PosProcessor.NounExtractor.NounExtractor; import kr.ac.kaist.swrc.jhannanum.plugin.SupplementPlugin.PosProcessor.SimplePOSResult09.SimplePOSResult09; import kr.ac.kaist.swrc.jhannanum.plugin.SupplementPlugin.PosProcessor.SimplePOSResult22.SimplePOSResult22; import kr.ac.kaist.swrc.jhannanum.share.JSONReader; import org.json.JSONException; import javax.swing.*; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeSelectionModel; import java.awt.*; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.event.*; import java.io.*; import java.util.HashMap; /** * This is a GUI-based demo program of the HanNanum that helps users to understand the concept * of work flow and use the HanNanum library easily. It shows a window that has components for plug-in pool, * work flow, plug-in information, work flow controls, input text and analysis result. Users can easily * set up various work flows by drag-and-drop the plug-ins from the plug-in pool to the work flow component, * and see the analysis result. <br> * <br> * Users can use this GUI demo program by following procedure:<br> * 1. Browse the plug-ins in the plug-in pool. The brief information about the selected plug-in will be * displayed so that you can refer the information when set the work flow up.<br> * 2. Drag and drop plug-ins from the plug-in pool to the list in the work flow considering the phase * and type of the plug-in.<br> * - If you want to remove the plug-in on the work flow, simply double click it.<br> * - If you change the order of the supplement plug-ins in each phase, simply drag and drop a plug-in * to the position you want.<br> * 3. Once you finish to set the work flow up, choose 'Multi-thread Mode' or 'Single-thread Mode'.<br> * 4. Click 'Activate the work flow' button.<br> * 5. Type or copy-and-past text that you want to analyze into the 'Input Text' area.<br> * 6. Click 'Analyze Text' button.<br> * 7. You can see the analysis result on 'Result' area.<br> * 8. Repeat 5~7 to analyze other text with the activated work flow.<br> * Or click 'Close the work flow' button and go to step 1 to set up new work flow.<br> * <br> * @author Sangwon Park (hudoni@world.kaist.ac.kr), CILab, SWRC, KAIST */ public class GUIDemo { private JFrame mainFrame = null; private JMenuBar menuBar = null; private JMenu menuFile = null; private JMenu menuHelp = null; private JMenuItem menuItemFileOpen = null; private JMenuItem menuItemHelp = null; private JTree tree; private HashMap<String, String> pluginInfoMap = null; private JList listPluginMajor2 = null; private JList listPluginMajor3 = null; private JList listPluginSupplement1 = null; private JList listPluginSupplement2 = null; private JList listPluginSupplement3 = null; private DefaultListModel listModelMajor2 = null; private DefaultListModel listModelMajor3 = null; private DefaultListModel listModelSupplement1 = null; private DefaultListModel listModelSupplement2 = null; private DefaultListModel listModelSupplement3 = null; private JTextArea areaPluginInfo = null; private JTextArea inputTextArea = null; private JTextArea outputTextArea = null; private JSplitPane splitPaneTop = null; private JSplitPane splitPaneBottom = null; private JRadioButton radioMultiThread = null; private JRadioButton radioSingleThread = null; private JButton buttonActivate = null; private JButton buttonAnalysis = null; private JButton buttonReset = null; private PluginInfo selectedPlugin = null; private PluginInfo tempPlugin = null; private boolean multiThreadMode = true; private boolean activated = false; private Workflow workflow = null; /** * Run this demo program. * @param args */ public static void main(String[] args) { GUIDemo demo = new GUIDemo(); demo.run(); } /** * Sets the GUI up and launch the demo. */ public void run() { /////////////////////////////////////////////////////////////////// // Basic setting for the mainFrame /////////////////////////////////////////////////////////////////// mainFrame = new JFrame(); Toolkit kit = mainFrame.getToolkit(); Dimension windowSize = kit.getScreenSize(); mainFrame.setBounds(windowSize.width / 20, windowSize.height / 20, windowSize.width * 18 / 20, windowSize.height * 18 / 20); mainFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); mainFrame.setTitle("HanNanum Korean Morphological Analyzer - A Plug-in Component based System (GUI Demo)"); Font font = new Font("MonoSpaced", Font.PLAIN, 12); UIManager.put("TextArea.font", font); /////////////////////////////////////////////////////////////////// // Layout setting for the mainFrame /////////////////////////////////////////////////////////////////// mainFrame.setLayout(new BorderLayout()); mainFrame.getContentPane().add(createPaneCenter(), BorderLayout.CENTER); mainFrame.getContentPane().add(createPaneNorth(), BorderLayout.NORTH); /////////////////////////////////////////////////////////////////// // Menu Setting /////////////////////////////////////////////////////////////////// menuBar = new JMenuBar(); menuFile = new JMenu("File"); menuItemFileOpen = new JMenuItem("Open", KeyEvent.VK_O); menuHelp = new JMenu("Help"); menuItemHelp = new JMenuItem("Help", KeyEvent.VK_H); menuItemFileOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.ALT_MASK)); menuItemHelp.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H, ActionEvent.ALT_MASK)); menuBar.add(menuFile); menuBar.add(menuHelp); menuFile.add(menuItemFileOpen); menuHelp.add(menuItemHelp); mainFrame.setJMenuBar(menuBar); /////////////////////////////////////////////////////////////////// // Event Handler Setting /////////////////////////////////////////////////////////////////// menuItemFileOpen.addActionListener(new SharedActionHandler()); menuItemHelp.addActionListener(new SharedActionHandler()); buttonActivate.addActionListener(new SharedActionHandler()); buttonAnalysis.addActionListener(new SharedActionHandler()); buttonReset.addActionListener(new SharedActionHandler()); radioMultiThread.addActionListener(new SharedActionHandler()); radioSingleThread.addActionListener(new SharedActionHandler()); listPluginMajor2.addMouseListener(new PluginListMouseListener(listPluginMajor2, listModelMajor2)); listPluginMajor3.addMouseListener(new PluginListMouseListener(listPluginMajor3, listModelMajor3)); listPluginSupplement1 .addMouseListener(new PluginListMouseListener(listPluginSupplement1, listModelSupplement1)); listPluginSupplement2 .addMouseListener(new PluginListMouseListener(listPluginSupplement2, listModelSupplement2)); listPluginSupplement3 .addMouseListener(new PluginListMouseListener(listPluginSupplement3, listModelSupplement3)); listPluginMajor2.setTransferHandler(new PluginTransferHandler(PluginInfo.PHASE2, PluginInfo.MAJOR)); listPluginMajor3.setTransferHandler(new PluginTransferHandler(PluginInfo.PHASE3, PluginInfo.MAJOR)); listPluginSupplement1 .setTransferHandler(new PluginTransferHandler(PluginInfo.PHASE1, PluginInfo.SUPPLEMENT)); listPluginSupplement2 .setTransferHandler(new PluginTransferHandler(PluginInfo.PHASE2, PluginInfo.SUPPLEMENT)); listPluginSupplement3 .setTransferHandler(new PluginTransferHandler(PluginInfo.PHASE3, PluginInfo.SUPPLEMENT)); listPluginSupplement1.setDropMode(DropMode.ON_OR_INSERT); listPluginSupplement2.setDropMode(DropMode.ON_OR_INSERT); listPluginSupplement3.setDropMode(DropMode.ON_OR_INSERT); listPluginMajor2.setDropMode(DropMode.ON_OR_INSERT); listPluginMajor3.setDropMode(DropMode.ON_OR_INSERT); listPluginMajor2.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); listPluginMajor3.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); listPluginSupplement1.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); listPluginSupplement2.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); listPluginSupplement3.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); listPluginMajor2.setDragEnabled(true); listPluginMajor3.setDragEnabled(true); listPluginSupplement1.setDragEnabled(true); listPluginSupplement2.setDragEnabled(true); listPluginSupplement3.setDragEnabled(true); tree.setDragEnabled(true); tempPlugin = new PluginInfo("", 0, 0); workflow = new Workflow(); // Show the main frame on the screen mainFrame.setVisible(true); for (int i = 0; i < tree.getRowCount(); i++) { tree.expandRow(i); } splitPaneTop.setDividerLocation(0.3); splitPaneBottom.setDividerLocation(0.5); } /** * Setting of the split panel for plug-in pool and the work flow. * @return the split panel */ private JComponent createPaneNorth() { splitPaneTop = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); splitPaneTop.setLeftComponent(createPluginPool()); splitPaneTop.setRightComponent(createWorkflow()); splitPaneTop.setOneTouchExpandable(true); return splitPaneTop; } /** * Setting of the plug-in tree view. * @return the plug-in tree view */ private JComponent createPluginPool() { DefaultMutableTreeNode top = new DefaultMutableTreeNode("HanNanum Plug-in Pool"); createPluginNodes(top); loadPluginInformation(); tree = new JTree(top); tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); tree.addTreeSelectionListener(new PluginTreeSelectionListener()); tree.putClientProperty("JTree.lineStyle", "Horizontal"); JScrollPane treeView = new JScrollPane(tree); return treeView; } /** * Setting of the each plug-in which is in the tree view. * @param top - default top tree node */ private void createPluginNodes(DefaultMutableTreeNode top) { DefaultMutableTreeNode phase = null; DefaultMutableTreeNode type = null; phase = new DefaultMutableTreeNode("Phase1 Plug-in. Plain Text Processing"); type = new DefaultMutableTreeNode("Supplement Plugin"); type.add(new DefaultMutableTreeNode( new PluginInfo("InformalSentenceFilter", PluginInfo.PHASE1, PluginInfo.SUPPLEMENT))); type.add(new DefaultMutableTreeNode( new PluginInfo("SentenceSegmentor", PluginInfo.PHASE1, PluginInfo.SUPPLEMENT))); phase.add(type); top.add(phase); phase = new DefaultMutableTreeNode("Phase2 Plug-in. Morphological Analysis"); type = new DefaultMutableTreeNode("Major Plug-in"); type.add(new DefaultMutableTreeNode( new PluginInfo("ChartMorphAnalyzer", PluginInfo.PHASE2, PluginInfo.MAJOR))); phase.add(type); type = new DefaultMutableTreeNode("Supplement Plug-in"); type.add(new DefaultMutableTreeNode( new PluginInfo("UnknownMorphProcessor", PluginInfo.PHASE2, PluginInfo.SUPPLEMENT))); type.add(new DefaultMutableTreeNode( new PluginInfo("SimpleMAResult09", PluginInfo.PHASE2, PluginInfo.SUPPLEMENT))); type.add(new DefaultMutableTreeNode( new PluginInfo("SimpleMAResult22", PluginInfo.PHASE2, PluginInfo.SUPPLEMENT))); phase.add(type); top.add(phase); phase = new DefaultMutableTreeNode("Phase3 Plug-in. Part Of Speech Tagging"); type = new DefaultMutableTreeNode("Major Plug-in"); type.add(new DefaultMutableTreeNode(new PluginInfo("HmmPosTagger", PluginInfo.PHASE3, PluginInfo.MAJOR))); phase.add(type); type = new DefaultMutableTreeNode("Supplement Plug-in"); type.add(new DefaultMutableTreeNode( new PluginInfo("NounExtractor", PluginInfo.PHASE3, PluginInfo.SUPPLEMENT))); type.add(new DefaultMutableTreeNode( new PluginInfo("SimplePOSResult09", PluginInfo.PHASE3, PluginInfo.SUPPLEMENT))); type.add(new DefaultMutableTreeNode( new PluginInfo("SimplePOSResult22", PluginInfo.PHASE3, PluginInfo.SUPPLEMENT))); phase.add(type); top.add(phase); } /** * It loads the meta information for each plug-in from the configuration files. */ private void loadPluginInformation() { try { pluginInfoMap = new HashMap<String, String>(); pluginInfoMap.put("InformalSentenceFilter", getPluginAbstarct( "conf/plugin/SupplementPlugin/PlainTextProcessor/InformalSentenceFilter.json")); pluginInfoMap.put("SentenceSegmentor", getPluginAbstarct("conf/plugin/SupplementPlugin/PlainTextProcessor/SentenceSegmentor.json")); pluginInfoMap.put("ChartMorphAnalyzer", getPluginAbstarct("conf/plugin/MajorPlugin/MorphAnalyzer/ChartMorphAnalyzer.json")); pluginInfoMap.put("UnknownMorphProcessor", getPluginAbstarct("conf/plugin/SupplementPlugin/MorphemeProcessor/UnknownMorphProcessor.json")); pluginInfoMap.put("SimpleMAResult09", getPluginAbstarct("conf/plugin/SupplementPlugin/MorphemeProcessor/SimpleMAResult09.json")); pluginInfoMap.put("SimpleMAResult22", getPluginAbstarct("conf/plugin/SupplementPlugin/MorphemeProcessor/SimpleMAResult22.json")); pluginInfoMap.put("HmmPosTagger", getPluginAbstarct("conf/plugin/MajorPlugin/PosTagger/HmmPosTagger.json")); pluginInfoMap.put("NounExtractor", getPluginAbstarct("conf/plugin/SupplementPlugin/PosProcessor/NounExtractor.json")); pluginInfoMap.put("SimplePOSResult09", getPluginAbstarct("conf/plugin/SupplementPlugin/PosProcessor/SimplePOSResult09.json")); pluginInfoMap.put("SimplePOSResult22", getPluginAbstarct("conf/plugin/SupplementPlugin/PosProcessor/SimplePOSResult22.json")); } catch (JSONException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * Returns the abstract text for a plug-in from the specified configuration file. * @param filePath - the configuration file for the plug-in written in JSON format * @return the abstract text for the specified plug-in * @throws JSONException * @throws IOException */ private String getPluginAbstarct(String filePath) throws JSONException, IOException { JSONReader json = new JSONReader(filePath); String res = null; res = String.format("* Name: %s\n* Type: %s\n* Version: %s\n* Author: %s\n* Description: %s\n", json.getName(), json.getType(), json.getVersion(), json.getAuthor(), json.getDescription()); return res; } /** * This class has the properties of a HanNanum plug-in. * * @author Sangwon Park (hudoni@world.kaist.ac.kr), CILab, SWRC, KAIST */ private class PluginInfo { /** * A plug-in for the first phase on the work flow. */ public static final int PHASE1 = 1; /** * A plug-in for the second phase one the work flow. */ public static final int PHASE2 = 2; /** * A plug-in for the third phase on the work flow. */ public static final int PHASE3 = 3; /** * A plug-in that is a major. */ public static final int MAJOR = 1; /** * A plug-in that is a supplement. */ public static final int SUPPLEMENT = 2; /** * The name of the plug-in. */ public String name = null; /** * The phase of the plug-in on the work flow. PHASE1 or PHASE2 or PHASE3. */ public int phase = 0; /** * The type of the plug-in. MAJOR or SUPPLEMENT. */ public int type = 0; /** * Constructor. * @param name - the name of the plug-in * @param phase - the phase of the plug-in on the work flow. PHASE1 or PHASE2 or PHASE3. * @param type - the type of the plug-in. MAJOR or SUPPLEMENT. */ public PluginInfo(String name, int phase, int type) { this.name = name; this.phase = phase; this.type = type; } /** * Returns the name of the plug-in. */ public String toString() { return name; } } /** * Event listener for the plug-in selection on the tree view. * * @author Sangwon Park (hudoni@world.kaist.ac.kr), CILab, SWRC, KAIST */ private class PluginTreeSelectionListener implements TreeSelectionListener { /** * It is called when the new plug-in was selected. */ public void valueChanged(TreeSelectionEvent e) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if (node == null) { selectedPlugin = null; return; } Object nodeInfo = node.getUserObject(); if (node.isLeaf()) { selectedPlugin = (PluginInfo) nodeInfo; areaPluginInfo.setText(pluginInfoMap.get((selectedPlugin.name))); } else { selectedPlugin = null; } } } /** * Event listener for the plug-in selection on the list for the work flow. * * @author Sangwon Park (hudoni@world.kaist.ac.kr), CILab, SWRC, KAIST */ private class PluginListMouseListener implements MouseListener { /** * The plug-in list where this listener is going to work. */ private JList list = null; /** * The model of plug-in list where this listener is going to work. */ private DefaultListModel listModel = null; /** * Constructor. * @param list - the plug-in list for the work flow * @param listModel - the model for the plug-in list */ public PluginListMouseListener(JList list, DefaultListModel listModel) { this.list = list; this.listModel = listModel; } /** * It is called when an mouse click event occur on the list. */ @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { listModel.remove(this.list.locationToIndex(e.getPoint())); } else { try { areaPluginInfo.setText( pluginInfoMap.get((String) listModel.get(this.list.locationToIndex(e.getPoint())))); } catch (Exception e1) { } } } /** * It is called when an mouse enter event occur on the list. */ @Override public void mouseEntered(MouseEvent e) { } /** * It is called when an mouse exited event occur on the list. */ @Override public void mouseExited(MouseEvent e) { } /** * It is called when an mouse pressed event occur on the list. */ @Override public void mousePressed(MouseEvent e) { } /** * It is called when an mouse released event occur on the list. */ @Override public void mouseReleased(MouseEvent e) { } } /** * Returns the panel for the work flow. * * @return the panel for the work flow */ private JComponent createWorkflow() { JPanel workflowPanel = new JPanel(new GridLayout(1, 3)); listModelMajor2 = new DefaultListModel(); listModelMajor3 = new DefaultListModel(); listModelSupplement1 = new DefaultListModel(); listModelSupplement2 = new DefaultListModel(); listModelSupplement3 = new DefaultListModel(); listPluginMajor2 = new JList(listModelMajor2); listPluginMajor3 = new JList(listModelMajor3); listPluginSupplement1 = new JList(listModelSupplement1); listPluginSupplement2 = new JList(listModelSupplement2); listPluginSupplement3 = new JList(listModelSupplement3); // phase1 JPanel phasePanel = new JPanel(new GridLayout(1, 1)); phasePanel.setBorder(BorderFactory.createTitledBorder("Phase1. Plain Text Processing")); JPanel listPanel = new JPanel(new GridLayout(1, 1)); listPanel.setBorder(BorderFactory.createTitledBorder("Supplement Plug-in")); JScrollPane scroll = new JScrollPane(); scroll.setViewportView(listPluginSupplement1); listPanel.add(scroll); phasePanel.add(listPanel); workflowPanel.add(phasePanel); // phase2 phasePanel = new JPanel(new GridLayout(1, 2)); phasePanel.setBorder(BorderFactory.createTitledBorder("Phase2. Morphological Analysis")); listPanel = new JPanel(new GridLayout(1, 1)); listPanel.setBorder(BorderFactory.createTitledBorder("Major Plug-in")); scroll = new JScrollPane(); scroll.setViewportView(listPluginMajor2); listPanel.add(scroll); phasePanel.add(listPanel); listPanel = new JPanel(new GridLayout(1, 1)); listPanel.setBorder(BorderFactory.createTitledBorder("Supplement Plug-in")); scroll = new JScrollPane(); scroll.setViewportView(listPluginSupplement2); listPanel.add(scroll); phasePanel.add(listPanel); workflowPanel.add(phasePanel); // phase3 phasePanel = new JPanel(new GridLayout(1, 2)); phasePanel.setBorder(BorderFactory.createTitledBorder("Phase3. Part Of Speech Tagging")); listPanel = new JPanel(new GridLayout(1, 1)); listPanel.setBorder(BorderFactory.createTitledBorder("Major Plug-in")); scroll = new JScrollPane(); scroll.setViewportView(listPluginMajor3); listPanel.add(scroll); phasePanel.add(listPanel); listPanel = new JPanel(new GridLayout(1, 1)); listPanel.setBorder(BorderFactory.createTitledBorder("Supplement Plug-in")); scroll = new JScrollPane(); scroll.setViewportView(listPluginSupplement3); listPanel.add(scroll); phasePanel.add(listPanel); workflowPanel.add(phasePanel); ///////////////////////////////////////////////////////////////////////////////////// JPanel controlPanel = new JPanel(new GridLayout(4, 1)); controlPanel.setBorder(BorderFactory.createTitledBorder("Workflow Control")); buttonActivate = new JButton("Activate the workflow"); buttonAnalysis = new JButton("Analyze Text"); buttonReset = new JButton("Close the workflow"); JPanel threadPanel = new JPanel(new GridLayout(1, 1)); radioMultiThread = new JRadioButton("Mutli-thread Mode", true); radioSingleThread = new JRadioButton("Single-thread Mode", false); threadPanel.setBorder(BorderFactory.createTitledBorder("Thread Mode")); threadPanel.add(radioMultiThread); threadPanel.add(radioSingleThread); ButtonGroup groupThread = new ButtonGroup(); groupThread.add(radioMultiThread); groupThread.add(radioSingleThread); controlPanel.add(threadPanel); controlPanel.add(buttonActivate); controlPanel.add(buttonAnalysis); controlPanel.add(buttonReset); buttonAnalysis.setEnabled(false); buttonReset.setEnabled(false); ///////////////////////////////////////////////////////////////////////////////////// JPanel pluginInfoPanel = new JPanel(new GridLayout(1, 1)); pluginInfoPanel.setBorder(BorderFactory.createTitledBorder("Plug-in Information")); areaPluginInfo = new JTextArea(); areaPluginInfo.setLineWrap(true); scroll = new JScrollPane(); scroll.setViewportView(areaPluginInfo); pluginInfoPanel.add(scroll); JPanel infoPanel = new JPanel(new GridLayout(1, 2)); infoPanel.add(pluginInfoPanel); infoPanel.add(controlPanel); JPanel panel = new JPanel(new GridLayout(2, 1)); workflowPanel.setBorder(BorderFactory.createTitledBorder("HanNanum Workflow")); panel.add(workflowPanel); panel.add(infoPanel); return panel; } /** * Returns a panel for the input and output text areas. * * @return a panel for the input and output text areas */ private JComponent createPaneCenter() { splitPaneBottom = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); JPanel panel = new JPanel(new GridLayout(1, 1)); panel.setBorder(BorderFactory.createTitledBorder("Input Text")); inputTextArea = new JTextArea(); JScrollPane scroll = new JScrollPane(); scroll.setViewportView(inputTextArea); panel.add(scroll); splitPaneBottom.setLeftComponent(panel); panel = new JPanel(new GridLayout(1, 1)); panel.setBorder(BorderFactory.createTitledBorder("Result")); outputTextArea = new JTextArea(); scroll = new JScrollPane(); scroll.setViewportView(outputTextArea); panel.add(scroll); splitPaneBottom.setRightComponent(panel); splitPaneBottom.setOneTouchExpandable(true); return splitPaneBottom; } /** * The event handler that is used in various purpose. * * @author Sangwon Park (hudoni@world.kaist.ac.kr), CILab, SWRC, KAIST */ private class SharedActionHandler implements ActionListener { /** * Performs an action depending on the given action event. */ public void actionPerformed(ActionEvent e) { try { Object source = e.getSource(); if (source == menuItemFileOpen) { fileOpen(); } else if (source == menuItemHelp) { help(); } else if (source == buttonActivate) { initWorkflow(); activateWorkflow(); } else if (source == buttonAnalysis) { analyzeText(); } else if (source == buttonReset) { reset(); } else if (source == radioMultiThread) { multiThreadMode = true; } else if (source == radioSingleThread) { multiThreadMode = false; } } catch (Exception e1) { e1.printStackTrace(); } } /** * Reads a text file, and use the text as the input data. */ private void fileOpen() { JFileChooser chooser = new JFileChooser(); chooser.setCurrentDirectory(new java.io.File(".")); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.setAcceptAllFileFilterUsed(false); if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) { File selectedFile = chooser.getSelectedFile(); try { BufferedReader br = new BufferedReader(new FileReader(selectedFile)); String line = null; while ((line = br.readLine()) != null) { inputTextArea.append(line + "\n"); } br.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } /** * Show 'help' window. */ private void help() { String helpStr = " This is a GUI-based demo program of the HanNanum that helps users to understand the concept\n" + "of work flow and use the HanNanum library easily. This consists of components for plug-in pool,\n" + "work flow, plug-in information, work flow controls, input text and analysis result. Users can\n" + "easily set up various work flows by drag-and-drop the plug-ins from the plug-in pool to the work\n" + "flow component, and see the analysis result.\n\n" + " Users can use this GUI demo program by following procedure:\n\n" + " 1. Browse the plug-ins in the plug-in pool. The brief information about the selected plug-in will be\n" + " displayed so that you can refer the information when set the work flow up.\n\n" + " 2. Drag and drop plug-ins from the plug-in pool to the list in the work flow considering the phase\n" + " and type of the plug-in.\n " + " - If you want to remove the plug-in on the work flow, simply double click it.\n " + " - If you change the order of the supplement plug-ins in each phase, simply drag and drop a plug-in\n" + " to the position you want.\n\n" + " 3. Once you finish to set the work flow up, choose 'Multi-thread Mode' or 'Single-thread Mode'.\n\n" + " 4. Click 'Activate the work flow' button.\n\n" + " 5. Type or copy-and-past text that you want to analyze into the 'Input Text' area.\n\n" + " 6. Click 'Analyze Text' button.\n\n" + " 7. You can see the analysis result on 'Result' area.\n\n" + " 8. Repeat 5~7 to analyze other text with the activated work flow.\n" + " Or click 'Close the work flow' button and go to step 1 to set up new work flow. \n\n" + " Author: Sangwon Park (hudoni@world.kaist.ac.kr), CILab, SWRC, KAIST\n"; JOptionPane.showMessageDialog(mainFrame, helpStr); } /** * Initialize the work flow with the sequence of the plug-ins that the user selected. */ private void initWorkflow() { /* Clear the previous work flow */ workflow.clear(); /* Set the work flow up */ String pluginName = null; // phase1 plug-in for (int i = 0; i < listModelSupplement1.size(); i++) { pluginName = (String) listModelSupplement1.get(i); if (pluginName.equals("InformalSentenceFilter")) { workflow.appendPlainTextProcessor(new InformalSentenceFilter(), null); } else if (pluginName.equals("SentenceSegmentor")) { workflow.appendPlainTextProcessor(new SentenceSegmentor(), null); } } // phase2 plug-in if (listModelMajor2.size() > 0) { pluginName = (String) listModelMajor2.get(0); if (pluginName.equals("ChartMorphAnalyzer")) { workflow.setMorphAnalyzer(new ChartMorphAnalyzer(), "conf/plugin/MajorPlugin/MorphAnalyzer/ChartMorphAnalyzer.json"); } } else { return; } for (int i = 0; i < listModelSupplement2.size(); i++) { pluginName = (String) listModelSupplement2.get(i); if (pluginName.equals("UnknownMorphProcessor")) { workflow.appendMorphemeProcessor(new UnknownProcessor(), null); } else if (pluginName.equals("SimpleMAResult09")) { workflow.appendMorphemeProcessor(new SimpleMAResult09(), null); } else if (pluginName.equals("SimpleMAResult22")) { workflow.appendMorphemeProcessor(new SimpleMAResult22(), null); } } // phase3 plug-in if (listModelMajor3.size() > 0) { pluginName = (String) listModelMajor3.get(0); if (pluginName.equals("HmmPosTagger")) { workflow.setPosTagger(new HMMTagger(), "conf/plugin/MajorPlugin/PosTagger/HmmPosTagger.json"); } } else { return; } for (int i = 0; i < listModelSupplement3.size(); i++) { pluginName = (String) listModelSupplement3.get(i); if (pluginName.equals("NounExtractor")) { workflow.appendPosProcessor(new NounExtractor(), null); } else if (pluginName.equals("SimplePOSResult09")) { workflow.appendPosProcessor(new SimplePOSResult09(), null); } else if (pluginName.equals("SimplePOSResult22")) { workflow.appendPosProcessor(new SimplePOSResult22(), null); } } } /** * Activates the work flow. */ private void activateWorkflow() { try { workflow.activateWorkflow(multiThreadMode); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } buttonAnalysis.setEnabled(true); buttonReset.setEnabled(true); buttonActivate.setEnabled(false); radioMultiThread.setEnabled(false); radioSingleThread.setEnabled(false); listPluginSupplement1.setEnabled(false); listPluginSupplement2.setEnabled(false); listPluginSupplement3.setEnabled(false); listPluginMajor2.setEnabled(false); listPluginMajor3.setEnabled(false); activated = true; } /** * Analyze the input text with the activated work flow. */ private void analyzeText() { String text = inputTextArea.getText(); if (text != null && text.length() > 0) { workflow.analyze(inputTextArea.getText()); outputTextArea.setText(workflow.getResultOfDocument()); buttonReset.setEnabled(true); buttonActivate.setEnabled(false); } else { outputTextArea.setText(""); } } /** * Reset the work flow and the demo program. */ private void reset() { workflow.clear(); buttonActivate.setEnabled(true); buttonAnalysis.setEnabled(false); buttonReset.setEnabled(false); radioMultiThread.setEnabled(true); radioSingleThread.setEnabled(true); listPluginSupplement1.setEnabled(true); listPluginSupplement2.setEnabled(true); listPluginSupplement3.setEnabled(true); listPluginMajor2.setEnabled(true); listPluginMajor3.setEnabled(true); activated = false; } } /** * Handler for the drag-and-drop functionality of plug-in from the plug-in pool to * the work flow. * * @author Sangwon Park (hudoni@world.kaist.ac.kr), CILab, SWRC, KAIST */ private class PluginTransferHandler extends TransferHandler { /** * serialVersionUID */ private static final long serialVersionUID = 1L; /** * The phase of the plug-in on the work flow. * PluginInfo.PHASE1 or PluginInfo.PHASE2 or PluginInfo.PHASE3. */ private int phase = 0; /** * The type of the plug-in. * PluginInfo.MAJOR or PluginInfo.SUPPLEMENT. */ private int type = 0; /** * Constructor. * @param phase - the phase of the plug-in. PluginInfo.PHASE1 or PluginInfo.PHASE2 or PluginInfo.PHASE3. * @param type - the type of the plug-in. PluginInfo.MAJOR or PluginInfo.SUPPLEMENT. */ public PluginTransferHandler(int phase, int type) { this.phase = phase; this.type = type; } /** * Returns true when it is possible to drag and drop the plug-in. */ public boolean canImport(TransferHandler.TransferSupport info) { if (!activated && selectedPlugin != null && phase == selectedPlugin.phase && type == selectedPlugin.type) { return true; } return false; } /** * It transfers the meta data of the plug-in from the plug-in pool to the work flow list. * * @return true: transference was done correctly, otherwise false */ public boolean importData(TransferHandler.TransferSupport info) { if (!info.isDrop()) { return false; } if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) { return false; } JList.DropLocation dl = (JList.DropLocation) info.getDropLocation(); DefaultListModel listModel = null; int index = dl.getIndex(); switch (selectedPlugin.phase) { case PluginInfo.PHASE1: listModel = (DefaultListModel) listPluginSupplement1.getModel(); break; case PluginInfo.PHASE2: if (selectedPlugin.type == PluginInfo.MAJOR) { listModel = (DefaultListModel) listPluginMajor2.getModel(); listModel.clear(); index = 0; } else if (selectedPlugin.type == PluginInfo.SUPPLEMENT) { listModel = (DefaultListModel) listPluginSupplement2.getModel(); } break; case PluginInfo.PHASE3: if (selectedPlugin.type == PluginInfo.MAJOR) { listModel = (DefaultListModel) listPluginMajor3.getModel(); listModel.clear(); index = 0; } else if (selectedPlugin.type == PluginInfo.SUPPLEMENT) { listModel = (DefaultListModel) listPluginSupplement3.getModel(); } break; } if (listModel == null) { return false; } try { Transferable t = info.getTransferable(); String data = (String) t.getTransferData(DataFlavor.stringFlavor); int pIndex = listModel.indexOf(data); listModel.add(index, data); if (pIndex != -1) { if (pIndex >= index) { pIndex++; } listModel.remove(pIndex); } } catch (Exception e) { return false; } return false; } /** * Returns the type of action at the source component. */ public int getSourceActions(JComponent c) { return COPY; } /** * Make it possible to transfer the selected plug-in. * Just one plug-in can be transfered, but it can be improved. */ protected Transferable createTransferable(JComponent c) { JList list = (JList) c; Object[] values = list.getSelectedValues(); StringBuffer buff = new StringBuffer(); if (values.length >= 0) { Object val = values[0]; buff.append(val); } tempPlugin.name = buff.toString(); tempPlugin.phase = phase; tempPlugin.type = type; selectedPlugin = tempPlugin; return new StringSelection(buff.toString()); } } }