最近花了三天的时间写了我的第一个SWT的程序,由于是第一次,所有遇到了一些问题,总结在这里。
程序描述:程序运行后要在后台进行长时间的数据库操作,同时将一些状态信息及时显示在界面上。
开始的做法是直接写代码,界面代码和后台代码混杂在一起,后台边运行边更新界面信息,这样做的结果是,一旦程序运行了,界面就不能在有任何鼠标点击或者切换的操作系统的其它文件夹在回来,否则界面就死掉了。
其实,当SWT程序中有比较耗时的操作时,应该把耗时的操作抽取出来,启动一个线程去单独执行,再在这个线程中获取界面实例并修改其界面信息,在此,SWT提供了syncExec(Runnable)方法。
正确的做法用下面简单的代码事例表述:
注意:声明类变量private MainTransformer mainTransformer = new MainTransformer(this);//后台类的实例;
需要动态更新的组件要声明为类变量,并提供public的get方法;
注意:后台程序需要声明前台界面的实例 private ModelGenApp genApp;
需要构造函数
其它:
获取配置文件路径:File config = new File(new File("").getAbsoluteFile().getAbsolutePath()+"\\config\\jdbc.properties");
打包发布:
MANIFEST.MF写法:Main-Class大小写区分;其它不区分;每项之间需要一个空格分隔;Class-Path: ./lib/or....jar.(第三方jar包如果不和打包的程序在一个文件夹下,需要这种写法,且第三方jar包不能在程序jar包内部,否则程序找不到它们);
程序描述:程序运行后要在后台进行长时间的数据库操作,同时将一些状态信息及时显示在界面上。
开始的做法是直接写代码,界面代码和后台代码混杂在一起,后台边运行边更新界面信息,这样做的结果是,一旦程序运行了,界面就不能在有任何鼠标点击或者切换的操作系统的其它文件夹在回来,否则界面就死掉了。
其实,当SWT程序中有比较耗时的操作时,应该把耗时的操作抽取出来,启动一个线程去单独执行,再在这个线程中获取界面实例并修改其界面信息,在此,SWT提供了syncExec(Runnable)方法。
正确的做法用下面简单的代码事例表述:
用于控制界面部分的代码(ModelGenApp.java)
- startButton.addSelectionListener(new SelectionAdapter() {
- /*
- * 当按钮按下时,执行转换命令
- */
- public void widgetSelected(SelectionEvent e) {
- setButtonState(false);
- // 得到任务数,多线程使用变量要求为final类型
- final int taskCount = mainTransformer.initTotalRowNum("T_S_SCENEINFO");
- //设置进度条格数
- progressBar.setMaximum(taskCount-1);
- consoleText.append("["+new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())+"]转换程序开始启动...\r\n");
- //为后台任务新开一个线程
- new Thread() {
- public void run() {
- mainTransformer.start(taskCount);
- }
- }.start();
- consoleText.append("["+new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())+"]转换程序启动结束\r\n");
- }
- });
需要动态更新的组件要声明为类变量,并提供public的get方法;
后台程序代码(MainTransformer.java)
- /**
- * 开始执行
- */
- public void start(int taskCount) {
- ......//省去部分代码
- for(int i=1;i<=this.totalRowNum;i++) {
- ......//一些操作
- insertConsoleText("["+new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())+"]====转换第"+i+"条数据完成====\r\n");
- }
- ......//省去一些代码
- }
后台类动态更新前台界面的代码代码
- /**
- * 插入文本
- * @param str
- */
- private void insertConsoleText(final String str) {
- Display.getDefault().syncExec(new Runnable() {
- public void run() {
- genApp.getConsoleText().append(str);
- }
- });
- }
需要构造函数
后台类的构造函数代码
- /**
- * 构造函数,取得前台界面对象
- *
- */
- public MainTransformer(ModelGenApp genApp) {
- this.genApp = genApp;
- }
其它:
获取配置文件路径:File config = new File(new File("").getAbsoluteFile().getAbsolutePath()+"\\config\\jdbc.properties");
关闭窗口按钮的提示代码
- shell.addShellListener(new ShellAdapter(){
- //关闭窗口提示
- public void shellClosed(ShellEvent e) {
- if(!MessageDialog.openConfirm(shell, "关闭", "您真的要关闭窗口并退出程序吗?")) {
- e.doit=false;//doit is a flag indicating whether the operation should be allowed
- }
- }
- });
打包发布:
MANIFEST.MF写法:Main-Class大小写区分;其它不区分;每项之间需要一个空格分隔;Class-Path: ./lib/or....jar.(第三方jar包如果不和打包的程序在一个文件夹下,需要这种写法,且第三方jar包不能在程序jar包内部,否则程序找不到它们);