home *** CD-ROM | disk | FTP | other *** search
Java Source | 1996-08-14 | 13.5 KB | 557 lines |
- // FileReq.java
- // A file requestor for loading/saving a file from the JFS.
- // When a file is chosen, sends an action event to it's parent with the
- // event argument set to "Load" or whatever. If cancel is clicked or the
- // window closed, then an event is sent with the arg set to "Cancel".
- import java.awt.*;
- import java.util.Vector;
- import java.util.StringTokenizer;
- import JFSclient;
- import JFSdirectory;
- import BorderPanel;
- import SpacedPanel;
-
- public class FileReq extends FixedFrame
- {
- JFSclient client; // connection to server
- Component parent; // where to send Events
- String act; // "Load" or "Save"
- boolean savestyle; // is this a save type of requestor?
- String mmaj, mmin; // major and minor parts of mime types to allow
- Button loadsave, can, par;
- TextField dir, file;
- DoubleListPanel filelist, version;
- Checkbox single, multi;
- Choice mtype; // mime type to save as
- JFSdirectory current; // files in the current directory
- Vector currentinfo = new Vector();
- Vector versionnum = new Vector();
-
- // Create new File Requestor
- // cl - connection to JFS server
- // pa - parent component, to send messages to
- // ac - what to put on the open button (ie. "Load" or "Save")
- // ty - mime type pattern to match
- // ss - Is this a style requestor, which gives the user a choice of
- // whether a new file is single/multiversion, and allows a choice
- // of what mime type to save as?
- // mt - Array of supported mime types
- FileReq(JFSclient cl, Component pa, String ac, String ty,
- boolean ss, String mt[])
- {
- super(new Dimension(400, 300));
- client = cl;
- parent = pa;
- act = ac;
- savestyle = ss;
- int slash = ty.indexOf('/');
- mmaj = ty.substring(0,slash);
- mmin = ty.substring(slash+1);
- setLayout(new BorderLayout());
-
- // Top panel
- Panel top = new SpacedPanel();
- top.setLayout(new BorderLayout());
- top.add("West",new Label("Directory :"));
- top.add("Center",dir = new TextField(simplify(client.currentdir)));
- top.add("East",par = new Button("Parent"));
- add("North",top);
-
- // Bottom panel
- Panel bot = new SpacedPanel();
- bot.setLayout(new BorderLayout());
- bot.add("West",new Label("File :"));
- bot.add("Center",file = new TextField(client.currentfile));
- Panel okcan = new Panel();
- okcan.setLayout(new GridLayout(1,2));
- okcan.add(loadsave = new Button(ac));
- okcan.add(can = new Button("Cancel"));
- bot.add("East",okcan);
- if (savestyle) {
- Panel verpanel = new Panel();
- verpanel.setLayout(new FlowLayout(FlowLayout.LEFT));
- CheckboxGroup gr = new CheckboxGroup();
- verpanel.add(single = new Checkbox("Single version", gr, true));
- verpanel.add(multi = new Checkbox("Multi-version", gr, false));
- verpanel.add(mtype = new Choice());
- if (client.currenttype != null)
- mtype.addItem(client.currenttype);
- for(int i=0; i<mt.length; i++)
- if (client.currenttype == null ||
- !mt[i].equals(client.currenttype))
- mtype.addItem(mt[i]);
- if (mtype.countItems() == 0) {
- // No mime types to use??
- mtype.addItem("application/octec-stream");
- }
- bot.add("South",verpanel);
- }
- add("South",bot);
-
- // File list
- Panel mid = new SpacedPanel();
- GridBagLayout gbl = new GridBagLayout();
- mid.setLayout(gbl);
- GridBagConstraints gbc = new GridBagConstraints();
- gbc.fill = GridBagConstraints.BOTH;
- gbc.weightx = .6;
- gbc.weighty = 1;
- filelist = new DoubleListPanel("Name","Type");
- gbl.setConstraints(filelist, gbc);
- mid.add(filelist);
- gbc.weightx = .4;
- version = new DoubleListPanel("Version","Size");
- gbl.setConstraints(version, gbc);
- mid.add(version);
- add("Center",mid);
-
- setTitle("Choose file to "+act);
- pack();
- show();
- filldir();
- }
-
- // getfile
- // Get the full path of the chosen file
- String getfile()
- {
- return simplify(dir.getText() + "/" + file.getText());
- }
-
- // getdir
- // Get only the directory part of the chosen file
- String getdir()
- {
- return simplify(dir.getText());
- }
-
- // getname
- // Get only the name part of the chosen file
- String getname()
- {
- return file.getText();
- }
-
- // getversion
- // Get the number of the chosen version, or 0 if the user doesn't care
- int getversion()
- {
- if (versionnum.size() == 0)
- return 0; // current file was something entered by user
- return ((Integer)versionnum.elementAt(version.selected())).intValue();
- }
-
- // multiversion
- // The position of the single/multi version checkboxes. Only matters
- // if the file doesn't exist.
- boolean multiversion()
- {
- return multi.getState();
- }
-
- // gettype
- // For save-style file requestors, returns the mime type chosen
- String gettype()
- {
- return mtype.getSelectedItem();
- }
-
- // filldir
- // Get the JFSdirectory structure for the current directory, and
- // fill in the file list.
- void filldir()
- {
- try current = client.getdir(dir.getText());
- catch(RequestException e) {
- new ErrorWindow("Couldn't access "+dir.getText()+" : "+
- e.getMessage());
- return;
- }
- filelist.clear();
- currentinfo.removeAllElements();
- version.clear();
- versionnum.removeAllElements();
- for(int i=0; i<current.size(); i++) {
- JFSfile f = (JFSfile)current.files.elementAt(i);
- int slash = f.type.indexOf('/');
- String ma = f.type.substring(0,slash);
- String mi = f.type.substring(slash+1);
- if ((mmaj.equals("*") || mmaj.equals(ma)) &&
- (mmin.equals("*") || mmin.equals(mi)) ||
- (ma.equals("jfs") && mi.equals("directory"))) {
- currentinfo.addElement(f);
- filelist.addItem(f.name, f.type);
- }
- }
- }
-
-
- // handleEvent
- // Process an event from the user
- public boolean handleEvent(Event evt)
- {
- if (evt.target == can || evt.id == Event.WINDOW_DESTROY) {
- parent.postEvent(new Event(this, Event.ACTION_EVENT, "Cancel"));
- dispose();
- }
- return super.handleEvent(evt);
- }
-
- // action
- // Handle some action from the user interface
- public boolean action(Event evt, Object obj)
- {
- if (evt.target == filelist && ((String)evt.arg).equals("Single")) {
- // single click on filename
- int sel = filelist.selected();
- JFSfile selfl = (JFSfile)currentinfo.elementAt(sel);
- file.setText(selfl.name);
- version.clear();
- versionnum.removeAllElements();
- if (selfl.multiversion) {
- JFSversion mx = null;
- for(int i=0; i<selfl.versions.size(); i++) {
- JFSversion vr = (JFSversion)selfl.versions.
- elementAt(i);
- version.addItem(String.valueOf(vr.number),
- String.valueOf(vr.size));
- versionnum.addElement(new Integer(vr.number));
- if (mx == null || vr.number > mx.number)
- mx = vr;
- }
- versionnum.addElement(new Integer(0));
- if (savestyle)
- version.addItem("New","");
- else
- version.addItem("Latest",
- String.valueOf(mx.size));
- version.select(selfl.versions.size());
- }
- else {
- JFSversion vr = (JFSversion)selfl.versions.elementAt(0);
- versionnum.addElement(new Integer(0));
- version.addItem("Single",String.valueOf(vr.size));
- version.select(0);
- }
- }
- else if (evt.target == loadsave ||
- evt.target == filelist && ((String)evt.arg).equals("Double") ||
- evt.target == version && ((String)evt.arg).equals("Double")) {
- // File chosen by double-click or load/save
- if (file.getText().length() == 0)
- return false; // no filename??
- JFSfile selfl = null;
- for(int i=0; i<currentinfo.size(); i++) {
- JFSfile fl = (JFSfile)currentinfo.elementAt(i);
- if (fl.name.equals(file.getText()))
- selfl = fl;
- }
- if (selfl != null && selfl.type.equals("jfs/directory")) {
- // enter a new dir
- dir.setText(simplify(dir.getText()+"/"+selfl.name));
- filldir();
- file.setText("");
- }
- else {
- parent.postEvent(
- new Event(this, Event.ACTION_EVENT, act));
- dispose();
- }
- }
- else if (evt.target == file) {
- // Return hit in file text box (to load/save the named file)
- version.clear();
- versionnum.removeAllElements();
- postEvent(new Event(loadsave, Event.ACTION_EVENT, null));
- }
- else if (evt.target == dir) {
- // Return hit in directory text box
- dir.setText(simplify(dir.getText()));
- filldir();
- }
- else if (evt.target == par) {
- // Parent button clicked
- String d = dir.getText();
- if (!d.equals("/")) {
- d = d.substring(0, d.lastIndexOf('/'));
- dir.setText(d.length() == 0 ? "/" : d);
- filldir();
- }
- }
- return true;
- }
-
- // simplify
- // Convert a path into it's simplest form.
- String simplify(String s)
- {
- if (s.charAt(0) != '/')
- return s; // huh?
- StringTokenizer tok = new StringTokenizer(s,"/");
- if (tok.countTokens() == 0)
- return "/"; // string only contains /'s
- String sim = "";
- while(tok.hasMoreTokens())
- sim += "/"+tok.nextToken();
- return sim;
- }
- }
-
-
- // DoubleListPanel
- // A two column list (for example, names and type or versions and sizes)
- class DoubleListPanel extends BorderPanel
- {
- String title1, title2;
- DoubleList list; // where the items are drawn
- Scrollbar scroll; // right side scrollbar
- // The behaviour of MS-windows and Motif scrollbars is slightly
- // different.. deal with it.
- static boolean broken_awt = System.getProperty("os.name").
- startsWith("Windows");
-
- DoubleListPanel(String title1, String title2)
- {
- super(2, Color.black, Color.white);
- setLayout(new BorderLayout());
- add("Center",list = new DoubleList(title1, title2));
- add("East",scroll = new Scrollbar(Scrollbar.VERTICAL, 0, 1, 0, 0));
- }
-
- // addIem
- // Add an item to the list
- void addItem(String n, String t)
- {
- list.addItem(n,t);
- compscroll();
- }
-
- // clear
- // Remove everything from the list
- void clear()
- {
- scroll.setValues(0, 1, 0, 0);
- list.clear();
- }
-
- // selected
- // Returns the number of the selected entry
- int selected()
- {
- return list.selected();
- }
-
- // select
- // Choose which entry is currently selected
- void select(int n)
- {
- list.select(n);
- }
-
- // compscroll
- // Re-size the scollbars
- void compscroll()
- {
- int r = list.rows();
- if (list.rows() != -1) {
- int c = list.count() - (broken_awt ? 0 : r);
- scroll.setValues(0, r==0?1:r , 0, c<0?0:c);
- }
- }
-
- // handleEvent
- // Handle a user action
- public boolean handleEvent(Event evt)
- {
- if (evt.target == scroll) {
- // scrollbar moved
- list.settop(scroll.getValue());
- }
- else if (evt.target == list && evt.id == Event.ACTION_EVENT) {
- // entry chosen
- getParent().postEvent(new Event(this, evt.id, evt.arg));
- }
- return super.handleEvent(evt);
- }
-
- // paint
- // Since this gets called upon resize, use it to recompute the
- // scrollbars.
- public void paint(Graphics g)
- {
- super.paint(g);
- compscroll();
- }
- }
-
-
- // DoubleList
- // The component actually used to display a double list
- class DoubleList extends Canvas
- {
- Vector names = new Vector();
- Vector types = new Vector();
- String title1, title2;
- int w,h; // size of this list
- FontMetrics fnm; // info about font
- Graphics gr; // where to draw
- Image back; // double buffer
- int top = 0; // first file to display
- int sel = -1; // currently selected file
- int oldsel = -1;
- long lastclick; // time of last click on file
- Font fn;
-
- DoubleList(String t1, String t2)
- {
- title1 = t1;
- title2 = t2;
- fn = new Font("courier", Font.PLAIN, 10);
- }
-
- // addItem
- // Add one entry to the list
- void addItem(String n, String t)
- {
- names.addElement(n);
- types.addElement(t);
- if (sel < 0 && oldsel == names.size()-1) {
- // Some item on the list was chosen before it was cleared,
- // and now that index exists again. Re-select it
- click(oldsel);
- }
- drawlist();
- }
-
- // clear
- // Remove all entries from the list
- void clear()
- {
- names.removeAllElements();
- types.removeAllElements();
- top = 0;
- sel = -1;
- drawlist();
- }
-
- // settop
- // Set the first row to be displayed.
- void settop(int t)
- {
- top = t;
- drawlist();
- }
-
- // select
- // Select an entry
- void select(int n)
- {
- if (n >= 0 && n < count()) {
- oldsel = sel = n;
- drawlist();
- }
- }
-
- // rows
- // Returns the number of rows displayable
- int rows()
- {
- if (fnm == null) return -1;
- else {
- int r = h / fnm.getHeight() - 1;
- return r > count() ? count() : r;
- }
- }
-
- // count
- // Returns the number of rows in the list
- int count()
- {
- return names.size();
- }
-
- // selected
- // Returns the number of the currently selected row
- int selected()
- {
- return sel;
- }
-
- // reshape
- // Change the size of this component.
- public void reshape(int nx, int ny, int nw, int nh)
- {
- w = nw; h = nh;
- gr = getGraphics();
- gr.setFont(fn);
- fnm = gr.getFontMetrics();
- super.reshape(nx,ny,nw,nh);
- }
-
- public void paint(Graphics g)
- {
- drawlist();
- }
-
- // mouseDown
- // Called when the user clicks on a row in the list
- public boolean mouseDown(Event evt, int x, int y)
- {
- int fl = y / fnm.getHeight() + top - 1;
- if (fl >= 0 && fl < count()) {
- click(fl);
- drawlist();
- }
- return true;
- }
-
- // click
- // Called when a list entry is clicked on, or we want to simulate
- // the clicking-on of a list entry
- void click(int fl)
- {
- long now = System.currentTimeMillis();
- String arg;
- if (now - lastclick < 1000 && sel == fl) arg = "Double";
- else arg = "Single";
- lastclick = now;
- oldsel = sel = fl;
- getParent().postEvent(new Event(this, Event.ACTION_EVENT, arg));
- }
-
- // drawlist
- // Render
- void drawlist()
- {
- if (gr == null) return; // we aren't around yet
-
- // clear background and draw titles
- gr.setColor(Color.white);
- gr.fillRect(0, 0, w, h);
- gr.setColor(Color.red);
- gr.setFont(fn);
- gr.drawString(title1, 0, fnm.getHeight() - fnm.getDescent());
- gr.drawString(title2, w/2, fnm.getHeight() - fnm.getDescent());
-
- // put blue box behind selected file
- if (sel >= top) {
- gr.setColor(Color.black);
- gr.fillRect(0, (sel-top+1)*fnm.getHeight(), w, fnm.getHeight());
- }
-
- // Draw file names
- for(int i=top; i<names.size(); i++) {
- if (i == sel) gr.setColor(Color.white);
- else gr.setColor(Color.black);
- int y = (i-top+2)*fnm.getHeight() - fnm.getDescent();
- String nm = (String)names.elementAt(i);
- String ty = (String)types.elementAt(i);
- while(fnm.stringWidth(nm) > (w/2)-10 && nm.length() > 0)
- nm = nm.substring(0, nm.length()-1);
- gr.drawString(nm, 1, y);
- gr.drawString(ty, w/2, y);
- }
- }
- }
-
-