概述
Lab3要求实现一个显示计划项信息的表格,以航班应用为例,需要实现Board所在时间一小时以内的起飞航班和抵达航班,以两个表格的形式显示。在这里,我以这个功能为例,浅述JSwing和GridBagLayout布局的应用。
Board的设计简述
首先,对于如前所述的一个Board应用,只设计一个类太过臃肿反复,考虑到将数据和表现分离,我们设计两个类,一个类(flightBoard)用于处理数据,具象化为将传入的一组航班提取出Board所在时间一小时以内的起飞航班和抵达航班即应当在Board中显示的航班;另一个类(FlightBoardGUI)用于将数据表现在GUI界面上,实现各种布局等。
//flightBoard类
private Location currentLocation;//Board的位置
private LocalDateTime currentTime;//Board的时间
private final List<FlightEntry> arrival = new ArrayList<>();//抵达航班
private final List<FlightEntry> departure = new ArrayList<>();//起飞航班
private FlightBoardGUI fbGUI;//图形界面
flightBoard类根据currentLocation和currentTime将应当显示的航班从arrival和departure中筛选出来,将筛选出来的数据传递给内部delegete的图形界面fbGUI,fbGUI再将数据表现出来。
Board的GUI界面JSwing实现
要实现GUI界面首先要了解JSwing的GUI界面结构,这里以继承了JFrame的FlightBoardGUI为例,其大体可以分为三层:
- 外部框架—JFrame
- 中间容器—JPanel
- 具体组件—JTable
我将其比喻为烤披萨的过程,JFrame相当于烤盘、烤架,JTable相当于待烤的披萨饼,披萨饼自然不能直接放在烤架、烤盘上,需要另外的披萨盘用于将披萨定型和使披萨受热更加均匀,这个披萨盘就是JPanel。当然,一次只烤一个小披萨对于一个大烤盘可能过于浪费,烤盘上多余的空间可以用来放其他的东西,比如蛋挞、蛋糕等,至于如何摆放更加美观或更省空间,这就是具体的布局了。
private GridBagLayout gridBag = new GridBagLayout();
private JPanel container = new JPanel(gridBag);
private JScrollPane arrivalPanel;
private JScrollPane departurePanel;
private JTable arrivalTable;
private JTable departureTable;
private JLabel arrivalLabel = new JLabel("抵达航班");
private JLabel departureLabel = new JLabel("出发航班");
在这里,我考虑使用GridBagLayout布局,用一个JPanel类型的container替换原有的JFame默认的JPanel,相当于将烤盘上换了一层锡纸,这个锡纸上的食品要求按照GridBagLayout的布局摆放,两个披萨饼—arrivalTable和departureTable放在两个披萨盘上—arrivalPanel和departurePanel,它们是JScrollPane类型的,表示带滚动条的,可以水平和垂直滚动的面板容器。另外的两个JLabel,可以直接放在锡纸—container上,也可以为它们新建两个容器,将容器放在container上,即隔着锡纸加热,在这里我选择的是前者。
具体的将组件放置在容器上的动作以及GridBagLayout布局的介绍见下一节。
FlightBoardGUI的GridLayout布局
布局的方式有很多,比如FlowLaout,GridLayout,BorderLayout以及我使用的GridBagLayout等等。
这当中GridLayout和GridBagLayout名字很像,前者将容器分成大小相等的单元格,比较死板,后者则给开发者更多的改变空间,更加灵活。我开始也尝试过使用GridLayout布局,但作为JLabel其和表格占据空间大小相同,不够美观,遂弃用。
public void visualize() {
this.arrivalData = this.getArrivalData();
this.departureData = this.getDepartureData();
this.arrivalTable = new JTable(arrivalData, columnName);
this.departureTable = new JTable(departureData, columnName);
this.arrivalPanel = new JScrollPane(arrivalTable);
this.departurePanel = new JScrollPane(departureTable);
GridBagConstraints c = new GridBagConstraints();
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
gridBag.addLayoutComponent(arrivalLabel, c);
gridBag.addLayoutComponent(arrivalPanel, c);
gridBag.addLayoutComponent(departureLabel, c);
gridBag.addLayoutComponent(departurePanel, c);
this.container.add(arrivalLabel);
this.container.add(arrivalPanel);
this.container.add(departureLabel);
this.container.add(departurePanel);
this.setContentPane(container);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
FlightBoardGUI的可视化visualize()方法如上所示,结合GridBagLayout布局及JSwing我将给与解释。
this.arrivalTable = new JTable(arrivalData, columnName);
this.departureTable = new JTable(departureData, columnName);
首先是两个JTable的初始化,对于arrivalTable的new JTable的两个参数,后者是String[]类型的变量,表示表头信息,前者是String[][]类型的变量,是表格单元格中的具体内容,列数要与表头元素个数保持一致。
this.arrivalPanel = new JScrollPane(arrivalTable);
this.departurePanel = new JScrollPane(departureTable);
然后将两个JTable表格放置在各自的中间容器上。
GridBagConstraints c = new GridBagConstraints();
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
这一步就与布局密切相关了,GridBagConstraints类的对象c描述了每个组件的位置与占用单元格的大小。我希望我的Board窗口以标签-表格-标签-表格的形式排成一列,每一列按照内容调整大小,可以随窗口大小的变化而改变大小。
c.gridwidth所设定的是组件显示区域在水平方向占用单元格的个数,默认为1,更改为REMAINDER后,会占满当前行剩余的单元格,并使单元格另起一行,即,使当前的组件独占一行,下一个组件如果加入,会被加入到下面一行。这样一来四个组件会纵向排列,否则会横向占满一行。
c.fill设定的是组件在显示区域中的填充方式,默认为NONE,即不调整,调整为BOTH后可以是组件完全填满显示区域。这样以来组件才会填满整个显示区域。
c.weightx和c.weighty设定的是显示区域在容器中分配的额外空间,当指定行/列中的其中任意一个 组件的权重(大于0),则该行/列将(和其他行/列按权重比例)分配额外的水平/竖直空间。这样以来显示区域才会填满容器,这与上一条语句共同保证了窗口内的表格、标签随窗口大小而变化。
gridBag.addLayoutComponent(arrivalLabel, c);
gridBag.addLayoutComponent(arrivalPanel, c);
gridBag.addLayoutComponent(departureLabel, c);
gridBag.addLayoutComponent(departurePanel, c);
这几行语句则将之前设定的GridBagConstraints约束应用于各个组件之上。
this.container.add(arrivalLabel);
this.container.add(arrivalPanel);
this.container.add(departureLabel);
this.container.add(departurePanel);
然后将这些组件—披萨饼放置到container—烤盘JFrame的锡纸上。
this.setContentPane(container);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
这四条语句分别对应:
- 将container设定为JFrame上最底层的容器—烤盘上放好锡纸;
- 将窗口调整到刚好为组件原始大小的状态;
- 将窗口位置设定为屏幕中心;
- 显示GUI界面。
窗口显示如下:
最后
以上就是听话大树为你收集整理的Board界面JSwing实现及GridBagLayout布局Board的设计简述Board的GUI界面JSwing实现FlightBoardGUI的GridLayout布局的全部内容,希望文章能够帮你解决Board界面JSwing实现及GridBagLayout布局Board的设计简述Board的GUI界面JSwing实现FlightBoardGUI的GridLayout布局所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复