上机考试软件(二)
?????? 在这个实验性质的C/S模式机考软件项目中,我所负责的那部分模块的业务代码早已完成了(回顾一下我的任务:考试系统后台数据的管理,包括考场信息的生成,试卷的生成、批改),可一直缺少界面来实现这些功能。因为在我潜意识里,用Java写界面是件非常痛苦的事情~
?????? 可能是无意中听说了新的Netbeans非常强大,我打起勇气,花了周六、周日整整两天的时间搞了一下界面……
???????????? 我的环境:eclipse3.4JEE版(有hibernate插件)+NetBeans6.1。理论上只用netbeans应该够了,可我把原来eclipse下完成的业务程序完全打包成jar文件,当成库文件导入到netbeans里,让GUI代码调用——报hibernate的错,运行不起来。所以只能在netbeans里“拖”界面,在eclipse里调试。
????????????? 在实际的使用后发现,netbeans的拖界面功能果然很强大,布局控件很自由,虽然和VS比还有差距,但至少不再会像eclipse的GUI插件里那样,控件位置基本不受我“控制”,完全死板地按标准布局样式来布局~
?????? 我最终的GUI效果如下面的插图。

?

????????????? 将这个界面和我的业务代码结合起来整整花了两天半时间啊!果然非常痛苦~也怪我对swing的基础知识掌握不牢固,特别是对一些事件处理机制的理解不够深刻。比如textField控件的actionPerformed事件,在经历一段“挫折”后才发现,原来要在数据输入后按下回车键才能触发的(虽然表面上看不出有什么反应)。
????????????? 个人感觉这个界面最难搞的是那两棵树了,我要求的功能是:左边的树从数据库读取数据,可以分类以树节点的方式展开,来显示数据库中的试题;右边的树显示我选取的试题,也可以分类展开;点中间的“添加”按钮可以将左边选中的试题添加到右边的树里,点“取消”按钮可以取消添加指定的试题,点“取消全部”可以取消所有试题的添加。最折我寿的过程是将数据从左面添加到右边,总数报错(虽然最终还是搞定了)。
???????????? 以下是两棵树的关键代码:
/** * “添加”按钮的事件。 * * @param evt */private void buttonAddActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_buttonAddActionPerformed// TODO add your handling code here:// 获取右边树的TreeModel。DefaultTreeModel model = (DefaultTreeModel) this.jTree2.getModel();// 获取右边树的根节点。DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();if (leftTree != null) {// 获取节点(当前路径的最后一个节点)。DefaultMutableTreeNode tempNode = (DefaultMutableTreeNode) leftTree.getLastPathComponent();if (tempNode != null) {// 如果是改节点是具体的题目,它必定是第三层节点,即序号为2.if (tempNode.getLevel() == 2) {// 获取所选题目的父节点,以便判断是哪种题型。TreeNode parent = tempNode.getParent();// 如果添加过来的是单选题。if (parent.toString().equals(SINGLES_NODE)) {SinglesDao sd = new SinglesDao();Singles s = sd.findByNo(tempNode.toString());// 将新添加的Singles对象加入到ArrayList:paperSingles中,用来保存所有添加的单选题。this.paperSingles.add(s);// 获取“单项选择题”节点DefaultMutableTreeNode par = (DefaultMutableTreeNode) model.getChild(root, 0);// 将这个新节点加入右边树的“单项选择题”节点下面。model.insertNodeInto(tempNode, par, model.getChildCount(par));} else if (parent.toString().equals(MULTIS_NODE)) {MultisDao md = new MultisDao();Multis m = md.findByNo(tempNode.toString());this.paperMultis.add(m);DefaultMutableTreeNode par = (DefaultMutableTreeNode) model.getChild(root, 1);model.insertNodeInto(tempNode, par, model.getChildCount(par));} else if (parent.toString().equals(JUDGES_NODE)) {JudgesDao jd = new JudgesDao();Judges j = jd.findByNo(tempNode.toString());this.paperJudges.add(j);DefaultMutableTreeNode par = (DefaultMutableTreeNode) model.getChild(root, 2);model.insertNodeInto(tempNode, par, model.getChildCount(par));} else if (parent.toString().equals(QUESTIONS_NODE)) {QuestionsDao qd = new QuestionsDao();Questions q = qd.findByNo(tempNode.toString());this.paperQuestions.add(q);DefaultMutableTreeNode par = (DefaultMutableTreeNode) model.getChild(root, 3);model.insertNodeInto(tempNode, par, model.getChildCount(par));}}}}this.leftTrees = null;}// GEN-LAST:event_buttonAddActionPerformed?/** * 处理左边树的节点选中事件。 * * @param evt */private void jTree1ValueChanged(javax.swing.event.TreeSelectionEvent evt) {// GEN-FIRST:event_jTree1ValueChanged// TODO add your handling code here:// 获取最新的一个选中路径。TreePath tp = evt.getNewLeadSelectionPath();this.leftTree = tp;if (tp != null) {// 获取节点(当前路径的最后一个节点)。DefaultMutableTreeNode tempNode = (DefaultMutableTreeNode) tp.getLastPathComponent();// 如果选择的是根节点,文本框显示“请选择具体题型!”。if (tempNode.getLevel() == 0) {this.areaTitle.setText("请选择具体题型!");} // 如果选择的是分类节点,文本框显示"请选择具体题目!"。else if (tempNode.getLevel() == 1) {this.areaTitle.setText("请选择具体题目!");} // 否则显示具体的题目。else {// title 保存题目内容。String title = new String();// 获取所选题目的父节点,以便判断是哪种题型。TreeNode parent = tempNode.getParent();// 如果是“单项选择题”的子节点:if (parent.toString().equals(SINGLES_NODE)) {// 从数据库中获取指定编号的这道单选题(Singles为单选题的持久化类)。SinglesDao sd = new SinglesDao();Singles s = sd.findByNo(tempNode.toString());// 将题目的标题传给title。title = s.getTitle();}// 如果是“多项选择题”的子节点:else if (parent.toString().equals(MULTIS_NODE)) {MultisDao md = new MultisDao();Multis m = md.findByNo(tempNode.toString());title = m.getTitle();}// 如果是“判断题”的子节点:else if (parent.toString().equals(JUDGES_NODE)) {JudgesDao jd = new JudgesDao();Judges j = jd.findByNo(tempNode.toString());title = j.getTitle();}// 如果是“问答题”的子节点:else if (parent.toString().equals(QUESTIONS_NODE)) {QuestionsDao qd = new QuestionsDao();Questions q = qd.findByNo(tempNode.toString());title = q.getTitle();}// 在文本框中显示相应的内容。this.areaTitle.setText("" + tempNode + ":" + title);}}}// GEN-LAST:event_jTree1ValueChangedprivate void jTree2ValueChanged(javax.swing.event.TreeSelectionEvent evt) {// GEN-FIRST:event_jTree2ValueChanged// TODO add your handling code here:this.rightTree = evt.getNewLeadSelectionPath();}// GEN-LAST:event_jTree2ValueChanged? 1 楼 wptc 2010-01-03 我也是07级的, 感觉和你的差距很大啊,要多多学习老 2 楼 smartzxy 2010-01-03 wptc 写道我也是07级的, 感觉和你的差距很大啊,要多多学习老哈哈,过奖啦~