ExplorerView.java :  » Net » SkunkDAV » org » skunk » dav » client » gui » Java Open Source

Java Open Source » Net » SkunkDAV 
SkunkDAV » org » skunk » dav » client » gui » ExplorerView.java
/*
 *  Copyright (c) 2000, Jacob Smullyan.
 *
 *  This is part of SkunkDAV, a WebDAV client.  See http://skunkdav.sourceforge.net/ 
 *  for the latest version.
 * 
 *  SkunkDAV 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 2, or (at your option)
 *  any later version.
 * 
 *  SkunkDAV  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 SkunkDAV; see the file COPYING.  If not, write to the Free
 *  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 *  02111-1307, USA.
*/

package org.skunk.dav.client.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.skunk.dav.client.gui.editor.DAVEditor;
import org.skunk.trace.Debug;

public class ExplorerView implements View
{
    private JFrame appFrame;
    private JTabbedPane tabPane=null;
    private ArrayList dockedBuffers=new ArrayList();
    private ArrayList dockedStatusComponents=new ArrayList();
    private AppContext appContext;
    private Buffer focussedBuffer=null;
    private JTextField statusField;
    private JLabel locationField;
    private Box statusBar;

    public ExplorerView(AppContext appContext)
    {
  this.appContext=appContext;
  initComponents();
    }

    public final AppContext getAppContext()
    {
  return this.appContext;
    }

    public Component getComponent()
    {
  return appFrame;
    }

    private void initComponents()
    {
  Explorer ex=new Explorer();
  getAppContext().getConfigurator().configure(ex);
  ExplorerMenuBar menubar=ExplorerMenuBar.getMenuBar(ex);
  initStatusBar();            
  appFrame=new JFrame("SkunkDAV " + ResourceManager.getMessage(ResourceManager.RELEASE_VERSION));
  appFrame.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent woo)
    {
        System.exit(0);
    }
      });
  appFrame.setJMenuBar(menubar);
  dock(ex);
  appFrame.pack();
  appFrame.setVisible(true);
    }

    private void initStatusBar()
    {  
  statusField=new JTextField();
  statusField.setEnabled(false);
  Font defaultFont=new Font("Serif", Font.PLAIN, 10);
  statusField.setFont(defaultFont);
  statusField.setBackground(UIManager.getColor("Label.background"));
  statusField.setForeground(Color.black);
  dockedStatusComponents.add(statusField);

  locationField=new JLabel();
  locationField.setFont(new Font("SansSerif", Font.PLAIN, 12));
  locationField.setForeground(Color.black);
  dockedStatusComponents.add(locationField);

  statusBar=Box.createHorizontalBox();
  StateMonitor.registerProperty(locationField, 
              "text",
              StateProperties.CARET_POSITION,
              new StateMonitor.Mapper() 
            {
                public Object getTargetValue(Object applicationValue)
                {
              if (applicationValue instanceof TextPoint)
              {
                  TextPoint p=(TextPoint) applicationValue;
                  return ResourceManager.getMessage(ResourceManager.LINE_AND_COLUMN, 
                      p.getCoordinates());
              }
              else return "";
                }

                public boolean canMapValue(Object applicationValue)
                {
              return true;
                }        
            },
              new StateMonitor.DomainMatcher()
            {
               public boolean domainMatches(Object domainKey) 
                {
              return domainKey!=null 
                  && domainKey.equals(ExplorerView.this);
                }
            });
  layoutStatusBarComponents();
    }

    private void layoutStatusBarComponents()
    {
  statusBar.removeAll();
  for (Iterator it=dockedStatusComponents.iterator();it.hasNext();)
  {
      statusBar.add((JComponent)it.next());
      if (it.hasNext())
    statusBar.add(Box.createHorizontalGlue());
  }
  statusBar.invalidate();

  if (appFrame!=null)
  {
      Dimension d=appFrame.getSize();
      appFrame.pack();
      appFrame.setSize(d);
      appFrame.repaint();
  }
    }

    private void resetStatusBar()
    {
  if (!dockedStatusComponents.contains(statusField))
  {
      swapStatus((JComponent)dockedStatusComponents.get(0), statusField);
  }
    }

    /**
     *  add the buffer to the application container widget
     */
    public void dock(Buffer buffer)
    {       
  if (! dockedBuffers.contains(buffer))
      dockedBuffers.add(buffer);
  buffer.docking();
  resetStatusBar();
  redoLayout();
  focus(buffer);
    }  

    /**
     *  remove the buffer from the application container widget
     */
    public void undock(Buffer buffer)
    {
  if (buffer instanceof Explorer)
  {
      Debug.trace(this, Debug.DP3, "attempting to undock an Explorer");
      return;
  }
  else
  {
      Debug.trace(this, Debug.DP3, "undocking "+buffer);
  }
  if (dockedBuffers.contains(buffer))
  {
      int index=dockedBuffers.indexOf(buffer);
      dockedBuffers.remove(buffer);
      buffer.undocking();
      resetStatusBar();
      redoLayout();
      //show the nearest buffer to the one that was removed.
      if (index>=dockedBuffers.size())
    index--;
      focus((Buffer)dockedBuffers.get(index));

  }
    }

    /**
     *  @return list of current docked buffers
     */
    public Iterator getDockedBuffers()
    {
  return dockedBuffers.listIterator();
    }

    /**
     *  ensure that the specified docked buffer is visible and has focus
     */ 
    public void focus(Buffer buffer)
    {
  if (dockedBuffers.size()>1 
      && getAppContext().getDockMode().equals(DockMode.TABBED_PANE_MODE))
  {
      tabPane.setSelectedComponent(buffer.getComponent());
  }
  focussedBuffer=buffer;
    }  

    /**
     * @return the buffer that has focus, or null if there are no buffers
     */
    public Buffer getFocussedBuffer()
    {
  return focussedBuffer;
    }
     /**
      * attempt to set for the given buffer the given visibility.
      * Depending on the dock mode, certain settings of this property
      * may be vetoed (e.g., in EMACS_MODE, at least one buffer must
      * be visible at all times, so setting the only visible buffer
      * invisible would not be permitted.)  A change of visibility
      * may entail a change to the focusedBuffer property, but it may
      * not change the visibility of another buffer.  (Hence, for
      * single-buffer dock modes (like TABBED_PANE_MODE, if restricted to one frame)
      * the setVisible method should throw an UnsupportedOperationException.)
      * Preconditions: the buffer must be docked and non-null.
      * 
      */
     public void setVisible(Buffer buffer, boolean visible) 
   throws UnsupportedOperationException, PropertyVetoException
    {
  if (getAppContext().getDockMode().equals(DockMode.TABBED_PANE_MODE))
      throw new UnsupportedOperationException("setVisible not supported for DockMode.TABBED_PANE_MODE");
    }

    /**      
     * @return whether the given buffer is visible
     */
    public boolean isVisible(Buffer buffer)
    {
  if (getAppContext().getDockMode().equals(DockMode.TABBED_PANE_MODE))
      return buffer.equals(focussedBuffer);
  //no other modes implemented yet
  return false;
    }

    public void dispose()
    {
  appFrame.dispose();
  StateMonitor.unregisterProperty(locationField, "text", StateProperties.CARET_POSITION);
    }

    public void showStatus(String message)
    {
  statusField.setText(message);
    }

    /**
     * add a component to the status bar
     */
    public void dockStatus(JComponent statusComponent)
    {
  swapStatus(statusField, statusComponent);
    }

    /**
     * remove a component from the status bar
     */
    public void undockStatus(JComponent statusComponent)
    {
  swapStatus(statusComponent, statusField);
    }

    private void swapStatus(JComponent firstComp, JComponent secondComp)
    {
  if (dockedStatusComponents.contains(firstComp))
  {
      int index=dockedStatusComponents.indexOf(firstComp);
      dockedStatusComponents.remove(firstComp);
      dockedStatusComponents.add(index, secondComp);
      layoutStatusBarComponents();
  }
  else Debug.trace(this, Debug.DP3, "Component {0} not status-docked, cannot swap", firstComp);
    }

    private String getBufferName(Buffer buffer)
    {
  String bs=buffer.getName();
  if (buffer instanceof DAVEditor)
  {
      if (((DAVEditor)buffer).isDirty())
      {
    return new StringBuffer(bs).append('*').toString();
      }
  }
  return bs;
    }

    public void bufferDirtinessChanged(Buffer buffer)
    {
  int index=tabPane.indexOfComponent(buffer.getComponent());
  if (index!=-1)
  {
      tabPane.setTitleAt(index, getBufferName(buffer));
  }
  if (buffer.equals(focussedBuffer) && buffer instanceof DAVEditor)
  {
      StateMonitor.setProperty(StateProperties.EDITOR_IN_FOCUS_AND_DIRTY,
             new Boolean(((DAVEditor)buffer).isDirty()),
             null);
  }
    }

    private void redoLayout()
    {
  locationField.setText("");
  if (dockedBuffers.size()==1)
  {
      Debug.trace(this, Debug.DP3, "only one buffer docked");
      JPanel basePanel=new JPanel(new BorderLayout());
      basePanel.add(statusBar, BorderLayout.SOUTH);
      JComponent jc=((Buffer)dockedBuffers.get(0)).getComponent();
      basePanel.add(jc, BorderLayout.CENTER);
      appFrame.setContentPane(basePanel);
  }
  else
  {
      if (getAppContext().getDockMode().equals(DockMode.TABBED_PANE_MODE))
      {
    Debug.trace(this, Debug.DP3, "adding tab");
    if (tabPane==null) 
    {
        tabPane=new JTabbedPane(SwingConstants.BOTTOM);
        tabPane.addChangeListener(new ChangeListener() {
          public void stateChanged(ChangeEvent cheese)
          {
        setFocussedBufferFromTabPane();
        resetStatusBar();
          }
      });
        tabPane.setBackground(UIManager.getColor("Label.background"));
        tabPane.setOpaque(true);
    }
    Dimension d0=appFrame.getContentPane().getPreferredSize();
    Dimension d1=appFrame.getContentPane().getSize();
    Dimension d=(d1==null) ? d0 : d1;
    tabPane.removeAll();
    for (ListIterator lit=dockedBuffers.listIterator();lit.hasNext();)
    {
        Buffer buffy=(Buffer)lit.next();
        tabPane.addTab(getBufferName(buffy), buffy.getComponent());
    }
    tabPane.setPreferredSize(d);
    JPanel basePanel=new JPanel(new BorderLayout());
    basePanel.add(statusBar, BorderLayout.SOUTH);
    basePanel.add(tabPane, BorderLayout.CENTER);
    basePanel.setPreferredSize(d);
    appFrame.setContentPane(basePanel);
      }
  }
         appFrame.invalidate();
  appFrame.validate();
  appFrame.repaint();
    }

    private void setFocussedBufferFromTabPane()
    {
  Component c=tabPane.getSelectedComponent();
  for (Iterator it=getDockedBuffers();it.hasNext();)
  {
      Buffer buffy=(Buffer)it.next();
      JComponent jc=buffy.getComponent();
      if (jc.equals(c)) 
      {
    focussedBuffer=buffy;
    boolean haveAnEditor=buffy instanceof DAVEditor;
    StateMonitor.setProperty(StateProperties.EDITOR_IN_FOCUS, 
           new Boolean(haveAnEditor), 
           null);
    StateMonitor.setProperty(StateProperties.EDITOR_IN_FOCUS_AND_DIRTY,
           new Boolean(haveAnEditor && ((DAVEditor)buffy).isDirty()),
           null);
    break;
      }
  }
    }
}

/* $Log: ExplorerView.java,v $
/* Revision 1.13  2001/07/22 07:04:24  smulloni
/* changed the handling of release number.
/*
/* Revision 1.12  2000/12/19 22:36:05  smulloni
/* adjustments to preamble.
/*
/* Revision 1.11  2000/12/19 19:22:22  smulloni
/* some tweaks: ExitAction now cleans up the app's buffers.  The app now does
/* not resize every time a buffer is added or removed.
/*
/* Revision 1.10  2000/12/04 23:51:16  smulloni
/* added ImageViewer; fixed word in SimpleTextEditor
/*
/* Revision 1.9  2000/12/03 23:53:26  smulloni
/* added license and copyright preamble to java files.
/*
/* Revision 1.8  2000/12/01 16:25:52  smullyan
/* improvements to look and feel; fixed NPE in DAVFile; new actions for text
/* editor
/*
/* Revision 1.7  2000/11/29 23:16:04  smullyan
/* adding first rough cut of search capability to the text editor.  View
/* is being updated to allow components to be docked into the status bar.
/*
/* Revision 1.6  2000/11/28 00:01:38  smullyan
/* added a status bar/minibuffer, with a location field showing the current line and
/* column number (for the SimpleTextEditor and kin only).
/*
/* Revision 1.5  2000/11/22 00:11:27  smullyan
/* editor now locks and unlocks, more or less appropriately.
/*
/* Revision 1.4  2000/11/20 23:30:21  smullyan
/* more editor integration work.
/*
/* Revision 1.3  2000/11/18 04:36:04  smullyan
/* work on StateMonitor and related functionality.
/*
/* Revision 1.2  2000/11/17 20:25:05  smullyan
/* new SaveAction; a StateMonitor being added to handle application state.
/*
/* Revision 1.1  2000/11/16 20:45:18  smullyan
/* the start of editor integration.
/* */
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.