50.java编程思想——创建窗口和程序片 布局控制

50.java编程思想——创建窗口和程序片 布局控制

在Java 里该方法是安一个组件到一个窗体中去,它不同我们使用过的其它GUI 系统。首先,它是全代码的;没有控制安放组件的“资源”。其次,该方法的组件被安放到一个被“布局管理器”控制的窗体中,由“布局管理器”根据我们add()它们的决定来安放组件。大小,形状,组件位置与其它系统的布局管理器显著的不同。另外,布局管理器使我们的程序片或应用程序适合窗口的大小,所以,如果窗口的尺寸改变(例如,在HTML 页面的程序片指定的规格),组件的大小,形状和位置都会改变。

程序片和帧类都是来源于包含和显示组件的容器。(这个容器也是一个组件,所以它也能响应事件。)在容器中,调用setLayout()方法允许我选择不同的布局管理器。

1     F l o w L a y o u t

到目前为止,所有的程序片都被建立,看起来使用一些不可思议的内部逻辑来布置它们的组件。那是因为程序使用一个默认的方式:FlowLayout。这个简单的“Flow”的组件安装在窗体中,从左到右,直到顶部的空格全部再移去一行,并继续循环这些组件。

这里有一个例子明确地(当然也是多余地)设置一个程序片的布局管理器去FlowLayout,然后在窗体中安放按钮。我们将注意到FlowLayout 组件使用它们本来的大小。例如一个按钮将会变得和它的字串符一样的大小。

1.1     代码

import java.awt.*;

import java.applet.*;

public class FlowLayout1 extends Applet {

    public voidinit() {

        setLayout(new FlowLayout());

        for (int i = 0; i < 20; i++)

            add(new Button("Button " + i));

    }

} /// :~

所有组件将在FlowLayout 中被压缩为它们的最小尺寸,所以我们可能会得到一些奇怪的状态。例如,一个标签会合适它自已的字符串的尺寸,所以它会右对齐产生一个不变的显示。

2     B o r d e r L a y o u t

布局管理器有四边和中间区域的概念。当我们增加一些事物到使用BorderLayout 的面板上时我们必须使用add()方法将一个字符串对象作为它的第一个自变量,并且字符串必须指定(正确的大写)“North”(上),“South”(下),“west”(左),“East”(右)或者“Center”。    如果我们拼写错误或没有大写,就会得到一个编译时的错误,并且程序片不会像你所期望的那样运行。幸运的是,我们会很快发现在Java 1.1 中有了更多改进。

简单的程序例子。

2.1     代码

import java.awt.*;

import java.applet.*;

public class BorderLayout1 extends Applet {

    public voidinit() {

        int i = 0;

        setLayout(new BorderLayout());

        add("North", new Button("Button "+ i++));

        add("South", new Button("Button "+ i++));

        add("East", new Button("Button "+ i++));

        add("West", new Button("Button "+ i++));

        add("Center", new Button("Button "+ i++));

    }

} /// :~

2.2     执行

除了“Center”的每一个位置,当元素在其它空间内扩大到最大时,我们会把它压缩到适合空间的最小尺寸。但是,“Center”扩大后只会占据中心位置。BorderLayout 是应用程序和对话框的默认布局管理器。

3     G r i d L a y o u t

GridLayout 允许我们建立一个组件表。添加那些组件时,它们会按从左到右、从上到下的顺序在网格中排列。在构建器里,需要指定自己希望的行、列数,它们将按正比例展开。

3.1     代码

import java.awt.*;

import java.applet.*;

public class GridLayout1 extends Applet {

    public voidinit() {

        setLayout(new GridLayout(7, 3));

        for (int i = 0; i < 20; i++)

            add(new Button("Button " + i));

    }

} /// :~

3.2     执行

在这个例子里共有21 个空位,但却只有20 个按钮,最后的一个位置作留空处理;注意对GridLayout 来说,并不存在什么“均衡”处理。

4     C a r d L a y o u t

CardLayout 允许我们在更复杂的拥有真正的文件夹卡片与一条边相遇的环境里创建大致相同于“卡片式对话框”的布局,我们必须压下一个卡片使不同的对话框带到前面来。在AWT 里不是这样的:CardLayout 是简单的空的空格,我们可以自由地把新卡片带到前面来。(JFC/Swing 库包括卡片式的窗格看起来非常的棒,且可以我们处理所有的细节。)

4.1     联合布局(Combininglayouts)

下面的例子联合了更多的布局类型,在最初只有一个布局管理器被程序片或应用程序操作看起来相当的困难。这是事实,但如果我们创建更多的面板对象,每个面板都能拥有一个布局管理器,并且像被集成到程序片或应用程序中一样使用程序片或应用程序的布局管理器。这就象下面程序中的一样给了我们更多的灵活性:

4.1.1       代码

import java.awt.*;

import java.applet.Applet;

class ButtonPanel extends Panel {

    ButtonPanel(String id) {

        setLayout(new BorderLayout());

        add("Center", new Button(id));

    }

}

public class CardLayout1 extends Applet {

    Button first = new Button("First"), second = new Button("Second"),third= newButton("Third");

    Panel cards = new Panel();

    CardLayout cl = new CardLayout();

    public voidinit() {

        setLayout(new BorderLayout());

        Panel p = new Panel();

        p.setLayout(new FlowLayout());

        p.add(first);

        p.add(second);

        p.add(third);

        add("North", p);

        cards.setLayout(cl);

        cards.add("First card", new ButtonPanel("The first one"));

        cards.add("Second card", new ButtonPanel("The second one"));

        cards.add("Third card", new ButtonPanel("The third one"));

        add("Center", cards);

    }

    public booleanaction(Event evt,Object arg){

        if (evt.target.equals(first)) {

            cl.first(cards);

        } else if (evt.target.equals(second)) {

            cl.first(cards);

            cl.next(cards);

        } else if (evt.target.equals(third)) {

            cl.last(cards);

        } else

            return super.action(evt, arg);

        return true;

    }

} /// :~

4.1.2       执行

这个例子首先会创建一种新类型的面板:BottonPanel(按钮面板)。它包括一个单独的按钮,安放在BorderLayout的中央,那意味着它将充满整个的面板。按钮上的标签将让我们知道我们在CardLayout 上的那个面板上。

在程序片里,面板卡片上将存放卡片和布局管理器CL 因为CardLayout 必须组成类,因为当我们需要处理卡片时我们需要访问这些句柄。

这个程序片变成使用BorderLayout 来取代它的默认FlowLayout,创建面板来容纳三个按钮(使用FlowLayout),并且这个面板安置在程序片末尾的“North”。卡片面板增加到程序片的“Center”里,有效地占据面板的其余地方。

当我们增加BottonPanels(或者任何其它我们想要的组件)到卡片面板时,add()方法的第一个自变量不是“North”,“South”等等。相反的是,它是一个描述卡片的字符串。如果我们想轻击那张卡片使用字符串,我们就可以使用,虽然这字符串不会显示在卡片的任何地方。使用的方法不是使用action();代之使用first()、next()和last()等方法。请查看我们有关其它方法的文件。

在Java 中,使用的一些卡片式面板结构十分的重要,因为(我们将在后面看到)在程序片编程中使用的弹出式对话框是十分令人沮丧的。对于Java 1.0 版的程序片而言,CardLayout 是唯一有效的取得很多不同的“弹出式”的窗体。

4.2     G r i d B a g L a y o u t

很早以前,人们相信所有的恒星、行星、太阳及月亮都围绕地球公转。这是直观的观察。但后来天文学家变得更加的精明,他们开始跟踪个别星体的移动,它们中的一些似乎有时在轨道上缓慢运行。因为天文学家知道所有的天体都围绕地球公转,天文学家花费了大量的时间来讨论相关的方程式和理论去解释天体对象的运行。当我们试图用GridBagLayout 来工作时,我们可以想像自己为一个早期的天文学家。基础的条例是(公告:有趣的是设计者居然在太阳上(这可能是在天体图中标错了位置所致,译者注))所有的天体都将遵守规则来运行。哥白尼日新说(又一次不顾嘲讽,发现太阳系内的所有的行星围绕太阳公转。)是使用网络图来判断布局,这种方法使得程序员的工作变得简单。直到这些增加到Java 里,我们忍耐(持续的冷嘲热讽)西班牙的GridBagLayout 和GridBagConstraints 狂热宗教。我们建议废止GridBagLayout 。取代它的是,使用其它的布局管理器和特殊的在单个程序里联合几个面板使用不同的布局管理器的技术。我们的程序片看起来不会有什么不同;至少不足以调整GridBagLayout 限制的麻烦。对我而言,通过一个例子来讨论它实在是令人头痛(并且我不鼓励这种库设计)。相反,建议您从阅读Cornell 和Horstmann 撰写的《核心Java》(第二版,Prentice-Hall 出版社,1997 年)开始。

在这范围内还有其它的:在JFC/Swing 库里有一个新的使用Smalltalk 的受人欢迎的“Spring and Struts”布局管理器并且它能显著地减少GridBagLayout的需要。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值