Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 273|回复: 0

[Swing学习]如何混排Swing和AWT组件

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-5 23:56:01 | 显示全部楼层 |阅读模式
    我们都清楚Swing是模拟的,所谓轻量级(lightweight)组件。而AWT使用本地的,所谓重量级(heavyweight)组件。什么是重量级组件?重量级组件是指每个组件对象对应于一个代表本地组件的native peer。这一点Swing组件和AWT完全不同。Swing中组件除顶级容器类组件如Window、Frame和Applet有自己的native peer外其他都没有对应的native peer,用来模拟这些Swing组件的图形对象资源都来自于它所在的顶层容器。
       
       
            
       
          由于实现机制不同,Swing和AWT组件有着完全不同的Z-order机制。这使得它们在混合排版时出现各种各样的互相遮盖问题。Swing的设计者Amy Fowler在SDN(Sun Developer Network)有一篇权威的文章介绍了混排Swing和AWT组件存在的问题,以及解决混排问题的原则:
       

       
       
        Mixing heavy and light components
       
       
          
       
          该文不推荐使用AWT组件,更不推荐将AWT组件和Swing组件进行混排,而推荐使用纯粹的Swing组件完成所需的任务。这样做有三点好处:
         
      
       
       
         
       

         
       
      


         1.高效的利用资源。Swing是轻量级组件,AWT是重量级组件,需要操作系统的额外开销。


       

         2.维护平台一致性。重量级组件在不同平台具有不同的缺省外观、尺寸、布局、字体以及行为等。这需要编写额外代码维护各个平台程序的一致性。比如Windows和Linux的缺省字体、大小和样式都不一样,需要显示的设置字体样式和大小等;在Windows很好看的布局有可能在Linux变得乱七八糟;组件间的间隔因为平台的不同而有很多变化。


       

         3.良好的皮肤支持。AWT同SWT一样是不支持皮肤更换机制的。


       


    同重量级AWT组件相比,轻量级Swing组件有如下不同特征:


         1.Swing组件可以是透明的,而AWT是不透明的。


         2.Swing的透明机制可以实现不规则形状的组件,而AWT组件只能是矩形组件。


         3.鼠标事件总是通过Swing组件所在的顶层容器一层层传递给它,因此可被中间组件截获进行特殊处理。最大应用就是GlassPane和LayerPane,可用来实现跨组件的协作,比如拖动以及弹出式菜单和下拉框等。而AWT组件的鼠标事件是直接传递给该组件的,应用程序无法截获而实现特殊效果,控制权都在本地图形系统哪儿。


         4.Swing组件的实际Z-order是同其顶层容器一样的。Swing的模拟行为最终要靠顶层容器提供图形设备资源完成,实际上所有同一顶层容器的Swing组件都共享该顶层容器的拥有的本地资源。因此这些Swing组件的实际Z-order值都是一样的,都要小于该顶层容器内所包含的其他AWT组件。所以当Swing组件和AWT组件重合时,Swing组件总是被AWT组件所覆盖。


         Z-order问题使Swing组件和AWT组件混排的界面产生了很多问题。但许多时候却往往不得不混排。一种典型混排场景是Swing组件没有提供相对应的组件,而这些组件目前只有AWT组件才提供。如为了显示网页内容,需要将JDIC的WebBrowser嵌入到Swing程序中。WebBrowser是使用AWT机制实现的重量级组件,它将平台的缺省浏览器嵌入到一个AWT的Canvas组件中。如果此时WebBrowser附近恰好有一个Swing组件需要动态变化,如WebBrowser的顶部有一些JMenu菜单或者JComboBox,那么这时弹出的窗口就会被WebBrowser所覆盖。


       

       Amy列举除了四条混排原则帮助你解决这些问题:


         1.
    Do not mix lightweight (Swing) and heavyweight (AWT) components within  a container where the lightweight component is expected to overlap the  heavyweight one.不要在同容器内混排互相覆盖的轻量级组件和重量级组件。比如下图两个标签一个是Swing的,一个是AWT的,它们互相覆盖,结果造成AWT总是覆盖助Swing的,不管你添加的顺序如何:














         2.Do not place heavyweight (AWT) components inside a JScrollPane. If  you need to scroll areas containing heavyweight components, use AWT"s  ScrollPane instead.不要将AWT组件放在JScrollPane内。如需要滚动AWT组件,请使用java.awt.ScrollPane。下图是将java.awt.Button放在JScrollPane的后果:















         3.Do not place heavyweight (AWT) components inside a JInternalFrame.不要将AWT组件放在JInternalFrame中。因为JInternalFrame是Swing组件,而且不同的JInternalFrame需要经常改变显示顺序,加在上面的AWT组件会总是在顶部,不管它所在的JInternalFrame是不是在前面:






      


         4.
    If you place Swing popup components in a window containing heavyweight  components and it"s possible that the popup windows will intersect a  heavyweight, then invoke JPopupMenu.setDefaultLightWeightPopupEnabled(false)before the popup components are instantiated.如果窗口中同时有Swing弹出式组件(比如菜单、下拉框)和重量级AWT组件,那么弹出窗口有可能会被重量级组件所遮挡。这是因为Swing弹出式窗口的实现为了尽可能轻量级化,使用了轻量级模拟窗口,而不是java.awt.Window组件。比如菜单,如果弹出菜单的窗口恰好在顶层容器内部,那么Swing采用模拟窗口的办法画出此窗口,只有当弹出窗口的边界超出了顶层容器窗口的边界时,这时才使用Window实现。这就会带来同上面各种Z-order问题相同的现象,菜单或者下拉框被AWT组件所遮住了:









      
        如何解决这种问题?如果是菜单或者下拉框,可调用JPopupMenu的静态方法
    setDefaultLightWeightPopupEnabled(false)将弹出的窗口强制为Canvas或者Window等重量级的AWT组件,这样就可以避免弹出窗口被别的AWT组件所覆盖。其他的弹出式组件都有对应的方法强制弹出重量级窗口。







         总之,
    不推荐使用Swing和AWT混排的方法编写界面。如果非要这样编写界面,那么首先保证它们之间不互相覆盖,其次AWT组件要放到ScrollPane而不是JScrollPane中,再次JInternalFrame中不能放置AWT组件,最后对于需要弹出窗口的组件要使用相应方法强制弹出重量级窗口。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 13:22 , Processed in 0.303686 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表