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

重拾JAVA之WinForm实战之(四)_第1张图片


重拾JAVA之WinForm实战之(四)_第2张图片

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

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

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()

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和主窗口都传过去了。其实可以只传个主窗口就可以的,至于为什么要传,一会说。

FrmCodeModify frmCodeModify = new FrmCodeModify(table,this);

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

重拾JAVA之WinForm实战之(四)_第3张图片

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

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

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

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中的数据。看一下代码,首先是初始化

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

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双击的行的行号。将值取出来放在修改界面上。然后刷新分页按钮状态,并给分页按钮注册统一事件处理程序。实现分页显示。最后修改数据,保存

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的。

public FrmCodeModify() {
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                ((FrmSysCodeMng)jf).BindTable();
            }
        });
        InitForm();
    }

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

重拾JAVA之WinForm实战之(四)_第4张图片

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

重拾JAVA之WinForm实战之(四)_第5张图片

设置JDBC的环境变量

重拾JAVA之WinForm实战之(四)_第6张图片

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

重拾JAVA之WinForm实战之(四)_第7张图片

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

重拾JAVA之WinForm实战之(四)_第8张图片

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

重拾JAVA之WinForm实战之(四)_第9张图片

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

重拾JAVA之WinForm实战之(四)_第10张图片

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