`

Swing布局入门很好的文章

 
阅读更多

本篇介绍AsWing的布局管理器(LayoutManager),在阅读本篇 之前读者需要对AsWing有基本认识,并且知道什么是容器,org.aswing.Container ,以下文中出现的 “容器” 都是指Container类或其子类。

布局管理器是什么

    和Java的Swing框架一样,AsWing中的布局管理器用来负责容器中所有组件的尺寸与排列方式,也就是说,当开发者将组件扔到容器中后,组件在容 器中如何排列与组件显示的尺寸都交付给该容器的布局管理器全权负责,容器本身只负责承载其内部的组件,并不对子组件的排列方式进行干预。
    所以对于AsWing的使用,掌握如何使用布局是非常重要的,AsWing自带一些常用的布局管理器,可以灵活使用,满足大部分的排列需求,如果有特殊需 求,开发者还可以扩展出新的布局方式以满足需要。

布局管理器的运作原理

    在AsWing的每一个容器组件中,都有一个LayoutManager对象,LayoutManager是一接口,所有具体的布局类都实现 LayoutManager接口。

    
addLayoutComponent
removeLayoutComponent
getLayoutAlignmentX
getLayoutAlignmentY
invalidateLayout
layoutContainer
maximumLayoutSize
minimumLayoutSize
preferredLayoutSize

 

    这些就是LayoutManager接口的所有方法。
    addLayoutComponent 和 removeLayoutComponent,用于向布局中添加组件和删除组件,这两个方法会在向容器中 添加/删除 组件的时候被调用,有时addLayoutComponent 还要指定布局约束,这个约束不是所有布局都会用到,是因布局的需要而决定的,就像BorderLayout的 东南西北中,稍后会说到。
    getLayoutAlignmentX 和 getLayoutAlignmentY 获取对齐方式。
    invalidateLayout 方法使布局失效,指示布局管理器放弃缓存了的信息,在下一次重绘时,重新计算布局。
    layoutContainer 是布局管理器中非常重要的方法,在实现类中,在该方法中应该编写具体的排列算法,对容器内的组件进行排列。

    布局管理器所做的事情就是对容器内的组件进行排列,并且为容器计算preferredSize(组件的最佳尺寸信息),有些布局管理器也会计算 mininumSize和maxnumSize(这两个值为组件的最小和最大尺寸,但很少用到着两个属性,通常最大设为一个极大值,最小设置为0,0即 可)。
    组件的preferredSize、mininumSize和maxnumSize,都是给布局管理器提供参考信息的,最终容器内部组件的大小还是由布局 具体实现中的算法决定,要获得组件的实际尺寸,通过 getSize() 方法。所以在有些时候为容器内的组件设置preferredSize或许会更有用。

如何使用布局

    前面说了每个容器中都有一个布局管理器,所以当我们要为一个容器指定一个布局的时候调用容器的 setLayout 方法即可,由于此项机制,我们可以在运行时动态改变容器的布局。
    当需要将某个组件加入到容器中时,不是用addChild,而是要用 append 或 insert 方法,append将组件追加到容器尾部,instert将组建添加到容器的指定位置,append和insert调用后,方法内部会同时调用容器中布局 对象的 addLayoutComponent方法,将组件加入到布局管理器中,这两个方法的最后一个参数为可选参数,就是前面提到的布局约束,如果指定了该参数 最终会传递给布局管理器的addLayoutComponent方法。如果使用addChild方法添加组件,组件会被视为普通显示元件而得不到布局管 理。
    大部分布局管理器会用到容器内组件的尺寸信息,在进行排列时会作为逻辑判断与最终设置组件的实际尺寸,这使得开发者可以给组件提供尺寸信息以达到想要的效 果,一般情况下布局管理器都会优先使用组件的preferredSize, 如果有些布局明确说明以preferredSize显示组件尺寸,那么为组件设置的preferredSize就是最终显示出来的尺寸,当然也有可能有布 局使用绝对尺寸来显示组件,比如EmptyLayout,要指定布局中组件的尺寸就是用 setSize。这些在不同的布局中都会有具体的情况,在使用具体的布局管理器时,需要先阅读该布局的描述文档,然后决定用何种方式来控制容器内组件的尺 寸。
    有时候对容器内的组件尺寸信息进行了改变,却没有立即看到效果,那可能是由于布局管理器缓存了布局信息,这时候我们就需要使布局失效,迫使他在下一次重绘 的时候重新计算排列容器内的组件。比较常用的方法是调用已发生改变的组件的revalidate方法,这样会使调用该方法的组件与该组件外层的所有容器都 标记为需要重新布局。

常用布局介绍

    AsWing中自带了很多种布局,这些布局可以满足日常开发中的大部分需求,下面介绍几个常用的布局方式。

BorderLayout
BoxLayout 只管里容器中的5个组件的排列方式,这五个组件的位置分别位于 东、南、西、北、中 方向,请看下图:
上图的容器中(JFrame的ContentPane)有5个按钮(JButton)组件,分别位于 North, South, West, East 和 Center 。
要为容器指定一个BorderLayout,可以使用

container.setLayout(new BorderLayout());

BorderLayout的构造函数可传入两个参数,即 hgap 和 vgap
组件之间的间隔为 VGap 和 HGap,VGap是纵向组件之间的间隔,HGap是横向组件之间的间隔,可以用 setVgap 和 setHgap 来设置。

位于 North 和 South 位置的组件高度为他们的 preferredHeight,而宽度就是容器的宽度,这里的 fullWidth 和 fullHeight指可用的最大宽度和高度。
位于West 和 East 位置的组件的宽度被设置为他们的 preferredWidth,高度为 fullHeigth。
Center位置即中间的那个组件的尺寸将被设为 剩余区域的大小。

要在向容器中添加组件时指定组件在容器中所处的位置,就可以用 append方法中的第二个参数来制定约束。
如 :

container.append(component, BorderLayout.NORTH);

        这将会把component添加到容器的 North位置(北方),记住虽然我们调用的是容器的append方法,但是最终决定如何排列组件的是容器中的布局管理器,容器会调用其布局管理器的相应 方法,传入组件和约束,布局管理器会根据约束来排列组件并且设置组件的尺寸。

FlowLayout
FlowLayout 是一种比较简单的布局方式,它会将所有组件排列成一行,以组件的preferredSize显示,一般情况下,如果一行显示不了所有的组件,会自动换到下 一行显示。
如图:
这是一个典型的FlowLayout布局,容器内的组件都以preferredSize显示,由于在一行中不够显示所有容器,所以布局管理器将剩余的组件 换到了第二行显示。

FlowLayout的构造函数可以接受4个参数:align, hgap, vgap, margin


align表示对齐方式,可以传入 FlowLayout.LEFT, FlowLayout.RIGHT, 或 FlowLayout.CENTER,分别表示左对齐,中间对齐和右对齐。
组件之间的间隔和BorderLayout一样,也是通过hgap和vgap定义。
margin为一个布尔参数,指示是否将间隔作用与容器的四周,默认为true,如果设置为false的话,组件将紧贴容器的边框。

要向使用了FlowLayout的容器中添加组件,只需要简单的调用容器的append或insert方法即可,无需指定约束,因为 FlowLayout对于组件的排列是一个挨一个的,没有特殊的约束定义。


BoxLayout
BoxLayout 对容器中的组件进行同一方向上的平均排列,纵向或者横向:

BoxLayout的构造函数有两个参数,axis 和 gap。
axis用于指示容器中组件的排列方向,一种有2种,BoxLayout.X_AXIS 和 BoxLayout.Y_AXIS 即横向与纵向。
gap就是制定组件之间的间隔,因为BoxLayout排列的组件不是横向就是纵向,不会出现横向纵向同时出现的情况,所以只要一个gap参数即可。

在横向排列的情况下,容器内组件的宽度是容器的宽度减去所有间隙的和然后平局分配得到的。组件的高度撑满容器内的高度。
纵向排列的方式雷同,只是情况正好相反。

SoftBoxLayout
         SoftBoxLayout与BoxLayout非常相似,使用上也几乎一样,但是,对于组件尺寸的设置有所不同。
        当布局被设为横向排列时,容器内的组件宽度会被设置成各组件的preferredWidth,高度为容器高度。
        当布局被设为纵向排列时,情况正好相反,组件的宽度被设为容器宽度,高度为各组件的preferredHeight。


SoftBoxLayout的构造函数接受4个参数,axis, gap, align
   前两个参数的作用于BoxLayout构造函数的参数作用相同,排列方向和组件间隔。
   第三个参数为容器内组件的对齐方式,当排列为横向排列时,可以设为 AsWingConstants.LEFT、AsWingConstants.CENTER、AsWingConstants.RIGHT,即左、中、 右。
   如果排列方式为纵向排列,可以设为 AsWingConstants.TOP、AsWingConstants.CENTER、 AsWingConstants.BOTTOM,集 上、中、下。

其他布局方式

这里介绍了4种比较常用的布局方式,当然AsWing中的布局方式还不止这些,相信读者只要掌握了这4中布局,再学习新的布局方式将不成问题。

上面的这些布局方式,都是对容器内的组件按一定规则进行排列和调整尺寸,如果要完全手动调整,进行绝对定位的话,可以使用EmptyLayout。
EmtpyLayout 是对LayoutManager接口的空实现,只是简单的实现了接口方法,没有具体算法,所以扔到EmptyLayout容器中的组件都可以直接 setSize,和setLocation,设置多少,运行时看到的就是多少,但是注意,由于是空实现,所以放到容器中的组件没有默认尺寸,如果不对其进 行setSize,是看不到的。

另外还有GridLayout,对容器中的组件进行网格式的排列。CenterLayout,只管里容器中的一个组件,使其在容器中居中。 FlowWrapLayout,FlowLayout的改进版,可以指定每行的最大宽度,如果大于指定宽度则开发换行。等等,读者可以自行查看 AsWing的API文档进行查看,如果觉得没有自己需要的,还可以自行实现LayoutManager接口,创建自己的布局方式。

 

 

综合布局实例

下面以一个简单的例子结束本篇教程,假设我们要实现一个类似 QQ/MSN这样的聊天面板,那么只要用AsWing的几种常用的布局就可以轻易实现。
先看一下最终效果:


在实现这个实例的时候,我只用了3种布局:BorderLayout、FlowLayout 和 SoftBoxLayout
下面这张图是对整个面板的布局拆解:

呵呵,非常抱歉,本人的图像处理能力几乎为0…… 所以搞得比较丑。

这个面板主要非为3个部分,顶部的按钮条,主体的文字输入输出区域,右侧的图片栏。 所以总的框架用BorderLayout来布局是最合适不过的了。
然后顶部(North)的按钮排列没有什么特殊需求,只要按顺序显示即可,所以用了FlowLayout。

主体部分(Center)用了一个AsWing的另一个容器组件,JSplitPane,该组件内仅容纳2个组件,可以通过当中的一条控制线来调整 内部两个组件所占用的空间。
JSplitPane中上面部分的组件仅为一个文本框。
观 察一下下半部分,我们需要在顶部显示一排按钮,中间也就是主体部分显示一个输入用的文本狂,下面也是用来显示按钮,这不又是一个BorderLayout 的用武之地么,上面的那排按钮被放在一个FlowLayout的容器中,注意底部的发送按钮,我们不是直接把那个按钮放在BorderLayout的 South位置,因为如果这样的话,按钮的宽度将会和这个容器一样,这样就会显得很长,那么我们可以在South位置再放一个容器,容器的布局使用 FlowLayout,对齐方式为右对齐,再把发送按钮放入这个容器中,就能做到我们需要的效果啦。

最后是聊天面板的右侧部分,右侧可能用来显示对话双方的头像或其他的一些功能面板,一般都会是一些纵向排列的组件,并且每个组件的高度可能会不同, 所以我为右侧面板选择了SoftBoxLayout。
至此,一个非常简易的聊天面板UI就完成了 :),下面是全部源代码:

package {import flash.display.Sprite;import org.aswing.ASColor;import org.aswing.AsWingConstants;import org.aswing.AsWingManager;import org.aswing.BorderLayout;import org.aswing.Container;import org.aswing.FlowLayout;import org.aswing.JButton;import org.aswing.JFrame;import org.aswing.JPanel;import org.aswing.JScrollPane;import org.aswing.JSplitPane;import org.aswing.JTextArea;import org.aswing.SoftBoxLayout;/** * AsWing 聊天面板布局实例 * * @author harry */public class ChatPane extends Sprite {    private var frame:JFrame;    private var mainContainer:Container;    public function ChatPane() {        AsWingManager.initAsStandard(this);        frame = new JFrame(this, "AsWing Chat Pane");        mainContainer = frame.getContentPane();        mainContainer.setLayout(new BorderLayout(5));        mainContainer.append(getNorthPane(), BorderLayout.NORTH);        mainContainer.append(getCenterPane(), BorderLayout.CENTER);        mainContainer.append(getEastPane(), BorderLayout.EAST);        frame.pack();        frame.show();    }    /**     * 顶部按钮面板     */    protected function getNorthPane():JPanel {        var pane:JPanel = new JPanel(new FlowLayout());        for(var i:int=0; i<5; i++) {            pane.append(new JButton("Btn"+i));        }        return pane;    }    /**     * 中间文本区域     */    protected function getCenterPane():Container {        // 文本显示区域        var displayArea:JScrollPane = new JScrollPane(new JTextArea());        var sp:JSplitPane = new JSplitPane(AsWingConstants.VERTICAL,                                            false,                                            displayArea,                                            getInputArea());        return sp;    }    /**     * 文本输入区域,包括按钮条,输入文本,发送按钮     */    protected function getInputArea():JPanel {        var inputArea:JPanel = new JPanel(new BorderLayout(0, 5));        var btnBar:JPanel = new JPanel(new FlowLayout());        for(var i:int=0; i<6; i++) btnBar.append(new JButton("B"+i));        inputArea.append(btnBar, BorderLayout.NORTH); // 将按钮条放置在顶部。        var inputPane:JScrollPane = new JScrollPane(new JTextArea());        inputArea.append(inputPane, BorderLayout.CENTER); //输入框放在中间        var sendButtonPane:JPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT,5,5,false));        sendButtonPane.append(new JButton("发送"));        inputArea.append(sendButtonPane, BorderLayout.SOUTH); //发送按钮在底部        return inputArea;    }    /**     * 右侧面板     */    protected function getEastPane():JPanel {        var pane:JPanel = new JPanel(new SoftBoxLayout(SoftBoxLayout.Y_AXIS, 5));        var pic1:JPanel = new JPanel();        pic1.setOpaque(true);        pic1.setBackground(new ASColor(0xFF6600));        pic1.setPreferredHeight(100);        var pic2:JPanel = new JPanel();        pic2.setOpaque(true);        pic2.setBackground(new ASColor(0x0000FF));        pic2.setPreferredHeight(100);        pane.appendAll(pic1, pic2);        pane.setPreferredWidth(100);        return pane;    }}}本篇AsWing布局入门就到这里了,如果读者有什么疑问可以到AsWing的官方论坛进行讨论

分享到:
评论

相关推荐

    javaSwing初级入门知识

    IBM的教程是很好的学习资源,通过阅读和实践,初学者可以快速掌握Swing的基本操作,为构建自己的Java桌面应用打下坚实的基础。在学习过程中,建议动手编写简单的应用程序来巩固理论知识,实践是最好的老师。同时,...

    helloword入门系列之swing 入门 简单的桌面小词典—附

    这个“Swing入门 简单的桌面小词典”教程是一个很好的起点,帮助新手逐步掌握Swing的各种概念和技术。通过分析并运行“SwingTest2”源代码,不仅可以提升编程技能,还能体验到Swing带来的便利性。

    swing初学者入门教程

    ### Swing初学者入门教程知识点详解 #### 一、UI(用户界面)的深入理解 - **定义**: UI,即用户界面,不仅仅是指我们常见的按钮、输入框等视觉元素,还包括了鼠标、键盘、屏幕颜色、字体等一切参与到人机交互过程...

    Java Swing入门基础.

    对于初学者来说,学习 Swing 是一个很好的提升阶段,因为它可以帮助理解 Java 如何创建交互式的图形界面。以下是一个简单的 Swing 程序示例,它展示了一个基础的窗口应用: ```java import javax.swing.*; import ...

    swing入门样例,配置文件读取,画面显示

    总的来说,这个"swing入门样例,配置文件读取,画面显示"涵盖了Swing GUI开发的基础和进阶内容,对于初学者来说是一份很好的学习资源。通过分析和理解这个样例,你可以学习到如何构建复杂的桌面应用程序,以及如何...

    swing入门-源码和教程

    本资源"swing入门-源码和教程"是一个非常适合初学者的起点,它包含了一系列的教程和源码示例,帮助你快速掌握Swing的基本概念和用法。 首先,`swing基础.pptx`很可能是讲解Swing基础知识的幻灯片,可能涵盖以下内容...

    java swing 学习资料

    Java Swing 是Java GUI(图形用户界面)开发的重要库,它属于Java Foundation Classes (JFC)的一部分。Swing 提供了一套丰富的组件集合,用于...对于想要进入Java桌面应用开发领域的学习者来说,这是一个很好的起点。

    swing入门级窗体一个管理界面

    这个入门级的管理界面项目提供了一个简单的方式来了解Swing的基本用法,非常适合初学者进行学习。 在Swing中,窗口通常由`JFrame`类来创建,它是所有顶级容器的基础。在你提供的资源中,我们可以预期有一个`JFrame`...

    MyEclipse 中Swing的可视化开发

    在IT行业中,Swing是Java平台上用于构建图形用户界面(GUI)的一个强大的...同时,对于学习Java GUI编程的新手来说,这是一条很好的入门路径,因为它降低了学习曲线,使他们能够更快地构建出功能丰富的桌面应用程序。

    Java的Swing组件实现的计算器,Java入门学习案例,源码.rar

    Java Swing 是Java编程语言中...对于初学者来说,它是一个很好的起点,可以帮助理解Java图形用户界面编程的基础知识。通过分析和实践这个项目,开发者能够深入理解Swing组件的用法,并掌握如何构建功能完备的应用程序。

    4个swing界面.rar_java swing_swing_swing 界面_个_界面

    总之,这个Java Swing界面的压缩包是一个很好的学习资源,它不仅涵盖了基本的Swing组件和界面设计,还可能提供了实际的运行示例,让初学者可以通过实践来深化理解。对于想要提升Java桌面应用开发能力的人来说,这是...

    Java Swing练习中的基础代码

    Java Swing是Java GUI(图形用户界面)开发的一个重要库,用于构建桌面应用程序。在这个"Java Swing练习中的基础代码"中,我们可以看到几个简单的...对于想要提升Java GUI编程技能的初学者来说,这是一个很好的起点。

    Java的Swing组件实现的信息管理系统,Java入门学习案例,源码.rar

    本项目是一个基于Swing的简单信息管理系统,对于初学者来说,是一个很好的实践案例,可以帮助理解如何在Java环境中运用Swing组件构建实际的应用程序。 首先,Swing提供了许多预定义的组件,如按钮(JButton)、文本框...

    Java学习指南(Swing入门篇)

    通过本篇的训练,学员可以较容易的掌握Java的主要语法,对常用的API都有很好的掌握。本篇内容至少包含:- 基本控件的使用- 布局管理器的使用- 自定义布局- 图片的加载及使用- 对话框,及自定义对话框- 菜单和工具栏-...

    精通Java Swing程序设计

    本教程"精通Java Swing程序设计"旨在帮助新手深入理解和掌握Swing技术,让初学者能够轻松地入门并感受到Java编程的乐趣。 Swing提供了一系列组件,如按钮、文本框、菜单等,它们都是轻量级的,运行在Java虚拟机上,...

    JAVA swing五子棋游戏项目软件源代码.zip

    总之,"JAVA swing五子棋游戏项目软件源代码"是一个很好的学习资源,它涵盖了Java Swing的基础知识,包括组件使用、图形绘制、事件处理以及简单的游戏逻辑实现。无论是对于希望提升Java GUI编程技能的初学者,还是...

    swt入门范例新手适用,入门级

    这个“swt入门范例新手适用,入门级”压缩包很可能是为初学者准备的一系列示例代码,帮助他们快速掌握SWT的基本用法。 SWT作为GUI工具包,提供了丰富的组件,如按钮、文本框、列表、树视图等,用于构建用户界面。与...

Global site tag (gtag.js) - Google Analytics