home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / pr8adpl7 / filereq.java < prev    next >
Encoding:
Java Source  |  1996-08-14  |  13.5 KB  |  557 lines

  1. // FileReq.java
  2. // A file requestor for loading/saving a file from the JFS.
  3. // When a file is chosen, sends an action event to it's parent with the
  4. // event argument set to "Load" or whatever. If cancel is clicked or the
  5. // window closed, then an event is sent with the arg set to "Cancel".
  6. import java.awt.*;
  7. import java.util.Vector;
  8. import java.util.StringTokenizer;
  9. import JFSclient;
  10. import JFSdirectory;
  11. import BorderPanel;
  12. import SpacedPanel;
  13.  
  14. public class FileReq extends FixedFrame
  15. {
  16.     JFSclient client;    // connection to server
  17.     Component parent;    // where to send Events
  18.     String act;        // "Load" or "Save"
  19.     boolean savestyle;    // is this a save type of requestor?
  20.     String mmaj, mmin;    // major and minor parts of mime types to allow
  21.     Button loadsave, can, par;
  22.     TextField dir, file;
  23.     DoubleListPanel filelist, version;
  24.     Checkbox single, multi;
  25.     Choice mtype;        // mime type to save as
  26.     JFSdirectory current;    // files in the current directory
  27.     Vector currentinfo = new Vector();
  28.     Vector versionnum = new Vector();
  29.  
  30.     // Create new File Requestor
  31.     // cl - connection to JFS server
  32.     // pa - parent component, to send messages to
  33.     // ac - what to put on the open button (ie. "Load" or "Save")
  34.     // ty - mime type pattern to match
  35.     // ss - Is this a style requestor, which gives the user a choice of
  36.     //      whether a new file is single/multiversion, and allows a choice
  37.     //      of what mime type to save as?
  38.     // mt - Array of supported mime types
  39.     FileReq(JFSclient cl, Component pa, String ac, String ty,
  40.         boolean ss, String mt[])
  41.     {
  42.     super(new Dimension(400, 300));
  43.     client = cl;
  44.     parent = pa;
  45.     act = ac;
  46.     savestyle = ss;
  47.     int slash = ty.indexOf('/');
  48.     mmaj = ty.substring(0,slash);
  49.     mmin = ty.substring(slash+1);
  50.     setLayout(new BorderLayout());
  51.  
  52.     // Top panel
  53.     Panel top = new SpacedPanel();
  54.     top.setLayout(new BorderLayout());
  55.     top.add("West",new Label("Directory :"));
  56.     top.add("Center",dir = new TextField(simplify(client.currentdir)));
  57.     top.add("East",par = new Button("Parent"));
  58.     add("North",top);
  59.  
  60.     // Bottom panel
  61.     Panel bot = new SpacedPanel();
  62.     bot.setLayout(new BorderLayout());
  63.     bot.add("West",new Label("File :"));
  64.     bot.add("Center",file = new TextField(client.currentfile));
  65.     Panel okcan = new Panel();
  66.     okcan.setLayout(new GridLayout(1,2));
  67.     okcan.add(loadsave = new Button(ac));
  68.     okcan.add(can = new Button("Cancel"));
  69.     bot.add("East",okcan);
  70.     if (savestyle) {
  71.         Panel verpanel = new Panel();
  72.         verpanel.setLayout(new FlowLayout(FlowLayout.LEFT));
  73.         CheckboxGroup gr = new CheckboxGroup();
  74.         verpanel.add(single = new Checkbox("Single version", gr, true));
  75.         verpanel.add(multi = new Checkbox("Multi-version", gr, false));
  76.         verpanel.add(mtype = new Choice());
  77.         if (client.currenttype != null)
  78.             mtype.addItem(client.currenttype);
  79.         for(int i=0; i<mt.length; i++)
  80.             if (client.currenttype == null ||
  81.                 !mt[i].equals(client.currenttype))
  82.                 mtype.addItem(mt[i]);
  83.         if (mtype.countItems() == 0) {
  84.             // No mime types to use??
  85.             mtype.addItem("application/octec-stream");
  86.             }
  87.         bot.add("South",verpanel);
  88.         }
  89.     add("South",bot);
  90.  
  91.     // File list
  92.     Panel mid = new SpacedPanel();
  93.     GridBagLayout gbl = new GridBagLayout();
  94.     mid.setLayout(gbl);
  95.     GridBagConstraints gbc = new GridBagConstraints();
  96.     gbc.fill = GridBagConstraints.BOTH;
  97.     gbc.weightx = .6;
  98.     gbc.weighty = 1;
  99.     filelist = new DoubleListPanel("Name","Type");
  100.     gbl.setConstraints(filelist, gbc);
  101.     mid.add(filelist);
  102.     gbc.weightx = .4;
  103.     version = new DoubleListPanel("Version","Size");
  104.     gbl.setConstraints(version, gbc);
  105.     mid.add(version);
  106.     add("Center",mid);
  107.  
  108.     setTitle("Choose file to "+act);
  109.     pack();
  110.     show();
  111.     filldir();
  112.     }
  113.  
  114.     // getfile
  115.     // Get the full path of the chosen file
  116.     String getfile()
  117.     {
  118.     return simplify(dir.getText() + "/" + file.getText());
  119.     }
  120.  
  121.     // getdir
  122.     // Get only the directory part of the chosen file
  123.     String getdir()
  124.     {
  125.     return simplify(dir.getText());
  126.     }
  127.  
  128.     // getname
  129.     // Get only the name part of the chosen file
  130.     String getname()
  131.     {
  132.     return file.getText();
  133.     }
  134.  
  135.     // getversion
  136.     // Get the number of the chosen version, or 0 if the user doesn't care
  137.     int getversion()
  138.     {
  139.     if (versionnum.size() == 0)
  140.         return 0;    // current file was something entered by user
  141.     return ((Integer)versionnum.elementAt(version.selected())).intValue();
  142.     }
  143.  
  144.     // multiversion
  145.     // The position of the single/multi version checkboxes. Only matters
  146.     // if the file doesn't exist.
  147.     boolean multiversion()
  148.     {
  149.     return multi.getState();
  150.     }
  151.  
  152.     // gettype
  153.     // For save-style file requestors, returns the mime type chosen
  154.     String gettype()
  155.     {
  156.     return mtype.getSelectedItem();
  157.     }
  158.  
  159.     // filldir
  160.     // Get the JFSdirectory structure for the current directory, and
  161.     // fill in the file list.
  162.     void filldir()
  163.     {
  164.     try current = client.getdir(dir.getText());
  165.     catch(RequestException e) {
  166.         new ErrorWindow("Couldn't access "+dir.getText()+" : "+
  167.                 e.getMessage());
  168.         return;
  169.         }
  170.     filelist.clear();
  171.     currentinfo.removeAllElements();
  172.     version.clear();
  173.     versionnum.removeAllElements();
  174.     for(int i=0; i<current.size(); i++) {
  175.         JFSfile f = (JFSfile)current.files.elementAt(i);
  176.         int slash = f.type.indexOf('/');
  177.         String ma = f.type.substring(0,slash);
  178.         String mi = f.type.substring(slash+1);
  179.         if ((mmaj.equals("*") || mmaj.equals(ma)) &&
  180.             (mmin.equals("*") || mmin.equals(mi)) ||
  181.             (ma.equals("jfs") && mi.equals("directory"))) {
  182.             currentinfo.addElement(f);
  183.             filelist.addItem(f.name, f.type);
  184.             }
  185.         }
  186.     }
  187.  
  188.  
  189.     // handleEvent
  190.     // Process an event from the user
  191.     public boolean handleEvent(Event evt)
  192.     {
  193.     if (evt.target == can || evt.id == Event.WINDOW_DESTROY) {
  194.         parent.postEvent(new Event(this, Event.ACTION_EVENT, "Cancel"));
  195.         dispose();
  196.         }
  197.     return super.handleEvent(evt);
  198.     }
  199.  
  200.     // action
  201.     // Handle some action from the user interface
  202.     public boolean action(Event evt, Object obj)
  203.     {
  204.     if (evt.target == filelist && ((String)evt.arg).equals("Single")) {
  205.         // single click on filename
  206.         int sel = filelist.selected();
  207.         JFSfile selfl = (JFSfile)currentinfo.elementAt(sel);
  208.         file.setText(selfl.name);
  209.         version.clear();
  210.         versionnum.removeAllElements();
  211.         if (selfl.multiversion) {
  212.             JFSversion mx = null;
  213.             for(int i=0; i<selfl.versions.size(); i++) {
  214.                 JFSversion vr = (JFSversion)selfl.versions.
  215.                            elementAt(i);
  216.                 version.addItem(String.valueOf(vr.number),
  217.                         String.valueOf(vr.size));
  218.                 versionnum.addElement(new Integer(vr.number));
  219.                 if (mx == null || vr.number > mx.number)
  220.                     mx = vr;
  221.                 }
  222.             versionnum.addElement(new Integer(0));
  223.             if (savestyle)
  224.                 version.addItem("New","");
  225.             else
  226.                 version.addItem("Latest",
  227.                         String.valueOf(mx.size));
  228.             version.select(selfl.versions.size());
  229.             }
  230.         else {
  231.             JFSversion vr = (JFSversion)selfl.versions.elementAt(0);
  232.             versionnum.addElement(new Integer(0));
  233.             version.addItem("Single",String.valueOf(vr.size));
  234.             version.select(0);
  235.             }
  236.         }
  237.     else if (evt.target == loadsave ||
  238.          evt.target == filelist && ((String)evt.arg).equals("Double") ||
  239.          evt.target == version && ((String)evt.arg).equals("Double")) {
  240.         // File chosen by double-click or load/save
  241.         if (file.getText().length() == 0)
  242.             return false;    // no filename??
  243.         JFSfile selfl = null;
  244.         for(int i=0; i<currentinfo.size(); i++) {
  245.             JFSfile fl = (JFSfile)currentinfo.elementAt(i);
  246.             if (fl.name.equals(file.getText()))
  247.                 selfl = fl;
  248.             }
  249.         if (selfl != null && selfl.type.equals("jfs/directory")) {
  250.             // enter a new dir
  251.             dir.setText(simplify(dir.getText()+"/"+selfl.name));
  252.             filldir();
  253.             file.setText("");
  254.             }
  255.         else {
  256.             parent.postEvent(
  257.                 new Event(this, Event.ACTION_EVENT, act));
  258.             dispose();
  259.             }
  260.         }
  261.     else if (evt.target == file) {
  262.         // Return hit in file text box (to load/save the named file)
  263.         version.clear();
  264.         versionnum.removeAllElements();
  265.         postEvent(new Event(loadsave, Event.ACTION_EVENT, null));
  266.         }
  267.     else if (evt.target == dir) {
  268.         // Return hit in directory text box
  269.         dir.setText(simplify(dir.getText()));
  270.         filldir();
  271.         }
  272.     else if (evt.target == par) {
  273.         // Parent button clicked
  274.         String d = dir.getText();
  275.         if (!d.equals("/")) {
  276.             d = d.substring(0, d.lastIndexOf('/'));
  277.             dir.setText(d.length() == 0 ? "/" : d);
  278.             filldir();
  279.             }
  280.         }
  281.     return true;
  282.     }
  283.  
  284.     // simplify
  285.     // Convert a path into it's simplest form.
  286.     String simplify(String s)
  287.     {
  288.     if (s.charAt(0) != '/')
  289.         return s;    // huh?
  290.     StringTokenizer tok = new StringTokenizer(s,"/");
  291.     if (tok.countTokens() == 0)
  292.         return "/";    // string only contains /'s
  293.     String sim = "";
  294.     while(tok.hasMoreTokens())
  295.         sim += "/"+tok.nextToken();
  296.     return sim;
  297.     }
  298. }
  299.  
  300.  
  301. // DoubleListPanel
  302. // A two column list (for example, names and type or versions and sizes)
  303. class DoubleListPanel extends BorderPanel
  304. {
  305.     String title1, title2;
  306.     DoubleList list;        // where the items are drawn
  307.     Scrollbar scroll;        // right side scrollbar
  308.     // The behaviour of MS-windows and Motif scrollbars is slightly
  309.     // different.. deal with it.
  310.     static boolean broken_awt = System.getProperty("os.name").
  311.                     startsWith("Windows");
  312.  
  313.     DoubleListPanel(String title1, String title2)
  314.     {
  315.     super(2, Color.black, Color.white);
  316.     setLayout(new BorderLayout());
  317.     add("Center",list = new DoubleList(title1, title2));
  318.     add("East",scroll = new Scrollbar(Scrollbar.VERTICAL, 0, 1, 0, 0));
  319.     }
  320.  
  321.     // addIem
  322.     // Add an item to the list
  323.     void addItem(String n, String t)
  324.     {
  325.     list.addItem(n,t);
  326.     compscroll();
  327.     }
  328.  
  329.     // clear
  330.     // Remove everything from the list
  331.     void clear()
  332.     {
  333.     scroll.setValues(0, 1, 0, 0);
  334.     list.clear();
  335.     }
  336.  
  337.     // selected
  338.     // Returns the number of the selected entry
  339.     int selected()
  340.     {
  341.     return list.selected();
  342.     }
  343.  
  344.     // select
  345.     // Choose which entry is currently selected
  346.     void select(int n)
  347.     {
  348.     list.select(n);
  349.     }
  350.  
  351.     // compscroll
  352.     // Re-size the scollbars
  353.     void compscroll()
  354.     {
  355.     int r = list.rows();
  356.     if (list.rows() != -1) {
  357.         int c = list.count() - (broken_awt ? 0 : r);
  358.         scroll.setValues(0, r==0?1:r , 0, c<0?0:c);
  359.         }
  360.     }
  361.  
  362.     // handleEvent
  363.     // Handle a user action
  364.     public boolean handleEvent(Event evt)
  365.     {
  366.     if (evt.target == scroll) {
  367.         // scrollbar moved
  368.         list.settop(scroll.getValue());
  369.         }
  370.     else if (evt.target == list && evt.id == Event.ACTION_EVENT) {
  371.         // entry chosen
  372.         getParent().postEvent(new Event(this, evt.id, evt.arg));
  373.         }
  374.     return super.handleEvent(evt);
  375.     }
  376.  
  377.     // paint
  378.     // Since this gets called upon resize, use it to recompute the
  379.     // scrollbars.
  380.     public void paint(Graphics g)
  381.     {
  382.     super.paint(g);
  383.     compscroll();
  384.     }
  385. }
  386.  
  387.  
  388. // DoubleList
  389. // The component actually used to display a double list
  390. class DoubleList extends Canvas
  391. {
  392.     Vector names = new Vector();
  393.     Vector types = new Vector();
  394.     String title1, title2;
  395.     int w,h;            // size of this list
  396.     FontMetrics fnm;        // info about font
  397.     Graphics gr;            // where to draw
  398.     Image back;            // double buffer
  399.     int top = 0;            // first file to display
  400.     int sel = -1;            // currently selected file
  401.     int oldsel = -1;
  402.     long lastclick;            // time of last click on file
  403.     Font fn;
  404.  
  405.     DoubleList(String t1, String t2)
  406.     {
  407.     title1 = t1;
  408.     title2 = t2;
  409.     fn = new Font("courier", Font.PLAIN, 10);
  410.     }
  411.  
  412.     // addItem
  413.     // Add one entry to the list
  414.     void addItem(String n, String t)
  415.     {
  416.     names.addElement(n);
  417.     types.addElement(t);
  418.     if (sel < 0 && oldsel == names.size()-1) {
  419.         // Some item on the list was chosen before it was cleared,
  420.         // and now that index exists again. Re-select it
  421.         click(oldsel);
  422.         }
  423.     drawlist();
  424.     }
  425.  
  426.     // clear
  427.     // Remove all entries from the list
  428.     void clear()
  429.     {
  430.     names.removeAllElements();
  431.     types.removeAllElements();
  432.     top = 0;
  433.     sel = -1;
  434.     drawlist();
  435.     }
  436.  
  437.     // settop
  438.     // Set the first row to be displayed.
  439.     void settop(int t)
  440.     {
  441.     top = t;
  442.     drawlist();
  443.     }
  444.  
  445.     // select
  446.     // Select an entry
  447.     void select(int n)
  448.     {
  449.     if (n >= 0 && n < count()) {
  450.         oldsel = sel = n;
  451.         drawlist();
  452.         }
  453.     }
  454.  
  455.     // rows
  456.     // Returns the number of rows displayable
  457.     int rows()
  458.     {
  459.     if (fnm == null) return -1;
  460.     else {
  461.         int r = h / fnm.getHeight() - 1;
  462.         return r > count() ? count() : r;
  463.         }
  464.     }
  465.  
  466.     // count
  467.     // Returns the number of rows in the list
  468.     int count()
  469.     {
  470.     return names.size();
  471.     }
  472.  
  473.     // selected
  474.     // Returns the number of the currently selected row
  475.     int selected()
  476.     {
  477.     return sel;
  478.     }
  479.  
  480.     // reshape
  481.     // Change the size of this component.
  482.     public void reshape(int nx, int ny, int nw, int nh)
  483.     {
  484.     w = nw; h = nh;
  485.     gr = getGraphics();
  486.     gr.setFont(fn);
  487.     fnm = gr.getFontMetrics();
  488.     super.reshape(nx,ny,nw,nh);
  489.     }
  490.  
  491.     public void paint(Graphics g)
  492.     {
  493.     drawlist();
  494.     }
  495.  
  496.     // mouseDown
  497.     // Called when the user clicks on a row in the list
  498.     public boolean mouseDown(Event evt, int x, int y)
  499.     {
  500.     int fl = y / fnm.getHeight() + top - 1;
  501.     if (fl >= 0 && fl < count()) {
  502.         click(fl);
  503.         drawlist();
  504.         }
  505.     return true;
  506.     }
  507.  
  508.     // click
  509.     // Called when a list entry is clicked on, or we want to simulate
  510.     // the clicking-on of a list entry
  511.     void click(int fl)
  512.     {
  513.     long now = System.currentTimeMillis();
  514.     String arg;
  515.     if (now - lastclick < 1000 && sel == fl) arg = "Double";
  516.     else arg = "Single";
  517.     lastclick = now;
  518.     oldsel = sel = fl;
  519.     getParent().postEvent(new Event(this, Event.ACTION_EVENT, arg));
  520.     }
  521.  
  522.     // drawlist
  523.     // Render 
  524.     void drawlist()
  525.     {
  526.     if (gr == null) return;    // we aren't around yet
  527.  
  528.     // clear background and draw titles
  529.     gr.setColor(Color.white);
  530.     gr.fillRect(0, 0, w, h);
  531.     gr.setColor(Color.red);
  532.     gr.setFont(fn);
  533.     gr.drawString(title1, 0, fnm.getHeight() - fnm.getDescent());
  534.     gr.drawString(title2, w/2, fnm.getHeight() - fnm.getDescent());
  535.  
  536.     // put blue box behind selected file
  537.     if (sel >= top) {
  538.         gr.setColor(Color.black);
  539.         gr.fillRect(0, (sel-top+1)*fnm.getHeight(), w, fnm.getHeight());
  540.         }
  541.  
  542.     // Draw file names
  543.     for(int i=top; i<names.size(); i++) {
  544.         if (i == sel) gr.setColor(Color.white);
  545.         else gr.setColor(Color.black);
  546.         int y = (i-top+2)*fnm.getHeight() - fnm.getDescent();
  547.         String nm = (String)names.elementAt(i);
  548.         String ty = (String)types.elementAt(i);
  549.         while(fnm.stringWidth(nm) > (w/2)-10 && nm.length() > 0)
  550.             nm = nm.substring(0, nm.length()-1);
  551.         gr.drawString(nm, 1, y);
  552.         gr.drawString(ty, w/2, y);
  553.         }
  554.     }
  555. }
  556.  
  557.