package edu.cmu.minorthird.ui; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.border.TitledBorder; import edu.cmu.minorthird.text.FancyLoader; import edu.cmu.minorthird.util.CommandLineProcessor; import edu.cmu.minorthird.util.ProgressCounter; import edu.cmu.minorthird.util.StringUtil; import edu.cmu.minorthird.util.gui.ComponentViewer; import edu.cmu.minorthird.util.gui.Console; import edu.cmu.minorthird.util.gui.SmartVanillaViewer; import edu.cmu.minorthird.util.gui.TypeSelector; import edu.cmu.minorthird.util.gui.Viewer; import edu.cmu.minorthird.util.gui.ViewerFrame; /** * Main UI program. With enough support to make it configurable interactively, * by command lines, or by a file. * */ public abstract class UIMain implements CommandLineProcessor.Configurable, Console.Task{ private JPanel errorPanel; public static JButton viewButton; public Console.Task main; // // some basic parameters and CommandLineProcessor items shared by everyone // protected CommandLineUtil.BaseParams base=new CommandLineUtil.BaseParams(); protected CommandLineUtil.GUIParams gui=new CommandLineUtil.GUIParams(); public CommandLineUtil.BaseParams getBaseParameters(){ return base; } public void setBaseParameters(CommandLineUtil.BaseParams base){ this.base=base; } public void helloWorld(){ System.out.println("hello world"); } /** Do the main action, after setting all parameters. */ @Override abstract public void doMain(); /** Return the result of the action. */ @Override abstract public Object getMainResult(); /** Returns whether base.labels exits */ @Override public boolean getLabels(){ return(base.labels!=null); } /** Helper to handle command-line processing, in either gui or text mode. */ public void callMain(final String[] args){ try{ CommandLineProcessor clp=getCLP(); clp.processArguments(args); if(clp.shouldTerminate()){ return; } if(!gui.useGUI){ if(base.labels==null) throw new IllegalArgumentException("-labels must be specified"); if(base.showLabels) new ViewerFrame("Labeled TextBase", new SmartVanillaViewer(base.labels)); doMain(); }else{ main=this; final Viewer v=new ComponentViewer(){ static final long serialVersionUID=20071024L; @Override public JComponent componentFor(Object o){ Viewer ts; if(base.classic) ts= new TypeSelector(SelectableTypes.CLASSES, "selectableTypes.txt",o.getClass()); else ts= new TypeSelector(SelectableTypes.CLASSES, InLineSelectableTypes.CLASSES,AdvancedParameters.NAMES, "selectableTypes.txt",o.getClass()); ts.setContent(o); // we'll put the type selector in a nice panel JPanel panel=new JPanel(); panel.setBorder(new TitledBorder(StringUtil.toString(args, "Command line: ",""," "))); panel.setLayout(new GridBagLayout()); GridBagConstraints gbc; // another panel to allow parameter modifications JPanel subpanel1=new JPanel(); subpanel1.setBorder(new TitledBorder("Parameter modification")); subpanel1.add(ts); gbc=Viewer.fillerGBC(); gbc.weighty=0; panel.add(subpanel1,gbc); // a control panel for controls JPanel subpanel2=new JPanel(); subpanel2.setBorder(new TitledBorder("Execution controls")); // a button to show the results viewButton=new JButton(new AbstractAction("View results"){ static final long serialVersionUID=20071024L; @Override public void actionPerformed(ActionEvent event){ Viewer rv=new SmartVanillaViewer(); rv.setContent(getMainResult()); new ViewerFrame("Result",rv); } }); viewButton.setEnabled(false); // another panel for error messages and other outputs errorPanel=new JPanel(); errorPanel.setBorder(new TitledBorder("Error messages and output")); final Console console= new Console(main,base.labels!=null,viewButton); errorPanel.add(console.getMainComponent()); // a button to start this thread JButton goButton=new JButton(new AbstractAction("Start Task"){ static final long serialVersionUID=20071024L; @Override public void actionPerformed(ActionEvent event){ console.start(); } }); // and a button to show the current labels JButton showLabelsButton= new JButton(new AbstractAction("Show labels"){ static final long serialVersionUID=20071024L; @Override public void actionPerformed(ActionEvent ev){ if(base.labels==null) noLabelsMessage(console); else new ViewerFrame("Labeled TextBase", new SmartVanillaViewer(base.labels)); } }); // and a button to clear the errorArea JButton clearButton=new JButton(new AbstractAction("Clear window"){ static final long serialVersionUID=20071024L; @Override public void actionPerformed(ActionEvent ev){ console.clear(); } }); // and a button for help JButton helpParamsButton= new JButton(new AbstractAction("Parameters"){ static final long serialVersionUID=20071024L; @Override public void actionPerformed(ActionEvent ev){ PrintStream oldSystemOut=System.out; ByteArrayOutputStream outBuffer=new ByteArrayOutputStream(); System.setOut(new PrintStream(outBuffer)); getCLP().usage(); console.append(outBuffer.toString()); System.setOut(oldSystemOut); } }); // and another JButton helpRepositoryButton= new JButton(new AbstractAction("Repository"){ static final long serialVersionUID=20071024L; @Override public void actionPerformed(ActionEvent ev){ repositoryHelp(console); } }); subpanel2.add(goButton); subpanel2.add(viewButton); subpanel2.add(showLabelsButton); subpanel2.add(clearButton); subpanel2.add(new JLabel("Help:")); subpanel2.add(helpParamsButton); subpanel2.add(helpRepositoryButton); gbc=Viewer.fillerGBC(); gbc.weighty=0; gbc.gridy=1; panel.add(subpanel2,gbc); gbc=Viewer.fillerGBC(); gbc.weighty=1; gbc.gridy=2; panel.add(errorPanel,gbc); // now some progress bars JProgressBar progressBar1=new JProgressBar(); JProgressBar progressBar2=new JProgressBar(); JProgressBar progressBar3=new JProgressBar(); ProgressCounter.setGraphicContext(new JProgressBar[]{progressBar1, progressBar2,progressBar3}); gbc=Viewer.fillerGBC(); gbc.weighty=0; gbc.gridy=3; panel.add(progressBar1,gbc); gbc=Viewer.fillerGBC(); gbc.weighty=0; gbc.gridy=4; panel.add(progressBar2,gbc); gbc=Viewer.fillerGBC(); gbc.weighty=0; gbc.gridy=5; panel.add(progressBar3,gbc); return panel; } }; v.setContent(this); String className= this.getClass().toString().substring("class ".length()); ViewerFrame f=new ViewerFrame(className,v); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }catch(Exception e){ e.printStackTrace(); System.out.println("Use option -help for help"); } } public void noLabelsMessage(Console console){ console.append("\nYou need to specify the labeled data you're using!\n" +"Modify the 'labels' parameters under base parameters section\n" +"of the parameter modification window.\n"); } private void repositoryHelp(Console console){ console .append("The Minorthird repository is a collection of data previously labeled for extraction\n" +"or classification learning. One version of the repository containing public data is on:\n" +" /afs/cs/project/extract-learn/repository.\n" +"\n" +"Your repository is now configured as follows:\n"+" "+ FancyLoader.SCRIPTDIR_PROP+ " => "+ FancyLoader.getProperty(FancyLoader.SCRIPTDIR_PROP)+ "\n"+ " "+ FancyLoader.DATADIR_PROP+ " => "+ FancyLoader.getProperty(FancyLoader.DATADIR_PROP)+ "\n"+ " "+ FancyLoader.LABELDIR_PROP+ " => "+ FancyLoader.getProperty(FancyLoader.LABELDIR_PROP)+ "\n"+ "To change these parameters, put new values in a file \"data.properties\" on your classpath.\n"+ "\n"+ FancyLoader.SCRIPTDIR_PROP+ " should contain bean shell scripts that return labeled datasets,\n"+ "encoded as TextLabels objects. Usually these load documents from the directory pointed to by\n"+ FancyLoader.DATADIR_PROP+ " and load labels from the directory pointed to by\n"+ FancyLoader.LABELDIR_PROP+ "\n\n"+ "Instead of using script names from repositories as the \"keys\" for the -labels options\n"+ "you can also use the name of (a) a directory containing XML-marked up data (b) the common stem\n"+ "\"foo\" of a pair of files foo.base and foo.labels or (c) the common stem of a pair foo.labels\n"+ "and foo, where foo is a directory.\n"); } }