ListenerWindow.java

00001 /* 
00002 ** Author(s): Miguel Calejo
00003 ** Contact:   interprolog@declarativa.com, http://www.declarativa.com
00004 ** Copyright (C) Declarativa, Portugal, 2000-2002
00005 ** Use and distribution, without any warranties, under the terms of the 
00006 ** GNU Library General Public License, readable in http://www.fsf.org/copyleft/lgpl.html
00007 */
00008 package com.declarativa.interprolog.gui;
00009 import com.declarativa.interprolog.*;
00010 import com.declarativa.interprolog.util.*;
00011 import java.util.*;
00012 import java.awt.*;
00013 import java.awt.event.*;
00014 import java.io.*;
00015 import javax.swing.*;
00016 import javax.swing.text.*;
00017 import javax.swing.table.*;
00018 import javax.swing.event.*;
00019 
00022 public abstract class ListenerWindow extends JFrame implements WindowListener{  
00023         public JTextArea prologOutput, prologInput; 
00024         JMenu historyMenu, fileMenu; 
00025         Vector loadedFiles;
00026         private static int topLevelCount = 0;
00027         public PrologEngine engine = null;
00028         
00029         public ListenerWindow(PrologEngine e){
00030                 this(e,true);
00031         }
00032         public ListenerWindow(PrologEngine e, boolean autoDisplay){
00033                 super("PrologEngine listener (Swing)");         
00034                 if (e!=null) engine=e;
00035                 else throw new IPException("missing Prolog engine");            
00036                 //engine.consultFromPackage("visualization.O",ListenerWindow.class);    
00037                 engine.consultFromPackage("visualization.xwam",ListenerWindow.class);   
00038                 engine.teachMoreObjects(guiExamples());
00039                 engine.command("write('Welcome to an InterProlog/XSB top level!')");
00040                 engine.command("xsb_configuration(version,_V), write('XSB version '), writeln(_V)");
00041                                 
00042                 if (engine==null) dispose(); // no interface object permitted!
00043                 else topLevelCount++;
00044                 debug=engine.isDebug();
00045                 
00046                 loadedFiles = new Vector();
00047                 
00048                 constructWindowContents();
00049                 constructMenu();
00050                 
00051                                 
00052                 addWindowListener(this);
00053                 prologInput.addKeyListener(new KeyAdapter(){
00054                         public void keyPressed(KeyEvent e){
00055                                 if (e.getKeyCode()==KeyEvent.VK_ENTER) {
00056                                         sendToProlog();
00057                                         e.consume();
00058                                 }
00059                         }
00060                 });
00061         if (autoDisplay) {
00062                     show();
00063                     focusInput();       
00064                 }
00065                 
00066         }
00067                         
00068         // WindowListener methods
00069         public void windowOpened(WindowEvent e){}
00070         public void windowClosed(WindowEvent e){}
00071         public void windowIconified(WindowEvent e){}
00072         public void windowClosing(WindowEvent e){
00073                 dispose();
00074                 engine.shutdown();
00075                 topLevelCount--;
00076                 if (topLevelCount <= 0) System.exit(0);
00077                         // should check whether any relevant windows are changed...
00078         }
00079         public void windowActivated(WindowEvent e){
00080                 prologInput.requestFocus();
00081         }
00082         public void windowDeactivated(WindowEvent e){}
00083         public void windowDeiconified(WindowEvent e){}
00084         
00085         public static ObjectExamplePair[] guiExamples() {
00086                 ObjectExamplePair[] examples = {
00087                         PredicateTableModel.example(),
00088                         TermListModel.example(),
00089                         TermTreeModel.example(),
00090                         new ObjectExamplePair("ArrayOfTermTreeModel",new TermTreeModel[0]),
00091                         XSBTableModel.example()
00092                 };
00093                 return examples;
00094         }
00095         
00096         void constructWindowContents(){
00097                 Font prologFont = new Font("Courier",Font.PLAIN,12);
00098                 Container c = getContentPane();
00099                 c.setLayout(new BorderLayout());
00100                 prologOutput = new JTextArea(20,80); prologOutput.setFont(prologFont); 
00101                 prologOutput.setEditable(false); 
00102                 prologOutput.setToolTipText("Here's XSB console output");
00103                 prologOutput.setLineWrap(true);  // Swing used to crash with large ammounts of text...
00104                 prologOutput.setDoubleBuffered(true); // Use Swing double screen buffer
00105                 JScrollPane piscroller = new JScrollPane();
00106                 prologInput = new JTextArea(4,80); prologInput.setFont(prologFont); prologInput.setLineWrap(true);
00107                 prologInput.setToolTipText("XSB input, sent when you press enter");
00108                 piscroller.getViewport().add(prologInput); 
00109 
00110                 JScrollPane scroller = new JScrollPane();
00111                 scroller.getViewport().add(prologOutput);
00112                 JSplitPane j = new JSplitPane (JSplitPane.VERTICAL_SPLIT, scroller, prologInput);
00113                 c.add("Center",j);
00114                 setSize(600,600);
00115                 j.setDividerLocation(500);
00116                 //j.resetToPreferredSizes();
00117                 validate();
00118         }
00119         
00120         void constructMenu(){
00121                 JMenuBar mb; 
00122                 mb = new JMenuBar(); setJMenuBar(mb);
00123                 
00124                 fileMenu = new JMenu("File"); mb.add(fileMenu);
00125                 
00126                 addItemToMenu(fileMenu,"Reconsult...",new ActionListener(){
00127                         public void actionPerformed(ActionEvent e){
00128                                 reconsultFile();
00129                         }
00130                 });
00131                 
00132                 addItemToMenu(fileMenu,"Load dynamically...",new ActionListener(){
00133                         public void actionPerformed(ActionEvent e){
00134                                 load_dynFile();
00135                         }
00136                 });
00137                 
00138                 fileMenu.addSeparator();
00139                 
00140                 JMenu toolMenu = new JMenu("Tools"); mb.add(toolMenu);
00141                 
00142                 final JCheckBoxMenuItem debugging = new JCheckBoxMenuItem("Engine debugging");
00143                 toolMenu.add(debugging);
00144                 debugging.addActionListener(new ActionListener(){
00145                         public void actionPerformed(ActionEvent e){
00146                                 engine.setDebug(debugging.isSelected());
00147                         }
00148                 });
00149 
00150                 addItemToMenu(toolMenu,"See Object Specifications",new ActionListener(){
00151                         public void actionPerformed(ActionEvent e){
00152                                 engine.command("showObjectVariables");
00153                         }
00154                 });
00155                 
00156                                 
00157                 addItemToMenu(toolMenu,"Interrupt XSB",new ActionListener(){
00158                         public void actionPerformed(ActionEvent e){
00159                                 engine.interrupt();
00160                         }
00161                 });
00162                 
00163                 historyMenu = new JMenu("History",true); mb.add(historyMenu); 
00164                 historyMenu.addSeparator(); // to avoid Swing bug handling key events
00165         }
00166         
00167         class HistoryListener implements ActionListener{
00168                 JTextComponent targetText;
00169                 String memory;
00170                 HistoryListener(JTextComponent t,String s){
00171                         targetText=t; memory=s;
00172                 }
00173                 public void actionPerformed(ActionEvent e){
00174                         targetText.replaceSelection(memory);
00175                 }
00176         }
00177         
00178         static void addItemToMenu(JMenu menu,String item,ActionListener handler) {
00179                 JMenuItem menuItem = new JMenuItem(item);
00180                 menu.add(menuItem);
00181                 menuItem.addActionListener(handler);
00182         }
00183         
00184         public abstract void sendToProlog();
00185         
00186         protected void addToHistory(){
00187                 JMenuItem item;
00188                 String goal = prologInput.getText();
00189                 if (goal.equals(";")) return; // not worthy remembering
00190                 if (goal.length()>20) historyMenu.add(item = new JMenuItem(goal.substring(0,19)+"..."));
00191                 else historyMenu.add(item = new JMenuItem(goal.substring(0,goal.length())));
00192                 item.addActionListener(new HistoryListener(prologInput,goal));
00193         }
00194         
00195         static class LoadedFile{
00196                 File file; String method;
00197                 LoadedFile(File file,String method){
00198                         this.file=file; this.method=method;
00199                         if (!(method.equals("reconsult") || method.equals("load_dyn")))
00200                         throw new IPException("bad load method");
00201                 }
00202                 public boolean equals(LoadedFile o){
00203                         return file.equals(o.file) && method.equals(o.method);
00204                 }
00205         }
00206         
00207         void addToReloaders(File file,String method){
00208                 final LoadedFile lf = new LoadedFile(file,method);
00209                 if (!loadedFiles.contains(lf)){
00210                         loadedFiles.addElement(lf);
00211                         addItemToMenu(fileMenu,file.getName(),new ActionListener(){
00212                                 public void actionPerformed(ActionEvent e){
00213                                         engine.command(lf.method+"('"+lf.file.getAbsolutePath()+ "')");
00214                                 }
00215                         });
00216                 }
00217         }
00218         
00219         void reconsultFile(){
00220                 String nome,directorio; File filetoreconsult=null;
00221                 FileDialog d = new FileDialog(this,"Reconsult file...");
00222                 d.show();
00223                 nome = d.getFile(); directorio = d.getDirectory();
00224                 if (nome!=null) {
00225                         filetoreconsult = new File(directorio,nome);
00226                         engine.command("reconsult('"+filetoreconsult.getAbsolutePath()+ "')");
00227                         addToReloaders(filetoreconsult,"reconsult");
00228                 }
00229         }
00230 
00231         void load_dynFile(){
00232                 String nome,directorio; File filetoreconsult=null;
00233                 FileDialog d = new FileDialog(this,"load_dyn file...");
00234                 d.show();
00235                 nome = d.getFile(); directorio = d.getDirectory();
00236                 if (nome!=null) {
00237                         filetoreconsult = new File(directorio,nome);
00238                         engine.command("load_dyn('"+filetoreconsult.getAbsolutePath()+ "')");
00239                         addToReloaders(filetoreconsult,"load_dyn");
00240                 }
00241         }
00242 
00243         public void focusInput(){
00244                 prologInput.selectAll();
00245                 prologInput.requestFocus();
00246         }
00247                 
00248         public void scrollToBottom(){
00249                 if (prologOutput.isShowing()) {
00250                         prologOutput.setCaretPosition(prologOutput.getDocument().getEndPosition().getOffset()-1 /* OBOB hack */);
00251                         try {
00252                                 // If we're in a JScrollPane, force scrolling to bottom and left
00253                                 JScrollBar scrollbarV = ((JScrollPane)((JViewport)(prologOutput.getParent())).getParent()).getVerticalScrollBar();
00254                                 scrollbarV.setValue(scrollbarV.getMaximum());
00255                                 JScrollBar scrollbarH = ((JScrollPane)((JViewport)(prologOutput.getParent())).getParent()).getHorizontalScrollBar();
00256                                 scrollbarH.setValue(scrollbarH.getMinimum());
00257                         } catch (Exception e) {/* We're not in a JScrollPane, forget it! */};
00258                 }
00259         }
00260         
00261         public static boolean debug = false;
00262         public static String prologStartCommand=null;
00263 
00264         public static void commonMain(String args[]) {
00265                 System.out.println("Welcome "+System.getProperty("user.name")+" to InterProlog "+PrologEngine.version+" on Java "+
00266                         System.getProperty("java.version") + " ("+
00267                         System.getProperty("java.vendor") + "), "+ 
00268                         System.getProperty("os.name") + " "+
00269                         System.getProperty("os.version"));
00270                         
00271                 if (args.length>=1){
00272                         int i=0;
00273                         while(true){
00274                                 if (args[i].toLowerCase().startsWith("-d")) {
00275                                         debug=true;
00276                                         i=i+1;
00277                                 } else {
00278                                         prologStartCommand = remainingArgs(args,i);
00279                                         break;
00280                                 }
00281                         }
00282                 } else System.err.println("Usage: ...thisclassname [-debug] PrologExecutablePath OtherPrologArgs");
00283 
00284         }
00285         
00286         public static String commandArgs(String[] args){
00287                 return remainingArgs(args,0);
00288         }
00289         public static String remainingArgs(String[] args,int first){
00290                 if (args.length==0) throw new IPException("Missing arguments in command line");
00291                 StringBuffer temp = new StringBuffer();
00292                 for (int i=first;i<args.length;i++){
00293                         if (i>first) temp.append(" ");
00294                         temp.append(args[i]);
00295                 }
00296                 return temp.toString();
00297         }
00298         
00299         public static void beep(){
00300                 Toolkit.getDefaultToolkit().beep();
00301         }
00302 }

Generated on Wed Jul 26 13:30:44 2006 for XSB by  doxygen 1.4.5