您的位置:首页 > 编程语言 > Java开发

JAVA的图形用户界面练习——万年历的制作

2017-01-10 21:41 176 查看


这学期学了java,里面的图形用户界面方面的内容学习时,由于之前接触过Flash的AS3.0语言,对组件、监听、事件等上手比较快,在这一方面两者较为类似,需要多注意的是布局的学习应用。最后的结果是做了一个万年历,结果图如下:
                                                               


看似简单的界面还是有不少深坑的。

这个万年历采用复杂网格布局(GridBagLayout),主要分为三个部分:

1.初始化方法。要实现第一次进入万年历时默认显示2017年1月,随后调用时部分组件不用重复布局(后面会讲为什么要调用初始化方法)。

2.响应事件。这个小程序一共安放了4个监听,分别加在“上月”、“下月”和两个年月值文本框(回车触发事件,用ActionEvent,非ItemEvent)。

3.星期的计算函数。获取年月值后,计算当月1号是星期几。

其中第三部分最容易理解,只要足够仔细,用getText获得年月值后,计算该年该月1号距离公元1 年1月1号(星期一)有多少天,对7取余不难得出结果。重点在于前两部分的设计和调试。

为了叙述方便,在下文中我把每次翻月会改变的部分命名为A区域,即图中的日期值阿拉伯数字部分。

显然,对于这个万年历,触发监听事件后需要更改的组件都是在A区域内,每次翻页只需要改变A区域即可。

所以得出了一个很自然的设想:触发事件监听时,remove出所有日期值,再依次放入新的月份值的各个日期。即:

监听翻页——>setText方法改变文本框的年月值——>remove掉A区域的组件——>获取年月值,自定义方法得到该月1号是星期几——>将“1”放到对应位置,后续依次排列

因为初始化方法init()只写一个比较好,我尝试过在上述第五步的时候用新的初始化方法init_2(),但一没必要,二容易出错。只需要在一开始定义一个flag=0,完成初始的全部布局后flag=1,再加上合适的判断语句不难做到第五步调用初始化方法时只执行部分语句。

在此先注意到remove(int index)方法,该方法需要一个参数,为组件的序号,组件序好取决于其放入的先后,如第3个放入的组件的序号是3,remove某一个组件后,序号在其后的组件的序号都会前移。所以在该程序中,只需要不断执行remove()若干次即可(得保证日期数字是最后放入的组件)。

随后完成初步调试后发现,上述步骤都能执行,但是点击翻页后,remove成功了,但新加入的组件未显示,但加入检测语句却发现初始化方法是正常调用的。到这里我认为是重新调用add语句将组件放入这种语句不正确。直到我偶然中拖动了一下边框改变了程序框的大小,发现这时新加入的A区域能正常显示了,但A区域外的组件变回了默认的边界布局(A区域仍然是复杂网格布局),备份问价在我完成后删了,所以具体的错误界面请各位脑补吧= =、。

由此引出了本次万年历设计过程中最大的两个问题:

1.为什么新加入组件需要拖动改变外框大小才能得以显示?

2.为什么调用一次初始化方法后,没对A区域外的组件干什么,但它们的原有布局会被破坏?

对于上述两个问题,我在查阅相关资料,问了一些同学之后找到了解决办法。

首先对于问题1:在完成组件的更换之后,Java要求界面得更新一下才能显示新的组件,我一开始使用的是repaint方法,但实际上这里要用的是validata方法。在监听方法调用初始化方法后加一句validata()就能解决这个问题。

至于问题2,则是一开始的布局方法使用就有问题。我采用的是复杂网格布局,依次创建GridBagLayout和GridBagConstraints的类对象,并设置相关参数后,我原先是直接使用add(XX);这样的确可以放入,我查阅的书籍上样例也是如此,但这样会导致上文所说的错误。因为书籍的该部分讲的是复杂网格布局的应用样例,所以对于万年历这样的具体项目需要多想一层。解决办法也很简单,新建一个Panel:panel,将所有的组件放到panel内而不是直接进行布局,后面语句也应该用panel.add();这样一来,所有的组件均在panel内布局,此时A区域外的组件在重新调用初始化方法后布局不会被破坏,问题解决。

新的布局方法片段:

GridBagLayout cal = new GridBagLayout();
GridBagConstraints cals = new GridBagConstraints();
setLayout(cal);
panel.setLayout(cal);
add(panel);
//“上月”按钮
cals.gridx = 1;
cals.gridy = 1;
cals.gridwidth = 2;
cals.gridheight = 7;
cal.setConstraints(last,cals);
panel.add(last,cals);
last.addActionListener(this);
回看整个项目,其实主要问题就是这两个,一味的模仿书上的样例而不具体结合需求进行编写的话,迟早会遇到问题。而且在分析问题解决问题中学到的才是真正的本领。上面两点对于我们来说尤为重要。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 布局