Swing JFC Java

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyVetoException;
import java.io.FileReader;
import javax.swing.DefaultDesktopManager;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JViewport;
import javax.swing.event.MouseInputAdapter;
public class JavaXWin extends JFrame
{
  protected int m_count;
  protected int m_tencount;
  protected int m_wmX, m_wmY;
  protected JButton m_newFrame;
  protected JDesktopPane m_desktop;
  protected WindowManager m_wm;
  protected JViewport viewport;
  
  public JavaXWin() {
    setTitle("JavaXWin");
    m_count = m_tencount = 0;
    m_desktop = new JDesktopPane();
    JScrollPane scroller = new JScrollPane();
    m_wm = new WindowManager(m_desktop);
    m_desktop.setDesktopManager(m_wm);
    m_desktop.add(m_wm.getWindowWatcher(),
      JLayeredPane.PALETTE_LAYER);
    m_wm.getWindowWatcher().setBounds(555,5,200,150);
    viewport = new JViewport() {
      public void setViewPosition(Point p) { 
        super.setViewPosition(p); 
        m_wm.getWindowWatcher().setLocation(
          m_wm.getWindowWatcher().getX() +
            (getViewPosition().x-m_wmX),
          m_wm.getWindowWatcher().getY() +
            (getViewPosition().y-m_wmY));
        m_wmX = getViewPosition().x;
        m_wmY = getViewPosition().y;
      }
    };
    viewport.setView(m_desktop);
    scroller.setViewport(viewport);
    ComponentAdapter ca = new ComponentAdapter() {
      JViewport view = viewport;
      public void componentResized(ComponentEvent e) {
        m_wm.getWindowWatcher().setLocation(
          view.getViewPosition().x + view.getWidth()-
            m_wm.getWindowWatcher().getWidth()-15,
          view.getViewPosition().y + 5);
      }
    };
    viewport.addComponentListener(ca);
      
    m_newFrame = new JButton("New Frame");
    m_newFrame.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        newFrame();
      }
    });
    JPanel topPanel = new JPanel(true);
    topPanel.setLayout(new FlowLayout());
    getContentPane().setLayout(new BorderLayout());
    getContentPane().add("North", topPanel);
    getContentPane().add("Center", scroller);
    topPanel.add(m_newFrame);
    Dimension dim = getToolkit().getScreenSize();
    setSize(800,600);
    setLocation(dim.width/2-getWidth()/2,
      dim.height/2-getHeight()/2);
    m_desktop.setPreferredSize(new Dimension(1600,1200));
    setVisible(true);
    WindowListener l = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    };       
    addWindowListener(l);
  }
  public void newFrame() {
    JInternalFrame jif = new JInternalFrame("Frame " + m_count, 
      true, true, true, true);
    jif.setBounds(20*(m_count%10) + m_tencount*80, 
      20*(m_count%10), 200, 200);
    JTextArea text = new JTextArea();
    JScrollPane scroller = new JScrollPane();
    scroller.getViewport().add(text);
    try {
      FileReader fileStream = new FileReader("");
      text.read(fileStream, "JavaLinux.txt");
    }
    catch (Exception e) {
      text.setText("* Could not read JavaLinux.txt *");
    }
    jif.getContentPane().add(scroller);
    m_desktop.add(jif);
    try {            
      jif.setSelected(true);        
    }
    catch (PropertyVetoException pve) {
      System.out.println("Could not select " + jif.getTitle());
    }
    m_count++;
    if (m_count%10 == 0) {
      if (m_tencount < 3)
        m_tencount++;
      else 
        m_tencount = 0;
    }
  }
  public static void main(String[] args) {
    new JavaXWin();
  }
}
class WindowManager 
extends DefaultDesktopManager
{
  protected WindowWatcher ww;
  public WindowManager(JDesktopPane desktop) {
    ww = new WindowWatcher(desktop);
  }
  public WindowWatcher getWindowWatcher() { return ww; }
    
  public void activateFrame(JInternalFrame f) {
    super.activateFrame(f);
    ww.repaint();
  }
  public void beginDraggingFrame(JComponent f) { 
    super.beginDraggingFrame(f);
    ww.repaint();
  }
  public void beginResizingFrame(JComponent f, int direction) {
    super.beginResizingFrame(f,direction);
    ww.repaint();
  }
  public void closeFrame(JInternalFrame f) {
    super.closeFrame(f);
    ww.repaint();
  }
  public void deactivateFrame(JInternalFrame f) {
    super.deactivateFrame(f);
    ww.repaint();
  }
  public void deiconifyFrame(JInternalFrame f) {
    super.deiconifyFrame(f);
    ww.repaint();
  }
  public void dragFrame(JComponent f, int newX, int newY) {
    f.setLocation(newX, newY);
    ww.repaint();
  }
  public void endDraggingFrame(JComponent f) {
    super.endDraggingFrame(f);
    ww.repaint();
  }
  public void endResizingFrame(JComponent f) {
    super.endResizingFrame(f);
    ww.repaint();
  }
  public void iconifyFrame(JInternalFrame f) {
    super.iconifyFrame(f);
    ww.repaint();
  }
  public void maximizeFrame(JInternalFrame f) {
    super.maximizeFrame(f);
    ww.repaint();
  }
  public void minimizeFrame(JInternalFrame f) {
    super.minimizeFrame(f);
    ww.repaint();
  }
  public void openFrame(JInternalFrame f) {
    super.openFrame(f);
    ww.repaint();
  }
  public void resizeFrame(JComponent f,
   int newX, int newY, int newWidth, int newHeight) {
    f.setBounds(newX, newY, newWidth, newHeight);
    ww.repaint();
  }
  public void setBoundsForFrame(JComponent f,
   int newX, int newY, int newWidth, int newHeight) {
    f.setBounds(newX, newY, newWidth, newHeight);
    ww.repaint();
  }
}
class WindowWatcher extends JPanel
{
  protected static final Color C_UNSELECTED =
    new Color(123, 123, 123);
  protected static final Color C_SELECTED =
    new Color(243, 232, 165);
  protected static final Color C_BACKGROUND =
    new Color(5,165,165);
  protected static final Color C_WWATCHER =
    new Color(203,226,0);
  protected float m_widthratio, m_heightratio;
  protected int m_width, m_height, m_XDifference, m_YDifference;
  protected JDesktopPane m_desktop;
  protected NorthResizeEdge m_northResizer;
  protected SouthResizeEdge m_southResizer;
  protected EastResizeEdge m_eastResizer;
  protected WestResizeEdge m_westResizer;
  
  public WindowWatcher(JDesktopPane desktop) {
    m_desktop = desktop;
    setOpaque(true);
    m_northResizer = new NorthResizeEdge(this);
    m_southResizer = new SouthResizeEdge(this);
    m_eastResizer = new EastResizeEdge(this);
    m_westResizer = new WestResizeEdge(this);
    setLayout(new BorderLayout());
    add(m_northResizer, BorderLayout.NORTH);
    add(m_southResizer, BorderLayout.SOUTH);
    add(m_eastResizer, BorderLayout.EAST);
    add(m_westResizer, BorderLayout.WEST);
    MouseInputAdapter ma = new MouseInputAdapter() {
      public void mousePressed(MouseEvent e) {
        m_XDifference = e.getX();
        m_YDifference = e.getY();
      }
      public void mouseDragged(MouseEvent e) {
        int vx = 0;
        int vy = 0;
        if (m_desktop.getParent() instanceof JViewport) {
          vx = ((JViewport) 
            m_desktop.getParent()).getViewPosition().x;
          vy = ((JViewport) 
            m_desktop.getParent()).getViewPosition().y;
        }
        int w = m_desktop.getParent().getWidth();
        int h = m_desktop.getParent().getHeight();
        int x = getX();
        int y = getY();
        int ex = e.getX();
        int ey = e.getY(); 
        if ((ey + y > vy && ey + y < h+vy) && 
            (ex + x > vx && ex + x < w+vx)) 
        {
          setLocation(ex-m_XDifference + x, ey-m_YDifference + y);
        }
        else if (!(ey + y > vy && ey + y < h+vy) && 
                  (ex + x > vx && ex + x < w+vx)) 
        {
          if (!(ey + y > vy) && ey + y < h+vy)
            setLocation(ex-m_XDifference + x, vy-m_YDifference);
          else if (ey + y > vy && !(ey + y < h+vy))
            setLocation(ex-m_XDifference + x, (h+vy)-m_YDifference);
        }
        else if ((ey + y >vy && ey + y < h+vy) && 
                !(ex + x > vx && ex + x < w+vx)) 
        {
          if (!(ex + x > vx) && ex + x < w+vx)
            setLocation(vx-m_XDifference, ey-m_YDifference + y);
          else if (ex + x > vx && !(ex + x < w))
            setLocation((w+vx)-m_XDifference, ey-m_YDifference + y);
        }
        else if (!(ey + y > vy) && ey + y < h+vy && 
                 !(ex + x > vx) && ex + x < w+vx)
          setLocation(vx-m_XDifference, vy-m_YDifference);
        else if (!(ey + y > vy) && ey + y < h+vy && 
                 ex + x > vx && !(ex + x < w+vx)) 
          setLocation((w+vx)-m_XDifference, vy-m_YDifference);
        else if (ey + y > vy && !(ey + y < h+vy) && 
                 !(ex + x > vx) && ex + x < w+vx) 
          setLocation(vx-m_XDifference, (h+vy)-m_YDifference);
        else if (ey + y > vy && !(ey + y < h+vy) && 
                 ex + x > vx && !(ex + x < w+vx)) 
          setLocation((w+vx)-m_XDifference, (h+vy)-m_YDifference);
      }
      public void mouseEntered(MouseEvent e) {
        setCursor(Cursor.getPredefinedCursor(
          Cursor.MOVE_CURSOR));
      }
      public void mouseExited(MouseEvent e) {
        setCursor(Cursor.getPredefinedCursor(
          Cursor.DEFAULT_CURSOR));
      }
    };
    addMouseListener(ma);
    addMouseMotionListener(ma);
  } 
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    m_height = getHeight();
    m_width = getWidth(); 
    g.setColor(C_BACKGROUND);
    g.fillRect(0,0,m_width,m_height);
    Component[] components = m_desktop.getComponents();
    m_widthratio = ((float) 
      m_desktop.getWidth())/((float) m_width);
    m_heightratio = ((float) 
      m_desktop.getHeight())/((float) m_height);
    for (int i=components.length-1; i>-1; i--) {
      if (components[i].isVisible()) {
        g.setColor(C_UNSELECTED);
        if (components[i] instanceof JInternalFrame) {
          if (((JInternalFrame) components[i]).isSelected())
            g.setColor(C_SELECTED);
        }
        else if(components[i] instanceof WindowWatcher)
          g.setColor(C_WWATCHER);
        g.fillRect(
          (int)(((float)components[i].getX())/m_widthratio),
          (int)(((float)components[i].getY())/m_heightratio),
          (int)(((float)components[i].getWidth())/m_widthratio), 
          (int)(((float)components[i].getHeight())/m_heightratio));
        g.setColor(Color.black);
        g.drawRect(
          (int)(((float)components[i].getX())/m_widthratio), 
          (int)(((float)components[i].getY())/m_heightratio),
          (int)(((float)components[i].getWidth())/m_widthratio), 
          (int)(((float)components[i].getHeight())/m_heightratio));
      }        
    }
    g.drawLine(m_width/2,0,m_width/2,m_height);
    g.drawLine(0,m_height/2,m_width,m_height/2);
  }
}
class EastResizeEdge extends JPanel
  implements MouseListener, MouseMotionListener {
    private int WIDTH = 3;
    private int MIN_WIDTH = 50;
    private boolean m_dragging;
    private JComponent m_resizeComponent;
  
    public EastResizeEdge(JComponent c) {
      m_resizeComponent = c;
      addMouseListener(this);
      addMouseMotionListener(this);
      setOpaque(true);
      setBackground(Color.black);
    }
    public Dimension getPreferredSize() {
      return new Dimension(WIDTH, m_resizeComponent.getHeight());
    }
    public void mouseClicked(MouseEvent e) {}
    public void mouseMoved(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {
      m_dragging = false;
    }
    public void mouseDragged(MouseEvent e) {
      if (m_resizeComponent.getWidth() + e.getX() >= MIN_WIDTH)
        m_resizeComponent.setBounds(m_resizeComponent.getX(), 
          m_resizeComponent.getY(), 
          m_resizeComponent.getWidth() + e.getX(),
          m_resizeComponent.getHeight());
      else
        m_resizeComponent.setBounds(m_resizeComponent.getX(), 
          m_resizeComponent.getY(), 
          MIN_WIDTH, m_resizeComponent.getHeight());
      m_resizeComponent.validate();
    }
    public void mouseEntered(MouseEvent e) {
      if (!m_dragging)
        setCursor(Cursor.getPredefinedCursor(
          Cursor.E_RESIZE_CURSOR));
    }
    
    public void mouseExited(MouseEvent e) {
      if (!m_dragging)
        setCursor(Cursor.getPredefinedCursor(
          Cursor.DEFAULT_CURSOR));
    }
  
    public void mousePressed(MouseEvent e) {
      //toFront();
      m_dragging = true;
    }  
  }
class NorthResizeEdge extends JPanel
  implements MouseListener, MouseMotionListener {
    private static final int NORTH = 0;
    private static final int NORTHEAST = 1;
    private static final int NORTHWEST = 2;
    private int CORNER = 10;
    private int HEIGHT = 3;
    private int MIN_WIDTH = 50;
    private int MIN_HEIGHT = 50;
    private int m_width, m_dragX, m_dragY, m_rightX, m_lowerY;
    private boolean m_dragging;
    private JComponent m_resizeComponent;
    private int m_mode;
    
    public NorthResizeEdge(JComponent c) {
      m_resizeComponent = c;
      addMouseListener(this);
      addMouseMotionListener(this);
      setOpaque(true);
      setBackground(Color.black);
    }
    public Dimension getPreferredSize() {
      return new Dimension(m_resizeComponent.getWidth(), HEIGHT);
    }
    public void mouseClicked(MouseEvent e) {}
    public void mouseMoved(MouseEvent e) {
      if (!m_dragging) {
        if (e.getX() < CORNER) {
          setCursor(Cursor.getPredefinedCursor(
            Cursor.NW_RESIZE_CURSOR));
        }
        else if(e.getX() > getWidth()-CORNER) {
          setCursor(Cursor.getPredefinedCursor(
            Cursor.NE_RESIZE_CURSOR));
        }
        else {
          setCursor(Cursor.getPredefinedCursor(
            Cursor.N_RESIZE_CURSOR));
        }
      }
    }
    public void mouseReleased(MouseEvent e) {
      m_dragging = false;
    }
    public void mouseDragged(MouseEvent e) {
      int h = m_resizeComponent.getHeight();
      int w = m_resizeComponent.getWidth();
      int x = m_resizeComponent.getX();
      int y = m_resizeComponent.getY();
      int ex = e.getX();
      int ey = e.getY();
      switch (m_mode) {
        case NORTH:
          if (h-(ey-m_dragY) >= MIN_HEIGHT)
            m_resizeComponent.setBounds(x, y + (ey-m_dragY), 
              w, h-(ey-m_dragY));
          else
              m_resizeComponent.setBounds(x, 
                m_lowerY-MIN_HEIGHT, w, MIN_HEIGHT);
          break;
        case NORTHEAST:
          if (h-(ey-m_dragY) >= MIN_HEIGHT
          && w + (ex-(getWidth()-CORNER)) >= MIN_WIDTH)
            m_resizeComponent.setBounds(x, 
              y + (ey-m_dragY), w + (ex-(getWidth()-CORNER)),
                h-(ey-m_dragY));
          else if (h-(ey-m_dragY) >= MIN_HEIGHT
          && !(w + (ex-(getWidth()-CORNER)) >= MIN_WIDTH))
            m_resizeComponent.setBounds(x, 
              y + (ey-m_dragY), MIN_WIDTH, h-(ey-m_dragY));
          else if (!(h-(ey-m_dragY) >= MIN_HEIGHT)
          && w + (ex-(getWidth()-CORNER)) >= MIN_WIDTH)
            m_resizeComponent.setBounds(x, 
              m_lowerY-MIN_HEIGHT, w + (ex-(getWidth()-CORNER)), 
                MIN_HEIGHT);
          else
            m_resizeComponent.setBounds(x, 
              m_lowerY-MIN_HEIGHT, MIN_WIDTH, MIN_HEIGHT);
          break;
        case NORTHWEST:
          if (h-(ey-m_dragY) >= MIN_HEIGHT
          && w-(ex-m_dragX) >= MIN_WIDTH)
            m_resizeComponent.setBounds(x + (ex-m_dragX), 
              y + (ey-m_dragY), w-(ex-m_dragX),
                h-(ey-m_dragY));
          else if (h-(ey-m_dragY) >= MIN_HEIGHT
          && !(w-(ex-m_dragX) >= MIN_WIDTH)) {
            if (x + MIN_WIDTH < m_rightX) 
              m_resizeComponent.setBounds(m_rightX-MIN_WIDTH, 
                y + (ey-m_dragY), MIN_WIDTH, h-(ey-m_dragY));
            else
              m_resizeComponent.setBounds(x, 
                y + (ey-m_dragY), w, h-(ey-m_dragY));
          } 
          else if (!(h-(ey-m_dragY) >= MIN_HEIGHT)
          && w-(ex-m_dragX) >= MIN_WIDTH) 
            m_resizeComponent.setBounds(x + (ex-m_dragX), 
              m_lowerY-MIN_HEIGHT, w-(ex-m_dragX), MIN_HEIGHT);
          else
            m_resizeComponent.setBounds(m_rightX-MIN_WIDTH, 
              m_lowerY-MIN_HEIGHT, MIN_WIDTH, MIN_HEIGHT);
          break;
      }
      m_rightX = x + w;
      m_resizeComponent.validate();
    }
  
    public void mouseEntered(MouseEvent e) {
      mouseMoved(e);
    }
    
    public void mouseExited(MouseEvent e) {
      if (!m_dragging)
        setCursor(Cursor.getPredefinedCursor(
          Cursor.DEFAULT_CURSOR));
    }
    
    public void mousePressed(MouseEvent e) {
      m_dragging = true;
      m_dragX = e.getX();
      m_dragY = e.getY();
      m_lowerY = m_resizeComponent.getY()
        + m_resizeComponent.getHeight();
      if (e.getX() < CORNER) {
        m_mode = NORTHWEST;
      }
      else if(e.getX() > getWidth()-CORNER) {
        m_mode = NORTHEAST;
      }
      else {
        m_mode = NORTH;    
      }
    }  
  }
class SouthResizeEdge extends JPanel
  implements MouseListener, MouseMotionListener {
    private static final int SOUTH = 0;
    private static final int SOUTHEAST = 1;
    private static final int SOUTHWEST = 2;
    private int CORNER = 10;
    private int HEIGHT = 3;
    private int MIN_WIDTH = 50;
    private int MIN_HEIGHT = 50;
    private int m_width, m_dragX, m_dragY, m_rightX;
    private boolean m_dragging;
    private JComponent m_resizeComponent;
    private int m_mode;
    
    public SouthResizeEdge(JComponent c) {
      m_resizeComponent = c;
      addMouseListener(this);
      addMouseMotionListener(this);
      setOpaque(true);
      setBackground(Color.black);
    }
    public Dimension getPreferredSize() {
      return new Dimension(m_resizeComponent.getWidth(), HEIGHT);
    }
  
    public void mouseClicked(MouseEvent e) {}
  
    public void mouseMoved(MouseEvent e) {
      if (!m_dragging) {
        if (e.getX() < CORNER) {
          setCursor(Cursor.getPredefinedCursor(
            Cursor.SW_RESIZE_CURSOR));
        }
        else if(e.getX() > getWidth()-CORNER) {
          setCursor(Cursor.getPredefinedCursor(
            Cursor.SE_RESIZE_CURSOR));
        }
        else {
          setCursor(Cursor.getPredefinedCursor(
            Cursor.S_RESIZE_CURSOR));
        }
      }
    }
  
    public void mouseReleased(MouseEvent e) {
      m_dragging = false;
    }
  
    public void mouseDragged(MouseEvent e) {
      int h = m_resizeComponent.getHeight();
      int w = m_resizeComponent.getWidth();
      int x = m_resizeComponent.getX();
      int y = m_resizeComponent.getY();
      int ex = e.getX();
      int ey = e.getY();
      switch (m_mode) {
        case SOUTH:
          if (h+(ey-m_dragY) >= MIN_HEIGHT)
           m_resizeComponent.setBounds(x, y, w, h+(ey-m_dragY));
          else
            m_resizeComponent.setBounds(x, y, w, MIN_HEIGHT);
          break;
        case SOUTHEAST:
          if (h+(ey-m_dragY) >= MIN_HEIGHT
            && w + (ex-(getWidth()-CORNER)) >= MIN_WIDTH)
            m_resizeComponent.setBounds(x, y, 
              w + (ex-(getWidth()-CORNER)), h+(ey-m_dragY));
          else if (h+(ey-m_dragY) >= MIN_HEIGHT
            && !(w + (ex-(getWidth()-CORNER)) >= MIN_WIDTH))
            m_resizeComponent.setBounds(x, y, 
              MIN_WIDTH, h+(ey-m_dragY));
          else if (!(h+(ey-m_dragY) >= MIN_HEIGHT)
            && w + (ex-(getWidth()-CORNER)) >= MIN_WIDTH)
            m_resizeComponent.setBounds(x, y, 
              w + (ex-(getWidth()-CORNER)), MIN_HEIGHT);
          else
            m_resizeComponent.setBounds(x, 
              y, MIN_WIDTH, MIN_HEIGHT);
          break;
        case SOUTHWEST:
          if (h+(ey-m_dragY) >= MIN_HEIGHT 
            && w-(ex-m_dragX) >= MIN_WIDTH)
            m_resizeComponent.setBounds(x + (ex-m_dragX), y, 
              w-(ex-m_dragX), h+(ey-m_dragY));
          else if (h+(ey-m_dragY) >= MIN_HEIGHT
            && !(w-(ex-m_dragX) >= MIN_WIDTH)) {
            if (x + MIN_WIDTH < m_rightX)
              m_resizeComponent.setBounds(m_rightX-MIN_WIDTH, y, 
                MIN_WIDTH, h+(ey-m_dragY));
            else
              m_resizeComponent.setBounds(x, y, w, 
                h+(ey-m_dragY));
          }
          else if (!(h+(ey-m_dragY) >= MIN_HEIGHT)
            && w-(ex-m_dragX) >= MIN_WIDTH)
            m_resizeComponent.setBounds(x + (ex-m_dragX), y, 
              w-(ex-m_dragX), MIN_HEIGHT);
          else
            m_resizeComponent.setBounds(m_rightX-MIN_WIDTH, 
              y, MIN_WIDTH, MIN_HEIGHT);
          break;
      }
      m_rightX = x + w;
      m_resizeComponent.validate();
    }
  
    public void mouseEntered(MouseEvent e) {
      mouseMoved(e);
    }
    
    public void mouseExited(MouseEvent e) {
      if (!m_dragging)
        setCursor(Cursor.getPredefinedCursor(
          Cursor.DEFAULT_CURSOR));
    }
    
    public void mousePressed(MouseEvent e) {
      //toFront();
      m_dragging = true;
      m_dragX = e.getX();
      m_dragY = e.getY();
      if (e.getX() < CORNER) {
        m_mode = SOUTHWEST;
      }
      else if(e.getX() > getWidth()-CORNER) {
        m_mode = SOUTHEAST;
      }
      else {
        m_mode = SOUTH;    
      }
    }  
  }
class WestResizeEdge extends JPanel
  implements MouseListener, MouseMotionListener {
    private int WIDTH = 3;
    private int MIN_WIDTH = 50;
    private int m_dragX, m_rightX;
    private boolean m_dragging;
    private JComponent m_resizeComponent;
  
    public WestResizeEdge(JComponent c) {
      m_resizeComponent = c;
      addMouseListener(this);
      addMouseMotionListener(this);
      setOpaque(true);
      setBackground(Color.black);
    }
    public Dimension getPreferredSize() {
      return new Dimension(WIDTH, m_resizeComponent.getHeight());
    }
    public void mouseClicked(MouseEvent e) {}
    public void mouseMoved(MouseEvent e) {}
  
    public void mouseReleased(MouseEvent e) {
      m_dragging = false;
    }
    public void mouseDragged(MouseEvent e) {
      if (m_resizeComponent.getWidth()-
       (e.getX()-m_dragX) >= MIN_WIDTH)
        m_resizeComponent.setBounds(
          m_resizeComponent.getX() + (e.getX()-m_dragX), 
          m_resizeComponent.getY(), 
          m_resizeComponent.getWidth()-(e.getX()-m_dragX),
          m_resizeComponent.getHeight());
      else
        if (m_resizeComponent.getX() + MIN_WIDTH < m_rightX)
          m_resizeComponent.setBounds(m_rightX-MIN_WIDTH, 
            m_resizeComponent.getY(), 
            MIN_WIDTH, m_resizeComponent.getHeight());
        else
          m_resizeComponent.setBounds(m_resizeComponent.getX(), 
            m_resizeComponent.getY(), 
            MIN_WIDTH, m_resizeComponent.getHeight());
      m_resizeComponent.validate();
    }
  
    public void mouseEntered(MouseEvent e) {
      if (!m_dragging)
        setCursor(Cursor.getPredefinedCursor(
          Cursor.W_RESIZE_CURSOR));
    }
    
    public void mouseExited(MouseEvent e) {
      if (!m_dragging)
        setCursor(Cursor.getPredefinedCursor(
          Cursor.DEFAULT_CURSOR));
    }
    
    public void mousePressed(MouseEvent e) {
      //toFront();
      m_rightX = m_resizeComponent.getX() + 
        m_resizeComponent.getWidth();
      m_dragging = true;
      m_dragX = e.getX();
    }  
  }