用Java实现的Status Bar (2/3)- StatusbarBuilder.java

相关文章:

/*===============================================================================

 * StatusbarBuilder.java

 *===============================================================================

 *  This program 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 of the License, or

 *  (at your option) any later version.

 * 

 *  This program 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 this program; if not, write to the Free Software

 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

 *===============================================================================

 * auth:    Jason

 * CSDN ID:    Unagain

 * Email:    tl21cen@hotmail.com

 * date:    2006-4-11

 *===============================================================================

 */

package tl.util;

 

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Component;

import java.awt.Cursor;

import java.awt.Dimension;

import java.awt.Graphics;

import java.awt.Point;

import java.awt.Rectangle;

import java.awt.Window;

import java.awt.event.MouseEvent;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import java.util.Hashtable;

 

import javax.swing.Box;

import javax.swing.BoxLayout;

import javax.swing.JComponent;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.border.AbstractBorder;

import javax.swing.border.BevelBorder;

import javax.swing.border.EmptyBorder;

import javax.swing.event.MouseInputAdapter;

import javax.swing.text.JTextComponent;

 

//class StatusBar extends JComponent {

public class StatusbarBuilder {

    //final static Dimension XGAP = new Dimension(2, 0);

 

    private JPanel bar;

 

    /**

     * matains all instances created, each instance associate

     * with an existing window object.<br>

     * you can create and to obtain a instance using newInstance

     * method with a specified window object.

     */

    private static

    Hashtable<Window, StatusbarBuilder> instances =

       new Hashtable<Window, StatusbarBuilder>();

 

    private Window window;

 

    final public static int PLAIN = 0;

 

    final public static int LOWERED = 1;

 

    /**

     *  @deprecated

     */

    final public static int RAISED = 2;

 

    // for builder

    private static int commonBarStyle = LOWERED;

 

    // for instance

    private AbstractBorder border = null;

 

    // test

    private int style;

 

    /**

     * only two style can be used for the bar, PLAIN or

     * LOWERED. I try to make cell's border to be RAISED

     * earlier, but it looks ugly.

     * <br><i>WARNING: </i>result of this method can only

     * effect the instance created next but not an instance

     * has been created prior. And you also be caution that

     * the effect will be acting for any instance created

     * subsequently until you invoked it again to set other

     * value. <br>

     * call reset method can reset all properties changed to

     *  be default.

     * @param style

     */

    public static void setBarStyle(int style) {

       if (style < PLAIN || style > LOWERED) {

           commonBarStyle = PLAIN;

       } else {

           commonBarStyle = style;

       }

    }

 

    // for builder

    private static Color commonBkColor = null;

    // for instance

    private Color bkColor = null;

 

    /**

     * set background color of bar.

     * <br><i>WARNING: </i>result of this method can only

     * effect the instance created next but not an instance

     * has been created prior. And you also be caution that

     * the effect will be acting for any instance created

     * subsequently until you invoked it again to set other

     * value. <br>

     * call reset method can reset all properties changed to

     *  be default.

     * @param color

     */

    public static void setBackground(Color color) {

        commonBkColor = color;

    }

 

    final static int DEFAULT_HEIGHT = 23;

    private static int commonHeight = 0;

    private int height = 0;

 

    /**

     * set the height of cell in bar

     * <br><i>WARNING: </i>result of this method can only

     * effect the instance created next but not an instance

     * has been created prior. And you also be caution that

     * the effect will be acting for any instance created

     * subsequently until you invoked it again to set other

     * value. <br>

     * call reset method can reset all properties changed to

     *  be default.

     * @param height

     */

    public static void setHeight(int height) {

        commonHeight = height;

    }

 

    final static int DEFAULT_GAP_WIDTH = 2;

    private static int gapWidth = DEFAULT_GAP_WIDTH;

    private int gw = 0;

 

    /**

    * In fact, it is used to set the width of gap.

     * <br><i>WARNING: </i>result of this method can only

     * effect the instance created next but not an instance

     * has been created prior. And you also be caution that

     * the effect will be acting for any instance created

     * subsequently until you invoked it again to set other

     * value. <br>

     * call reset method can reset all properties changed to

     *  be default.

     * @param width

     */

    public static void setGap(int width) {

        gapWidth = width;

    }

   

    private static JComponent commonNotice = null;

    private JComponent notice;

    /**

     * I think perhaps you've got a custom component that

     * can show help message more effective.

     * I hope it can be used on this bar directly.

     * <br><i>WARNING: </i>result of this method can only

     * effect the instance created next but not an instance

     * has been created prior. And you also be caution that

     * the effect will be acting for any instance created

     * subsequently until you invoked it again to set other

     * value. <br>

     * call reset method can reset all properties changed to

     *  be default.

     * @param comp a custom component can show help message.

     */

    public static void setNotice(JComponent comp) {

        commonNotice = comp;

    }

   

    public static void reset() {

        commonBarStyle = LOWERED;

        commonBkColor = null;

        commonHeight = DEFAULT_HEIGHT;

        gapWidth = DEFAULT_GAP_WIDTH;

        commonNotice = null;

    }

   

    /**

     * send a message to bar, so can be appeared in bar.<br>

     * <i>be cauthion</i> that it will do nothing if it is a custom

     * component you applied, and it isn't an instance of JLabel

     * and any other subclass of JTextComponent.

     * @param s a message

     */

    public void notice(String s) {

       if (notice instanceof JLabel) {

           ((JLabel)notice).setText(s);

       } else if (notice instanceof JTextComponent) {

           ((JTextComponent)notice).setText(s);

       }

    }

   

    /**

     * By default, notice cell hasn't border. so this method

     * can be use to set whether notice cell can has a border.

     *  

     * @param style @see @link

     */

    public void setNoticeStyle (int style) {

       if (style == PLAIN) {

           if (border instanceof EmptyBorder) {

               notice.setBorder(border);

           } else {

               notice.setBorder(

                  new EmptyBorder(1,1,1,1));

           }

       } else if (style == LOWERED) {

           if (border instanceof BevelBorder) {

               notice.setBorder(border);

           } else {

               notice.setBorder(

                  new SlightBevelBorder(BevelBorder.LOWERED));

           }          

       }

    }

 

    /**

     * Create a status bar for the window given. by default, the

     * window use BorderLayout as its layout mananger, and the

     * status bar created will reside on bottom of the window.

     * 

     * @param window

     * @return

     */

    public static StatusbarBuilder getInstance(Window window) {

        return getInstance(window, BorderLayout.PAGE_END);

    }

 

    /**

     * Create a status bar for a window given. User apply 

     * constraints for status to reside in the window.

     *

     * @param window

     * @param constraints

     * @return

     */

    public static StatusbarBuilder getInstance(Window window,

           Object constraints) {

       // get instance from pool.

        StatusbarBuilder instance = instances.get(window);

 

       // create a new instance if there isn't a instance associate

       // the window.

       if (instance == null) {

           instance = new StatusbarBuilder();

 

           // pool the new instance.

           instances.put(window, instance);

 

           window.add(instance.bar, constraints);

           instance.window = window;          

 

           // create a monitor on window, so that statusbar can be

           // released before window wiil be deactivate.

           window.addWindowListener(new WindowAdapter() {

               public void windowClosed(WindowEvent e) {

                   Window window = e.getWindow();

                   System.out.println(window);

                   StatusbarBuilder inst = instances.get(window);

                   System.out.println(inst);

                  inst = null;

                   instances.remove(window);

                   System.out.println("gfgfff");

               }

           });

       }

        return instance;

    }

 

    private RBCorner corner;

    /**

     * create a inew instance of status bar. Each status bar created

     * belones to a window specified.

     */

    private StatusbarBuilder() {

       bar = new JPanel();

        bar.setLayout(new BoxLayout(bar, BoxLayout.LINE_AXIS));

        bar.setBorder(new EmptyBorder(2, 0, 1, 1));

 

       // initialize instance variable.

        height = commonHeight == 0 ? DEFAULT_HEIGHT : commonHeight;

 

        bkColor = commonBkColor == null ? bar.getBackground() : commonBkColor;

 

       // prepare border

       style = commonBarStyle;

       if (commonBarStyle == LOWERED) {

           border = new SlightBevelBorder(BevelBorder.LOWERED);

       } else if (commonBarStyle == RAISED) {

           border = new SlightBevelBorder(BevelBorder.RAISED);

       } else {

           border =

           //new LineBorder(bkColor);

           new EmptyBorder(2, 2, 2, 2);

       }

 

       // initialize a gap used for separate cells.

       // gw = gapWidth == 0 ? DEFAULT_GAP_WIDTH : gapWidth;

       gw = gapWidth;

 

        bar.setBackground(bkColor);

        //bar.setMinimumSize(new Dimension(50, height));

        //bar.setMaximumSize(new Dimension(5000, height));      

 

        bar.add(Box.createRigidArea(new Dimension(0, height)));

      

        corner = new RBCorner();

        corner.setBorder(border);

        bar.add(corner);

 

       // At first, it used to show notice such as help message.

       // In addition, it used to fill increased space if bar

       // was stretched.

       if (commonNotice == null) {

           notice = new JLabel();

       } else {

           notice = commonNotice;

       }

        notice.setMinimumSize(new Dimension(50, height));

        notice.setMaximumSize(new Dimension(5000, height));      

 

        //notice.setBorder(border);

        bar.add(notice);

        bar.add(createGap());

    }

 

    // 增加显示格。在添加到Container之前,设置其Border

    /**

     * add a cell to the bar, and its height will be

     * changed to predefined height.

     *

     * @param comp

     */

    public void add(JComponent comp) {

        Dimension minSize = comp.getMinimumSize();

        Dimension prefSize = comp.getPreferredSize();

        Dimension maxSize = comp.getMaximumSize();

 

       add(comp, minSize.width, prefSize.width, maxSize.width);

    }

 

    /**

     * add a cell with a specified solid width.

     *  

     * @param comp

     * @param solidWidth

     */

    public void add(JComponent comp, int solidWidth) {

       add(comp, solidWidth, solidWidth, solidWidth);

    }

 

    /**

     * add a cell with specified minimum width and max width.

     * @param comp

     * @param minWidth

     * @param maxWidth

     */

    public void add(JComponent comp, int minWidth, int maxWidth) {

       add(comp, minWidth, minWidth, maxWidth);

    }

 

    /**

     * add a component to the bar with specified minimum

     * width, preffered width and maximum width.<br>

     * The effect doesn't observable. It seens that width

     * of other cell won't change until notice cell reduced

     * to its minimum size when the window's width reduced.  

     *

     * @param comp

     * @param minWidth

     * @param prefWidth

     * @param maxWidth

     */

    public void add(JComponent comp, int minWidth, int prefWidth, int maxWidth) {

       if (comp != corner) {

           bar.remove(corner);

       }

      

        comp.setBorder(border);

 

        comp.setMinimumSize(new Dimension(minWidth, height));

        comp.setPreferredSize(new Dimension(prefWidth, height));

        comp.setMaximumSize(new Dimension(maxWidth, height));

 

       // 按默认的添加方式,显示格会挤在一起,所以之间填充一个水平的刚性支撑。

        //System.out.println(bar.add(gap));

        //bar.add(gap);

      

        bar.add(comp);

      

        bar.add(createGap());

      

       if (comp != corner) {

           bar.add(corner);

       }      

    }

   

    private Component createGap() {

        Component gap;

       if (gw == 0) {

           gap = Box.createHorizontalStrut(0);

       } else {

           if (commonBarStyle == PLAIN) {

               gap = new Gap(gw);

           } else {

               gap = Box.createHorizontalStrut(gw);

           }

       }

        return gap;

    }

 

    private class SolidCell extends JComponent {

       int cellWidth;

 

        SolidCell(int width) {

           super();

           this.cellWidth = width;

       }

 

        public Dimension getMinimumSize() {

           return new Dimension(cellWidth, height);

       }

 

        public Dimension getMaximumSize() {

           return new Dimension(cellWidth, height);

       }

 

        public Dimension getPreferredSize() {

           return new Dimension(cellWidth, height);

       }

    }

 

    class Gap extends SolidCell {

        public Gap(int width) {

           super(width);

       }

 

        public void paint(Graphics g) {

           super.paint(g);

           g.setColor(bkColor.darker());

           g.drawLine(0, 0, 0, height-1);

 

           g.setColor(bkColor.brighter().brighter());

           g.drawLine(1, 0, 1, height-1);

       }

    }

 

    final static int DEFAULT_CORNER_WIDTH = 18;

    /**

     * Do you take notice of that there is a manner of

     * status bar in many other programs, that you can drag

     * the right-bottom corner to resize the window? <br>

     * Okey, I just want to achieve it. I've spent many

     * more hours on it, but it isn't ideal yet.<br>

     * Be it so.

     *  

     * @author Jason

     */

    class RBCorner extends SolidCell {

        Rectangle resizeArea;

        public RBCorner() {

           super(DEFAULT_CORNER_WIDTH);         

           ResizeAdapter mouseAdapter =

               new ResizeAdapter();

          

           addMouseMotionListener(mouseAdapter);

           addMouseListener(mouseAdapter);

       }

      

       /**

        * this class in response to monitor several mouse

        * events, as response, it changes Cursor when mouse

        * over and leave it, and it can also resize the

        * window that it resides in when you drag it.

        *

        * @author Jason

        */

       class ResizeAdapter

        extends MouseInputAdapter{

           Cursor oldCursor;

           boolean entered;

           boolean holded;

           Point p;

          

           public void mouseDragged(MouseEvent e) {

               Point p1 = e.getPoint();

               window.setSize(

                   window.getWidth() + (p1.x - p.x),

                   window.getHeight() + (p1.y - p.y)

                  );

               p = p1;

           }

           public void mousePressed(MouseEvent e) {

               p = e.getPoint();

               holded = true;

           }

           public void mouseReleased(MouseEvent e) {

               p = null;

               holded = false;

               window.validate();

               window.repaint();

           }

           public void mouseEntered(MouseEvent e) {

               entered = true;

               oldCursor = getCursor();

               setCursor(

                   Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));            

           }

           public void mouseExited(MouseEvent e) {

               if (entered) {

                   setCursor(oldCursor);

                   entered = false;

               }            

           }          

       }

 

        public void paint(Graphics g) {

           super.paint(g);

            Rectangle r = g.getClipBounds();

           Color c = g.getColor();

 

           for (int i = 0; i < 3; i++) {

               g.setColor(Color.GRAY);

               g.drawLine(r.width - i * 4 - 4, r.height - 1, r.width - 1,

                      r.height - i * 4 - 4);

               g.drawLine(r.width - i * 4 - 5, r.height - 1, r.width - 1,

                      r.height - i * 4 - 5);

 

               g.setColor(Color.WHITE);

               g.drawLine(r.width - i * 4 - 6, r.height - 1, r.width - 1,

                      r.height - i * 4 - 6);

           }

           g.setColor(Color.LIGHT_GRAY);

           g.drawLine(r.width - 13, r.height - 1, r.width - 1, r.height - 1);

           g.drawLine(r.width - 1, r.height - 13, r.width - 1, r.height - 1);

       }

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
做方便实用的SWING控件! 欢迎大家测试并提交BUG报告. 由于个人能力和时间上的局限,希望有兴趣一起开发SWING控件的朋友,请与我联系.让我们一起努力! 为了方便查看,需要讨论的朋友请到另外一个置顶贴子. [讨论]关于"开源SWING控件" -------------------------------------------------------------------- 2004/03/25 首次发布 2004/04/08 把以前的组件和新做的组件合并到一个OpenSwing.jar文件中, 并初步将该组件库命名为”OpenSwing” 2004/06/17 加入了一个打印模板和一些新做的组件。 2004/07/25 加入了一个类似QQ界面的JGroupPane,修正了一些以前的组件的BUG. 对几乎所有的组件全部加入了JavaBeans处理, 使OpenSwing支持可视开发. 2005/04/17 将JNumberField最大长度,小数位长度修正成符合数据库定义的规范,如:NUMBER(10,2) 2005/04/21 修改了JNumberField的参数方式及不能输入负数的BUG,及数字验证方法 JDatePicker弹出时不能显示当前输入日期的BUG 加入了好多人在CJW论坛上贴子中想要的带关闭按钮的JCloseableTabbedPane可关闭的JTabbedPane的组件 2005/06/21 对JDatePicker加入了时分秒的输入 2006/01/20 修正了JPopupButton在XP风格下呈两个按钮样子的BUG 对JFontDialog进行了部分修改 2006/03/08 从JDatePicker提出来一个组件JCalendarPanel日期选择面板 并修改了JDatePicker的设计方式 2006/03/23 加入了韩文支持, 感谢在韩国工作的网友Sang Jian,韩文支持 OpenSwing_ko_KR.properties文件由他提供 2006/04/04 对JFileTree加入了文件过滤器建构式.并对显示进行了排序 -------------------------------------------------------------------- ■以下组件,均在j2sdk1.4.2_01+win2k环境下测试通过,继续欢迎大家测试并提交BUG报告. JCalendarPanel 日期选择面板, 从JDatePicker提出来的控件, 可以单独使用。 JCloseableTabbedPane 带关闭按钮/可设置菜单的JTabbedPane JDateField 日期输入框,输入正确格式的日期 JDatePicker 继承自JComboBox的日期选择框,保证输入正确格式的日期(yyyy-MM-dd) 履历: 2004/03/26 根据网友caiyj的建议引入了recoon写的关于JDateDocument的校验方法 2004/04/02 根据网友caiyj提交的BUG,修正了做为TableCellEditor时日期选择面板弹不出问题 JDirChooser 文件目录选择对话框 JFileTree 文件目录树 JFontDialog 字体对话框 JGroupPane 类似QQ界面的组群管理面板 JIpAddressField IP地址输入框,只能输入0~255数字的IP地址 JListChooser 列表选择对话框 JNumberField 数字输入框,可限制小数位数,数字最大长度,最大最小能输入的数字 JPopupButton 带下拉菜单的工具栏按钮 JStatusBar 模拟Windows的状态栏. JStringField 字符输入框,限制可输入的最大长度 JTreeComboBox 带有树形结构的下拉列表 com.sunking.swing.print.* 一个打印模板 -------------------------------------------------------------------- ■ OpenSwing的测试方法: 解压后是一个JBUILDER项目的目录结构,里面有一个test.bat文件和OpenSwing.jar(主库文件)/OpenSwingBeanInfo.jar(可视开发支持文件),直接执行test.bat进行测试。 ■ OpenSwing的发布: 只需要将OpenSwing.jar(主库文件)包含在CLASSPATH中即可。 OpenSwingBeanInfo.jar(可视开发支持文件)不需要发布, 仅提供可视化开发的支持 ■JBuilder上配置OpenSwing可视化开发组件 1.将OpenSwing.jar/ OpenSwingBeanInfo.jar文件复制到 %JBuilderX_HOME%\lib\ 目录下 2.打开JBuilderX 3.菜单Tools --> Configure Libraries…-->弹出Configure Libraries…对话框 ①New… --> Name中输入OpenSwing, Location中输入User Home -->OK ②选取对话框左边User Home下面出现的OpenSwing ③对话框右边Class和 Source页中分别做如下动作: Add…-->选择%JBuilder_HOME%\lib\OpenSwing.jar和OpenSwingBeanInfo.jar --> OK ④按OK关闭 Configure Libraries…对话框 4.菜单Tools--> Configure Palette… 弹出Palette Properties…对话框 ①Pages 页中按 Add… --> PageName中输入OpenSwing --> OK ②Add components页中 -->Select library…--> 选取User Home 下的OpenSwing类库-->OK ③Add components页中 -->在Component filtering块中选择 No filtering-->展开com.sunking.swing类包-->选择如下类: JGroupPanel,JStatusBar,JPopupButton,JDatePicker,JStringField,JNumberField,JFontDialog,JIpAddressField,JDateField (可按住Ctrl键复选)-->OK ④按OK关闭Palette Properties…对话框 5.配置成功标志: 随便打开一个JAVA文件,点下面的Design页,然后上面会出来一个设计工具条,诸如:Swing,Swing Containers…等,工具条的右上角有用来滚动工具栏的按钮,我们可以将其滚动到最末尾.如果看到有一个OpenSwing的页,并在它上面有几个可视组件的话,说明你已经配置成功了,开始你的OpenSwing可视开发之旅吧.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值