重拾JAVA之WinForm实战之(四)

简介:

今天这篇文章主要实现双击修改的功能,话说这java的winform程序实在是令人崩溃,各种问题搞得我神志不清。

170828503.png


164558682.png

那么这个功能就是双击Jtable中的某一行,然后弹出修改界面,修改完之后数据刷新到Jtable中。同时,这个修改界面还支持页码变化,即可以点击上一页,下一页等按钮抓取Jtable中对应行的数据。

先看双击事件,在C#中DataGridView有双击事件,可是JTable没有。怎么办呢?大家不知道看没看过我的另一篇文章,Silverlight MVVM切近实战主界面的双击实现,今天java这个双击和那个类似,原理就是监控两次单击在指定的时间段内完成的话算双击。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
TimerTask timTsk;
     Timer tim =  new  Timer();
     Boolean isTimerRuning =  true ;
     String ename=\"\";
     private  void  TimTaskInit() {
         timTsk =  new  TimerTask() {
             public  void  run() {
                 isTimerRuning =  false ;
             }
         };
         tim.schedule(timTsk,  200 200 );
     }
     private  void  ShowModifyForm()  throws  IllegalArgumentException,
             IllegalAccessException {
         if  (isTimerRuning) {
             isTimerRuning =  false ;
             FrmCodeModify frmCodeModify =  new  FrmCodeModify(table, this );
             frmCodeModify.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
             StartMain.SetMidScreen(frmCodeModify);
             frmCodeModify.setVisible( true );
         else  {
             TimerScheduleReset(timTsk);
             isTimerRuning =  true ;
             tim.schedule(timTsk,  200 200 );
         }
     }
     private  void  TimerScheduleReset(TimerTask timTsk) {
         Field field;
         try  {
             field = TimerTask. class .getDeclaredField(\"state\");
             field.setAccessible( true );
             try  {
                 field.set(timTsk,  0 );
             catch  (IllegalArgumentException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             catch  (IllegalAccessException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         catch  (NoSuchFieldException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         catch  (SecurityException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
     }

在Jtable单击的时候调用ShowModifyForm()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
table.addMouseListener( new  MouseAdapter() {
             @Override
             public  void  mouseClicked(MouseEvent e) {
                 try  {
                     if  (table.getSelectedRow() == - 1 ) {
                         MessageHelper.ShowMessage(\"请双击要修改的行!\");
                         return ;
                     }
                     ShowModifyForm();
                 catch  (IllegalArgumentException e1) {
                     // TODO Auto-generated catch block
                     e1.printStackTrace();
                 catch  (IllegalAccessException e1) {
                     // TODO Auto-generated catch block
                     e1.printStackTrace();
                 }
             }
         });

在调用弹出界的时候,首先定义一个timer,它的任务是200ms执行一次。每一次时间间隔之后都会将变量isTimerRuning设置为false。当单击第一次的时候,将其设置为true,当单击第二次的时候判断如果还是true,说明这两次单击是在200ms内完成的,从而模拟了双击事件。

OK,模拟玩双击事件之后,就是打开修改界面了。在这里我直接把Jtable和主窗口都传过去了。其实可以只传个主窗口就可以的,至于为什么要传,一会说。

1
FrmCodeModify frmCodeModify =  new  FrmCodeModify(table, this );

好了,界面打开之后,如下

165002813.png

我们发现比上篇文章多出了备注这个字段,所以加了个字段

1
String sql =  "SELECT 0 as bit,data,ename,cname,display_content,remark  FROM dbo.Codes WHERE ename='"

但是这个列并不用来显示在jtable中,所以隐藏它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CommonFunctions.hiddenColumn( 5 , table);
public  class  CommonFunctions {
     public  static  void  hiddenColumn( int  columnIndex,JTable table){
         TableColumnModel tcm=table.getColumnModel();
         TableColumn tc=tcm.getColumn(columnIndex);
         tc.setWidth( 0 );
         tc.setPreferredWidth( 0 );
         tc.setMaxWidth( 0 );
         tc.setMinWidth( 0 );
         table.getTableHeader().getColumnModel().getColumn(columnIndex)
               .setMaxWidth( 0 );
         table.getTableHeader().getColumnModel().getColumn(columnIndex)
              .setMinWidth( 0 );
     }
}

OK,我们可以通过上面的翻页来加载主页面jtable中的数据。看一下代码,首先是初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public  FrmCodeModify(JTable tb,JFrame jf) {
         InitForm();
         table = tb;
         this .jf=jf;
         Init();
     }
     /**
      * Create the frame.
      */
     public  FrmCodeModify() {
         addWindowListener( new  WindowAdapter() {
             @Override
             public  void  windowClosed(WindowEvent e) {
                 ((FrmSysCodeMng)jf).BindTable();
             }
         });
         InitForm();
     }

初始化的时候将传过来的jtable和jf附上值。然后调用Init()。再说这个Init之前,我想说的是,java 中为什么没有提供有参构造函数调用无参构造函数的方案。在C#中是通过有参:this()来实现的。好了,我们看一下Init

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
private  void  Init() {
         rowIndex = table.getSelectedRow();
         this .RowIndexChanged(rowIndex);
         this .RefreshPagerState();
         RegisterEventListener();
     }
     private  void  RefreshPagerState() {
         labFirst.setEnabled( true );
         labPrevious.setEnabled( true );
         labNext.setEnabled( true );
         labLast.setEnabled( true );
         if  (rowIndex ==  0 ) {
             labFirst.setEnabled( false );
             labPrevious.setEnabled( false );
         }
         if  (rowIndex == table.getRowCount() -  1 ) {
             labNext.setEnabled( false );
             labLast.setEnabled( false );
         }
     }
     private  void  RowIndexChanged( int  rowIndex) {
         String data = table.getValueAt(rowIndex,  1 ).toString();
         String ename = table.getValueAt(rowIndex,  2 ).toString();
         String cname = table.getValueAt(rowIndex,  3 ).toString();
         String display = table.getValueAt(rowIndex,  4 ).toString();
         String remark = table.getValueAt(rowIndex,  5 ).toString();
         this .txtDisplay.setText(display);
         this .labCName.setText(cname);
         this .labEname.setText(ename);
         this .labData.setText(data);
         this .txtRemark.setText(remark);
     }
     private  void  GetRowIndex(PagerType pt) {
         switch  (pt) {
         case  FIRST:
             rowIndex =  0 ;
             break ;
         case  PREVIOUS:
             rowIndex--;
             break ;
         case  NEXT:
             rowIndex++;
             break ;
         case  LAST:
             rowIndex = table.getRowCount() -  1 ;
             break ;
         }
     }
     private  void  RegisterEventListener() {
         JLabel[] labels =  new  JLabel[] { labFirst, labPrevious, labNext,
                 labLast };
         for  (JLabel lb : labels) {
             lb.addMouseListener( new  MouseAdapter() {
                 @Override
                 public  void  mouseClicked(MouseEvent e) {
                     PagerType pt;
                     String labName = ((JLabel)e.getComponent()).getName();
                     MessageHelper.ShowMessage(labName);
                     switch  (labName) {
                     case  "labFirst" :
                         pt = PagerType.FIRST;
                         break ;
                     case  "labPrevious" :
                         pt = PagerType.PREVIOUS;
                         break ;
                     case  "labNext" :
                         pt = PagerType.NEXT;
                         break ;
                     case  "labLast" :
                         pt = PagerType.LAST;
                         break ;
                     default :
                         pt = PagerType.FIRST;
                         break ;
                     }
                     GetRowIndex(pt);
                     RowIndexChanged(rowIndex);
                     RefreshPagerState();
                 }
             });
         }
     }
     enum  PagerType {
         FIRST, PREVIOUS, NEXT, LAST
     }

这一堆的代码就是用来实现初始化数据的,先获取父页面jtable双击的行的行号。将值取出来放在修改界面上。然后刷新分页按钮状态,并给分页按钮注册统一事件处理程序。实现分页显示。最后修改数据,保存

1
2
3
4
5
6
7
8
9
10
11
12
13
private  void  UpdateCodeInformation() {
         String display = txtDisplay.getText().trim();
         String remark = txtRemark.getText().trim();
         String ename = labEname.getText();
         String data = labData.getText();
                                                                                                                                                                                                
         String sql =  "Update TOP(1) dbo.Codes SET display_content='"  + display
                 "',remark='"  + remark +  "' WHERE ename='"  + ename
                 "' AND data='"  + data +  "'" ;
         JDBCSqlHelper.update(sql);
         MessageHelper.ShowMessage( "保存成功!" );
         this .dispose();
     }

那么最后在传递的这个this就是在修改页面关闭以后,刷新jtable的。

1
2
3
4
5
6
7
8
9
public  FrmCodeModify() {
         addWindowListener( new  WindowAdapter() {
             @Override
             public  void  windowClosed(WindowEvent e) {
                 ((FrmSysCodeMng)jf).BindTable();
             }
         });
         InitForm();
     }

好了洗洗睡吧,我靠,才中午,是吃饭才对,吃晚饭,话说这java一次编译,到处运行,在linux上来一下。先把生成的jar包导出到我的windows7的FTP服务文件夹中。在linux查看

195035507.png

好的,将GRLZ.JAR和JBDC4驱动拷贝至/opt/GRLZ/下

195156251.png

设置JDBC的环境变量

195302311.png

OK,现在运行起来,打开终端,输入如下命令,界面打开

195408655.png

可是我的密码怎么也输不进去

195521527.png

于是乎,我直接点击登录按钮,弹出提示

195618395.png

我靠自从弹出这个提示后,密码可以输入了,我靠,这个时候我最想问那些爱问别人原理的面试官,这是什么原理,为什么会这样。

195717926.png

直接报找不到JDBC驱动,老夫郁闷了,搞了大半天还没搞好,放弃吧,哪位高人如果进来了,给我指点一下。




本文转自 BruceAndLee 51CTO博客,原文链接:http://blog.51cto.com/leelei/1331230,如需转载请自行联系原作者


相关文章
|
12天前
|
存储 SQL 安全
Java 安全性编程:基本概念与实战指南
【4月更文挑战第27天】在当今的软件开发领域,安全性编程是一个至关重要的方面。Java,作为广泛使用的编程语言之一,提供了多种机制来保护应用免受常见的安全威胁。本博客将探讨 Java 安全性编程的基本概念,并通过实际示例来展示如何实现这些安全措施。
22 3
|
2天前
|
存储 监控 安全
JVM工作原理与实战(十六):运行时数据区-Java虚拟机栈
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了运行时数据区、Java虚拟机栈等内容。
|
3天前
|
Java
Java中的多线程编程:基础知识与实战技巧
【5月更文挑战第6天】多线程编程是Java中的一个重要特性,它允许我们在一个程序中同时执行多个任务。本文将介绍Java多线程的基础知识,包括线程的创建、启动、同步和通信,以及如何在Java中实现多线程编程。通过实例代码和解析,帮助读者深入理解Java多线程编程的概念和应用。
|
8天前
|
存储 Java 数据格式
Java实战:轻松掌握文件重命名与路径提取技巧
Java实战:轻松掌握文件重命名与路径提取技巧
15 0
|
9天前
|
设计模式 算法 安全
Java多线程编程实战:从入门到精通
【4月更文挑战第30天】本文介绍了Java多线程编程的基础,包括线程概念、创建线程(继承`Thread`或实现`Runnable`)、线程生命周期。还讨论了线程同步与锁(同步代码块、`ReentrantLock`)、线程间通信(等待/通知、并发集合)以及实战技巧,如使用线程池、线程安全设计模式和避免死锁。性能优化方面,建议减少锁粒度和使用非阻塞算法。理解这些概念和技术对于编写高效、可靠的多线程程序至关重要。
|
10天前
|
XML Java 测试技术
Java异常处理神器:Guava Throwables类概念与实战
【4月更文挑战第29天】在Java开发中,异常处理是保证程序稳定性和可靠性的关键。Google的Guava库提供了一个强大的工具类Throwables,用于简化和增强异常处理。本篇博客将探讨Throwables类的核心功能及其在实战中的应用。
26 2
|
10天前
|
安全 Java 测试技术
利用Java反射机制提高Spring Boot的代码质量:概念与实战
【4月更文挑战第29天】Java反射机制提供了一种强大的方法来在运行时检查或修改类和对象的行为。在Spring Boot应用中,合理利用反射可以提高代码的灵活性和可维护性。本篇博客将探讨Java反射的核心概念,并展示如何通过反射提高Spring Boot项目的代码质量。
28 0
|
10天前
|
存储 Java 大数据
JAVA:编程的艺术与实战解析
JAVA:编程的艺术与实战解析
19 2
|
12天前
|
监控 Java API
Java 模块化设计:概念与实战应用
【4月更文挑战第27天】模块化设计是现代软件开发的关键,它帮助开发者构建可管理、可维护的大型系统。Java 平台的模块化支持始于 Java 9,引入了一种全新的模块系统。
20 3
|
12天前
|
设计模式 算法 Java
Java 设计模式:探索策略模式的概念和实战应用
【4月更文挑战第27天】策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在 Java 中,策略模式通过定义一系列的算法,并将每一个算法封装起来,并使它们可以互换,这样算法的变化不会影响到使用算法的客户。
20 1