• 用SWT可视化工具快速开发GUI应用


    一、开发背景介绍:

         1. 要开发什么工具?

        最近和公司里的几位同事凑钱买了个的士发票打印机(报销用,你懂的^_^),内容可自己写,比如金额,时间,路程等等。发票内容的输出位置和文字样式要跟真实发票的一样,否则容易穿帮(嘻嘻...)。但位置、样式要手工调,非常麻烦。所以如果有个工具能够帮助我们调好位置和文字样式的话,那就方便省事多了!!
        2. 为什么强调要快速开发?
        其实已经有个同事开发出这样的工具了,所以一开始我也没想过再造一个出来。但是当我好奇的问他用什么语言开发的时候,他来了句“你可以自己开发一个嘛!我用C#啊!”!我如果没理解错,这是向我宣战了。而我接受了这个挑战。那天是周五快下班的时候,我决定下周一给他看看我的版本!
        3.我为什么选择SWT,而不选择Swing?
        Swing有太深的Java UI的烙印--UI控件的风格过于简陋。既然要PK,起码外观上不能输。而SWT的好处是它会调用底层操作系统提供的UI控件,因此UI风格比较友好,用户觉得亲切熟悉。还有一个好处是可在Eclipse上进行SWT可视化开发,这能极大提高开发速度!就它了!
     
    终于说到正题了。
       二、准备工作
           1.Eclipse我用的是3.5 Galileo。
           2.可视化工具:WindowBuilder ,可通过Eclipse在线安装,这里不多说了,可google下。
           3.jar包转exe工具:Jsmooth。
     
      三、     实际开发
         1. 先看看成果
     
          
           
     
          

       2. 开发要点

          2.1读取Excel文件将内容显示到表格中
     
          核心代码如下:
          2.1.1 “导入”按钮的触发动作
     
    1. Button button_1 = new Button(shell, SWT.NONE); 
    2. button_1.addSelectionListener(new SelectionAdapter() { 
    3.       @Override 
    4.       public void widgetSelected(SelectionEvent selectionevent) { 
    5.                         String filePath = text.getText(); 
    6.                         showProgressDialog(filePath); 
    7.                   } 
    8.             }); 
            2.1.2 显示进度条
     
    1.     private void showProgressDialog(final String filePath) { 
    2.         try { 
    3.              final Display display = Display.getCurrent(); 
    4.              ProgressMonitorDialog progressDialog = new ProgressMonitorDialog(display.getActiveShell()); 
    5.              final List<String[]> contents = new ArrayList<String[]>(); 
    6.              IRunnableWithProgress progRunnable = new IRunnableWithProgress() { 
    7.  
    8.                 public void run(IProgressMonitor iprogressmonitor) 
    9.                         throws InvocationTargetException, InterruptedException { 
    10.                     int totalRow = 0; 
    11.                     try { 
    12.                     InputStream in = ExcelUtils.readExcelFile(filePath); 
    13.                     // IProgressMonitor 为监视器,可监控任务进度,此处设定任务总量为100个单位 
    14.                     iprogressmonitor.beginTask("努力为你读取文件,请稍候...", 100); 
    15.                      
    16.                     Sheet sheet = ExcelUtils.retreiveSheet(in, 0); 
    17.                     totalRow = sheet.getRows(); 
    18.                     int totalCol = sheet.getColumns(); 
    19.                     int rowStart = 0;  
    20.                     int rowEnd = 0; 
    21.                     int temp = totalRow / 10; 
    22.                     int segLength = temp > 0 ? temp : 1; 
    23.                     // 把任务人为的分成10端 
    24.                     for(int seg = 1; seg <= 10 && !iprogressmonitor.isCanceled(); seg++) { 
    25.                         rowStart = rowEnd; 
    26.                         rowEnd += segLength; 
    27.                         for(int row = rowStart; row < rowEnd; row++) { 
    28.                             List<String> rowContent = new ArrayList<String>(); 
    29.                             for(int c = 0; c < totalCol; c++) { 
    30.                                 Cell cell = sheet.getCell(c, row); 
    31.                                 rowContent.add(cell.getContents()); 
    32.                             } 
    33.                             contents.add(rowContent.toArray(new String[0])); 
    34.                         } 
    35.                         //每完成一段监视器增加10个单位 
    36.                         iprogressmonitor.worked(10); 
    37.                         iprogressmonitor.subTask("已完成"+seg*10+"%"); 
    38.                         if(rowEnd >= totalRow) { 
    39.                             break
    40.                         } 
    41.                     } 
    42.                     // 完成剩余的记录(如果有的话) 
    43.                     for(int k = rowEnd; k < totalRow; k++) { 
    44.                         List<String> rowContent = new ArrayList<String>(); 
    45.                         for(int c = 0; c < totalCol; c++) { 
    46.                             Cell cell = sheet.getCell(c, k); 
    47.                             rowContent.add(cell.getContents()); 
    48.                         } 
    49.                         contents.add(rowContent.toArray(new String[0])); 
    50.                     } 
    51.                     // 在非UI线程中更新UI,必须利用asyncExec 或者 syncExec  
    52.                     display.asyncExec(new Runnable() { 
    53.                         public void run() { 
    54.                             // 向表格控件添加数据 
    55.                             addTableItems(table,contents); 
    56.                         } 
    57.                     }); 
    58.                     iprogressmonitor.done(); 
    59.                       // 如果此时为用户取消的操作 
    60.                     if (iprogressmonitor.isCanceled()) { 
    61.                        throw new InterruptedException("用户已取消操作"); 
    62.                     } 
    63.                     }catch(Exception ex) { 
    64.                         ex.printStackTrace(); 
    65.                         showMessgeBox(shell,ex.getMessage()); 
    66.                     } 
    67. //                  showMessgeBox(shell,"已成功为你读取" + totalRow + "条记录."); 
    68.                 } 
    69.                   
    70.              }; 
    71.              progressDialog.run(truefalse, progRunnable); 
    72.         }catch(Exception ex) { 
    73.             ex.printStackTrace(); 
    74.         } 
    75.     } 
    76.      
    77.     private void addTableItems(Table table,List<String[]> contents) { 
    78.         for(String[] rowContents : contents) { 
    79.             TableItem tableItem = new TableItem(table, SWT.NONE); 
    80.             tableItem.setText(rowContents); 
    81.         } 
    82.     } 
     
     
     
         2.2 选中某一行数据后将数据格式化显示
            2.2.1效果如下:
         
     
           2.2.2 核心代码如下
     
    1. table.addListener(SWT.MouseUp, new Listener() { 
    2.  
    3.                   public void handleEvent(Event event) { 
    4.                         int sTextWidth = initStyledText(Integer.parseInt(combo.getItem(combo 
    5.                                     .getSelectionIndex())),Integer.parseInt(spinner_3.getText()), Integer.parseInt(spinner_1 
    6.                                     .getText())); 
    7.                         int charsNum = new Double(Math.ceil(sTextWidth/8.0)).intValue(); 
    8.                         int colCount = table.getColumnCount(); 
    9.                         TableItem[] selectedItems= table.getSelection(); 
    10.                         StringBuffer sb = new StringBuffer(); 
    11.                         int topLine = Integer.parseInt(spinner.getText()); 
    12.                         for(int line = 0; line < topLine; line++) { 
    13.                               sb.append(LINE_SEPARATOR); 
    14.                         } 
    15.                         for(int i = 0; i < selectedItems.length; i++) { 
    16.                               TableItem item = selectedItems[i]; 
    17.                               for(int j=0;j<colCount;j++) { 
    18.                                     String realText = item.getText(j); 
    19.                                     if(realText.length() < charsNum) { 
    20.                                           int spaces = charsNum - realText.getBytes().length; 
    21.                                           for(int k = 0;k < spaces;k++) { 
    22.                                                 sb.append(" "); 
    23.                                           } 
    24.                                     } 
    25.                                     sb.append(item.getText(j)).append(LINE_SEPARATOR); 
    26.                               } 
    27.                         } 
    28.                         styledText.setText(sb.toString()); 
    29.                   } 
    30.                    
    31.             }); 
    32.       } 
    33.  
    34.      /** 
    35.        * 文本样式,如字体大小,行距,对齐等用StyledText来控制。 
    36.       * @param fontSize 字体大小 
    37.       * @param rightMove      右移位数 
    38.       * @param lineSpacing 行距 
    39.       * @return 
    40.       * @version: v1.0.0 
    41.       * @author: <a href="mailto:flysqrlboy@gmail.com">flysqrlboy</a> 
    42.       * @date: 2013-1-27 
    43.        */ 
    44.       private int initStyledText(int fontSize,int rightMove,int lineSpacing) { 
    45.             styleTextFont = SWTResourceManager.getFont("宋体", fontSize, SWT.NORMAL); 
    46.             styledText.setFont(styleTextFont); 
    47.             styledText.setAlignment(SWT.LEFT); 
    48.             styledText.setJustify(true); 
    49.             styledText.setLineSpacing(lineSpacing); 
    50.             return styledTextSrcWidth + rightMove * 8
    51.       } 
     
      四、jar包转成Exe执行文件
        打成Exe可执行文件的目的是双击即可运行,当然运行目前这个版本的exe文件要求用户的电脑中要有Java 运行时环境(JRE)。如果要在没有JRE的电脑中运行,则在转exe时把jre包一起打进exe文件中即可。 
        1.打jar包
        这里要注意的是,我们的目标是双击exe即可运行,无需依赖外部的资源,所以打jar包时要把所有依赖的jar都打进一个jar里。
         如下图操作:
     

           

           

         2. 用Jsmooth转成EXE
         
         这里只说Application的配置,如下图:
     

        由于invoice.jar已经是可运行的jar(双击运行),所以上图中的Classpath无需任何设置,即不必依赖外部资源。

     
        至此,工具开发完成。周末两天去除生活上一些杂七杂八的琐事,开发时间应该在18小时内。
    工具本身很轻巧没什么难度,不过把一个想法鼓捣出来的过程还是挺爽的!
     
     

    本文出自 “鼯鼠男孩” 博客,请务必保留此出处http://flysqrlboy.blog.51cto.com/5027074/1129782

  • 相关阅读:
    NLP 中的embedding layer
    Java Web -- Servlet(5) 开发Servlet的三种方法、配置Servlet具体解释、Servlet的生命周期(2)
    我对REST的理解
    QML 与 C++ 交互之工厂方法
    Hive分析窗体函数之LAG,LEAD,FIRST_VALUE和LAST_VALUE
    【C/C++】:用C实现输出日期的阴历日子
    Android6.0执行时权限解析,RxPermissions的使用,自己封装一套权限框架
    统计报表
    2015 HDU 多校联赛 5363 Key Set
    查看sedna创建的数据库和集合,文档之类
  • 原文地址:https://www.cnblogs.com/xhqgogogo/p/3371894.html
Copyright © 2020-2023  润新知