权记

一个关于我们生活点滴的网站,一个记录我们酸甜苦辣的日志。

Archive for the ‘技术’ Category

 

网上看到一篇很好的介绍Bridge模式的文章,分享给大家。

蜡笔与毛笔的故事:http://www.cnblogs.com/zhenyulu/articles/67016.html

蜡笔12种颜色,三类笔,共3×12=36

毛笔12种颜色,三类笔,共3+12=15

通过Bridge模式,我们把乘法运算3×12=36改为了加法运算3+12=15。

作者通过蜡笔盒毛笔的例子,通俗的介绍了Bridge模式的好处之一。

  • 0 Comments
  • Filed under: 技术
  • Drawing in code

    之前介绍了一个Swing做的原子钟的效果 “Swing Nixieclock(原子钟)效果”,作者放出了制作 Swing原子钟 制作的主要元素 – 原子钟的制造过程。

    想看制作过程的移步这里:

    Part One

    先通过绘图工具,绘出原型,绘制过程以及绘制时的参数,要在Swing中使用。

    Part Two

    将原型绘制过程中的一些数据,以Java Code 的形式在Swing中体现出来,步骤和通过绘图工具绘制时差不多,一步步来。

  • 0 Comments
  • Filed under: 技术
  • 在JavaEye上看的这个,转发一下,原文:http://www.javaeye.com/news/13151

    Gerrit 受到了这些设计的启发,尝试着使用Swing创造出了NixieClock(原子钟)效果。

    *首先,在Fireworks中创建了一个原型

    *第二步是建立一个JavaBean并将其转成Swing,这个步骤要花费很多时间

    *第三步是建立一个包含时钟逻辑的JFrame和6个nixie number的组件

    结果如下:

    下载NixieClock:http://www.jug-muenster.de/wp-content/uploads/2010/01/NixieClock.zip

  • 1 Comment
  • Filed under: 技术
  • 最近在Web项目开发过程中遇到的本地图片预览的需求,虽然最后因为其他原因没能使用,但是也算有些了解,整理出来。

    这里我们按浏览器分,主要包括IE6,IE7/8 和Firefox3, 不包含Opera,Safari和Chrome,这三个基本上需求很小,没有研究。

    总结一下就是:

    IE6下可以直接从file的value获取图片路径来显示预览。
    IE7和IE8下通过select获取file的图片路径,再用滤镜来显示预览。
    FireFox下调用file的getAsDataURL方法获取Data URI数据来显示预览。

    下面是一个完整的Demo:

    Tips:You can change the code before run.

  • 0 Comments
  • Filed under: 技术
  • 由于项目需要,需要进行图像剪裁,网上找到这个JQuery的插件,蛮好用的,记录一下。

    强烈建议使用前,先去官网看看Demo:http://deepliquid.com/projects/Jcrop/demos.php

    实现的流程大体如下:

    1. 通过JCrop获取剪辑框的位置x, y 和 剪辑框的大小 w , h。
    2. 将图片和剪辑框的四个参数传到服务器端,由服务器完成图片的剪辑工作。
    3. 保存剪辑好的图片。

    具体使用方法,看官网的手册,简单易懂:http://deepliquid.com/content/Jcrop_Manual.html

  • 0 Comments
  • Filed under: 技术
  • IE6下的错误提示:IEPNGFix: Children of positioned element are unclickable

    起因:由于PNG在IE6下的透明问题导致的

    为了解决透明问题,引入IEPNGFix, 具体介绍可看这里:http://www.twinhelix.com/css/iepngfix/demo/

    但是在Position为absolute的情况下,IE6 会出现:IEPNGFix: Children of positioned element are unclickable 错误。

    Search了下google,遇上此问题的网友不少,收集两种解决方案:

    1、需要使用 PNG 背景的元素是 #bg,在写结构的时候就让 #bg 不要成为其他任何元素的父元素。让本要在 #bg 里面的元素成为 #bg 的兄弟元素。然后再通过定位把兄弟元素覆盖到 #bg 上去。

    2、在原来用PNG背景的box外加个div,把定位的属性写到外层的div,里面的box不要有定位的属性。

  • 0 Comments
  • Filed under: 技术
  • 天发现了这个好玩的东西,让本来在Linux就不咋用QQ的我有重拾QQ的冲动,感觉很不错,分享给大家,先看图吧,借用LinuxToy的图片。

    webqq-message-400x84

    原文在这里:WebQQ 桌面化

    我简要表述下主要做法:

    1、安装allTray,版本0.69,最新版的貌似不行,还是安装0.69版的比较好。

    2、创建WebQQ的桌面应用,具体看WebQQ 桌面化的做法。

    3、按照WebQQ 桌面化的格式,编辑WebQQ的属性。

    4、注意,一定要注意,图标地址别用错了,一定是你自己的图标,不要直接拷贝过来使用,检查检查是否格式正确。

    allTray一直在用,但是没有发现其还有这么好用的命令,正如作者所说用 Alltray 创建系统托盘提示功能才是那篇文章的精华!

  • 0 Comments
  • Filed under: 技术
  • JTable Print

    几天在做关于JTable的打印工作,项目中客户需要直接将JTable打印出来,之前这方面工作做的比较少,经过这几天的研究,稍微有些积累,现在分享一下。

    JTable打印目前用的比较多的还是JasperReport来实现的,JasperReport开源免费,但是不是特别好用,这也是为什么JasperReport免费用,但是培训是收费的。

    不过常用的一些JTable的打印实现起来也还好了,只是复杂的稍微有些麻烦,可以看看我之前介绍的一篇入门文章:JasperReport 个人使用的一些经验

    这里主要分享的是通过Swing 打印的积累,JasperReport常用的简单的打印没问题,但是遇上比较复杂的表单,比如合成表头等,就稍微有点麻烦,当然也有可能是自己没有找到JasperReport的处理方法,要是有朋友知道欢迎分享下。

    通过Swing来绘制,应该是无奈的一步,不过通过这无奈的一步,和同事的帮助下,却学习到了不少这方面的知识,尤其是Swing绘制方面的。

    下面的代码是我抽出来的一个比较通用的,基于TableModel的表格打印,普通表头,不带合成表头的,如果Table Model不一样,那么自己就需要改改了。

    import java.awt.Font;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.print.PageFormat;
    import java.awt.print.Printable;
    import java.awt.print.PrinterException;
    import java.awt.print.PrinterJob;
    import java.math.BigDecimal;
    import java.text.NumberFormat;
    import javax.swing.JTable;
    import javax.swing.table.TableModel;
    
    /**
     *
     * @author xiaoquan
     */
    public class SwingCommonPrinitTools implements Printable {
    
        private TableModel model = null;
        private String info;
        private int totalRow = 0;
        private static final int LEFT = 0;
        private static final int RIGHT = 1;
        private static final int CENTER = 2;
        private static final int AUTO = 3;
    
        public void printTable(TableModel model,
                String info) {
            this.model = model;
            this.info = info;
            totalRow = model.getRowCount();
            PrinterJob printJob = PrinterJob.getPrinterJob();
            printJob.setPrintable(this);
            if (printJob.printDialog()) {
                try {
                    printJob.print();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
        private static final double paper_offset_x = 20;
        private static final double paper_offset_y = 20;
        private static final double title_time_margin = 10;
        private static final double time_body_margin = 2;
        private static final double cell_padding_y = 3;
        private static final double cell_padding_x = 2;
        private static final double body_btm_margin = 20;
        private static final double body_cell_height = 20;
        private static final Font title_font = new Font("黑体", Font.PLAIN, 18);
        private static final Font time_font = new Font("Dialog", Font.PLAIN, 10);
        private static final Font body_font = new Font("Dialog", Font.PLAIN, 10);
    
        @Override
        public int print(Graphics g, PageFormat pf, int pageIndex) throws
                PrinterException {
            //纸张宽
            double pageWidth = pf.getImageableWidth();
            //纸张高
            double pageHeight = pf.getImageableHeight();
            //打印的内容起始X
            double pageStartX = pf.getImageableX();
            //打印的内容起始Y
            double pageStartY = pf.getImageableY();
    
            //表头高
            double tableHeadH = 0;
            //Cell高
            double cellH = 0;
    
            //计算表头高度和单元格高度
            g.setFont(body_font);
            FontMetrics cellFm = g.getFontMetrics();
            cellH = cellFm.getHeight() + cell_padding_y * 2 + 1;
            tableHeadH = cellH * 2;
    
            //计算Title以及其位置
            String title = info;
            g.setFont(title_font);
            FontMetrics titleFm = g.getFontMetrics();
            int titleW = titleFm.stringWidth(title);
    
            //表底和表头文字属性
            g.setFont(time_font);
            FontMetrics btmFm = g.getFontMetrics();
            FontMetrics timeFm = g.getFontMetrics();
    
            //表格以上的Margin
            double tableTopMargin = paper_offset_y + titleFm.getHeight() +
                    title_time_margin + timeFm.getHeight() + time_body_margin;
    
            //表格每列的最大宽度
            double[] cellColMaxWidths = caculateTableCellWidth(model, cellFm);
    
            //当前Page的数据容量高度-不包括表头和表尾
            double currentPageDataCapacityHeight = pageHeight - tableTopMargin -
                    tableHeadH - btmFm.getHeight() - body_btm_margin - 1;
    
            //当前Page的数据容量
            int currentPageBodyCapacityRows = (int) (currentPageDataCapacityHeight /
                    cellH);
    
            //Y方向的分页数量
            int pagesY = 0;
            if (model.getRowCount() % currentPageBodyCapacityRows == 0) {
                pagesY = (int) (model.getRowCount() /
                        currentPageBodyCapacityRows);
            } else {
                pagesY = (int) (model.getRowCount() /
                        currentPageBodyCapacityRows) +
                        1;
            }
    
            //当前页数大于总页数时不打印
            if (pageIndex + 1 > pagesY) {
                return NO_SUCH_PAGE;
            }
    
            //绘制Title
            g.setFont(title_font);
            g.drawString(title, (int) (pageStartX +
                    (pageWidth - titleW) / 2), (int) (pageStartY +
                    paper_offset_y +
                    titleFm.getAscent()));
    
            //绘制区域移动到新的(0,0)点
            g.translate((int) (paper_offset_x + pageStartX), (int) (tableTopMargin +
                    pageStartY));
            int currentX = 0, currentY = 0;
    
            //绘制第一张表
    
            //绘制表头
            g.setFont(time_font);
            String time = "表头: " + info;
            g.drawString(time, currentX, currentY);
            currentY += 5;
            //绘制单一表头
            for (int i = 0; i < model.getColumnCount(); i++) {
                double width = cellColMaxWidths[i];
                double height = tableHeadH;
                String name = model.getColumnName(i);
                drawCell(g, name, currentX, currentY, (int) width,
                        (int) height, CENTER);
                currentX += width;
            }
    
            //绘制数据
            currentX = 0;
            currentY = (int) tableHeadH;
            //当前Page的数据容量
            int rightCellX = 0;
            int yIndex = pageIndex;
            int startRow = currentPageBodyCapacityRows * yIndex;
            int endRow = (currentPageBodyCapacityRows * (yIndex + 1)) >
                    totalRow
                    ? totalRow
                    : (currentPageBodyCapacityRows * (yIndex + 1));
            for (int row = startRow; row < endRow; row++) {
                //绘制单项表头下面的数据
                for (int i = 0; i < model.getColumnCount(); i++) {
                    double width = cellColMaxWidths[i];
                    double height = body_cell_height;
                    Object value = model.getValueAt(row, i);
                    drawCell(g, value, currentX, currentY, (int) width,
                            (int) height, AUTO);
                    currentX += width;
                    rightCellX = currentX;
                }
                currentX = 0;
                currentY += cellH;
            }
    
            //绘制闭合线,下面和右侧两条
            g.drawLine(currentX, currentY, rightCellX, currentY);
            g.drawLine(rightCellX, 5, rightCellX, currentY);
    
            drawBottomInfo(pageIndex, pagesY, currentY, g, (int) pageWidth);
            return PAGE_EXISTS;
        }
    
        private void drawBottomInfo(int pageIndex, int pagesY,
                int currentY, Graphics g, int pageWidth) {
            if (pageIndex + 1 == pagesY) {
                //绘制底部信息
                int btmX = 0;
                int btmY = currentY + 20;
                g.drawString("负责人:", btmX, btmY);
                g.drawString("制表:", pageWidth / 3, btmY);
                FontMetrics fm = g.getFontMetrics();
                int dataWidth = fm.stringWidth("日期: 2009/10/26");
                g.drawString("日期:", pageWidth - dataWidth, btmY);
            }
        }
    
        /**
         * 计算最大列宽
         * @param cellFm
         * @return
         */
        private double[] caculateTableCellWidth(
                TableModel model,
                FontMetrics cellFm) {
            //表格每列的最大宽度
            double[] cellColMaxWidths = new double[model.getColumnCount()];
    
            //计算表头每列最大宽度
            double[] headerColMaxWidths = new double[model.getColumnCount()];
    
            for (int i = 0; i < model.getColumnCount(); i++) {
                String name = model.getColumnName(i);
                headerColMaxWidths[i] = cellFm.stringWidth(name) + cell_padding_x *
                        2 + 1;
            }
            //没有数据时,表头每列的最大宽度就是表格每列的最大宽度
            cellColMaxWidths = headerColMaxWidths;
    
            //算数据每列的最大宽度和表头每列最大宽度对比
            for (int j = 0; j < model.getRowCount(); j++) {
                for (int i = 0; i < model.getColumnCount(); i++) {
                    //做些数据类型的判断
                    Object value = model.getValueAt(j, i);
                    if (value instanceof BigDecimal) {
                        value = ((BigDecimal) value).doubleValue();
                    }
                    String text = "";
                    if (value != null) {
                        text = value.toString();
                    }
                    double temp = cellFm.stringWidth(text) + cell_padding_x * 2 + 1;
                    if (cellColMaxWidths[i] < temp) {
                        cellColMaxWidths[i] = temp;
                    }
                }
            }
            return cellColMaxWidths;
        }
    
        /**
         * 绘制单元格及里面的文字
         * @param g
         * @param value
         * @param x
         * @param y
         * @param width
         * @param height
         */
        private static void drawCell(Graphics g, Object value, int x, int y,
                int width,
                int height, int locate) {
    
            g.drawLine(x, y, x + width - 1, y);
            g.drawLine(x, y, x, y + height - 1);
            FontMetrics fm = g.getFontMetrics();
            if (value == null) {
                value = "";
            }
            switch (locate) {
                case 0:
                    //居左
                    g.drawString(value.toString(), (int) (x + cell_padding_x), y +
                            (height - fm.getHeight()) / 2 + fm.getAscent());
                case 1:
                    //居右
                    g.drawString(value.toString(),
                            (int) (x +
                            (width - fm.stringWidth(value.toString()) + width -
                            fm.stringWidth(value.toString()) - cell_padding_x) /
                            2), y +
                            (height - fm.getHeight()) / 2 + fm.getAscent());
                case 2:
                    //居中
                    g.drawString(value.toString(), x + (width - fm.stringWidth(
                            value.toString())) / 2, y + (height -
                            fm.getHeight()) / 2 + fm.getAscent());
                case 3:
                    //自动判断
                    NumberFormat formatter = NumberFormat.getNumberInstance();
                    formatter.setMinimumFractionDigits(2);
                    formatter.setMaximumFractionDigits(2);
                    //根据数据类型左对齐还是右对齐绘制还是居中对齐
                    if (value instanceof BigDecimal) {
                        //居右
                        value = ((BigDecimal) value).doubleValue();
                        value = formatter.format(value);
                        g.drawString(value.toString(),
                                (int) (x +
                                (width - fm.stringWidth(value.toString()) + width -
                                fm.stringWidth(value.toString()) - cell_padding_x) /
                                2), y +
                                (height - fm.getHeight()) / 2 + fm.getAscent());
                    } else if (value instanceof Integer || value instanceof Long ||
                            value instanceof Double) {
                        //居右
                        g.drawString(value.toString(),
                                (int) (x +
                                (width - fm.stringWidth(value.toString()) + width -
                                fm.stringWidth(value.toString()) - cell_padding_x) /
                                2), y +
                                (height - fm.getHeight()) / 2 + fm.getAscent());
                    } else {
                        //居中
                        g.drawString(value.toString(), x + (width - fm.stringWidth(
                                value.toString())) / 2, y + (height -
                                fm.getHeight()) / 2 + fm.getAscent());
                    }
            }
        }
    
        public static void main(String[] args) {
            new SwingCommonPrinitTools().printTable(testData(), "测试");
        }
    
        private static TableModel testData() {
            final Object rows[][] = {
                {"one", "ichi - \u4E00", "Test1", "Test2", "Test3"},
                {"two", "ni - \u4E8C", "Test1", "Test2", "Test3"},
                {"three", "san - \u4E09", "Test1", "Test2", "Test3"},
                {"four", "shi - \u56DB", "Test1", "Test2", "Test3"},
                {"five", "go - \u4E94", "Test1", "Test2", "Test3"},
                {"six", "roku - \u516D", "Test1", "Test2", "Test3"},
                {"seven", "shichi - \u4E03", "Test1", "Test2", "Test3"},
                {"eight", "hachi - \u516B", "Test1", "Test2", "Test3"},
                {"nine", "kyu - \u4E5D", "Test1", "Test2", "Test3"},
                {"ten", "ju - \u5341", "Test1", "Test2", "Test3"},
                {"one", "ichi - \u4E00", "Test1", "Test2", "Test3"},
                {"two", "ni - \u4E8C", "Test1", "Test2", "Test3"},
                {"three", "san - \u4E09", "Test1", "Test2", "Test3"},
                {"four", "shi - \u56DB", "Test1", "Test2", "Test3"},
                {"five", "go - \u4E94", "Test1", "Test2", "Test3"},
                {"six", "roku - \u516D", "Test1", "Test2", "Test3"},
                {"seven", "shichi - \u4E03", "Test1", "Test2", "Test3"},
                {"eight", "hachi - \u516B", "Test1", "Test2", "Test3"},
                {"nine", "kyu - \u4E5D", "Test1", "Test2", "Test3"},
                {"ten", "ju - \u5341", "Test1", "Test2", "Test3"},
                {"one", "ichi - \u4E00", "Test1", "Test2", "Test3"},
                {"two", "ni - \u4E8C", "Test1", "Test2", "Test3"},
                {"three", "san - \u4E09", "Test1", "Test2", "Test3"},
                {"four", "shi - \u56DB", "Test1", "Test2", "Test3"},
                {"five", "go - \u4E94", "Test1", "Test2", "Test3"},
                {"six", "roku - \u516D", "Test1", "Test2", "Test3"},
                {"seven", "shichi - \u4E03", "Test1", "Test2", "Test3"},
                {"eight", "hachi - \u516B", "Test1", "Test2", "Test3"},
                {"nine", "kyu - \u4E5D", "Test1", "Test2", "Test3"},
                {"ten", "ju - \u5341", "Test1", "Test2", "Test3"},
                {"one", "ichi - \u4E00", "Test1", "Test2", "Test3"},
                {"two", "ni - \u4E8C", "Test1", "Test2", "Test3"},
                {"three", "san - \u4E09", "Test1", "Test2", "Test3"},
                {"four", "shi - \u56DB", "Test1", "Test2", "Test3"},
                {"five", "go - \u4E94", "Test1", "Test2", "Test3"},
                {"six", "roku - \u516D", "Test1", "Test2", "Test3"},
                {"seven", "shichi - \u4E03", "Test1", "Test2", "Test3"},
                {"eight", "hachi - \u516B", "Test1", "Tes12121t2", "Test3"},
                {"nine", "kyu - \u4E5D", "Test1", "Test2", "Test3"},
                {"ten", "ju - \u5341", "Test1", "Test2", "Test3"},
                {"one", "ichi - \u4E00", "Test1", "Test2", "Test3"},
                {"two", "ni - \u4E8C", "Test1", "Test2", "Test3"},
                {"three", "san - \u4E09", "Test1", "Test2", "Test3"},
                {"four", "shi - \u56DB", 12, "Test2", "Test3"},
                {"five", "go - \u4E94", 121212, "Test2", "Test3"},
                {"six", "roku - \u516D", 1212121212, "Test2", "Test3"},
                {"seven", "shichi - \u4E03", 12.01, "Test2", "Test3"},
                {"eight", "hachi - \u516B", 135.12, "Test2", "Test3"},
                {"nine", "kyu - \u4E5D", 93828.34, "Test2", "Test3"},
                {"ten", "ju - \u5341", "Test1", "Test2", "Test3"},
                {"one", "ichi - \u4E00", "Test1", "Test2", "Test3"},
                {"two", "ni - \u4E8C", "Test1", "Test2", "Test3"},
                {"three", "san - \u4E09", "Test1", "Test2", "Test3"},
                {"four", "shi - \u56DB", "Test1", "Test2", "Test3"},
                {"five", "go - \u4E94", "Test1", "Test2", "Test3"},
                {"six", "roku - \u516D", "Test1", "Test2", "Test3"},
                {"seven", "shichi - \u4E03", "Test1", "Test2", "Test3"},
                {"eight", "hachi - \u516B", "Test1", "Test2", "T1212121212est3"},
                {"nine", "kyu - \u4E5D", "Test1", "Test2", "Test3"},
                {"ten", "ju - \u5341", "Test1", "Test2", "Test3"},};
            final Object headers[] = {"English", "Japanese", "Column1", "Column2",
                "Column3"};
            JTable table = new JTable(rows, headers);
            return table.getModel();
        }
    }
    
  • 3 Comments
  • Filed under: 技术
  • 提是保证你的Linux已经安装了相应的Java软件,如果没有安装Java, 先装安装Java,配置Java环境, 假如安装到了/usr/java/jre1.6.0_17/

    找到你的FireFox安装的目录,假如安装到了 /usr/firefox

    cd /usr/firfox

    如果有plugins目录那就继续往下看,如果没有,mkdir plugins

    ln -s /usr/java/jre1.6.0_17/plugin/i386/ns7/libjavaplugin_oji.so

    OK,至此大功告成,测试一下,打开 http://www.java.com/zh_CN/download/installed.jsp 看看即可

    ubuntu下安装这个其实很方便,firefox会自动检测并让你安装,java plugin, 但是在有些Linux环境下就需要手动了。

  • 0 Comments
  • Filed under: 技术
  • 于“墙”的存在,有时候一些网站无法访问,于是购买了SSH服务,来通过SSH绕“墙”,每次开机都需要连接,很是麻烦,于是便找到了下面的方法。

    这个方法和之前的一篇文章:linux下 scp命令不需要输入用户密码 有点区别,那篇文章的前提是你需要能控制另一个Linux主机,但是如果你是购买的ssh服务,那么就不行了,下面给出一个方法,也是自己网上搜索的,目前用着很好,如果有更好的欢迎共享下。

    1、通过expect 来实现的,我自己用的Ubuntu,需要安装expect:sudo apt-get install expect

    2、autoSSH.sh 脚本

    #!/usr/bin/expect -f
    set timeout 30
    spawn ssh -D 7070 login_name@host_name
    expect "password:"
    send “123456\r”
    interact
    

    3、给脚本加权限, chmod +x autoSSH.sh

    OK,执行就可以了,也可以让直接开机运行这段脚本。

  • 0 Comments
  • Filed under: 技术
  •