首页 | 互联网 | IT动态 | Cisco | Windows | Linux | Java | .Net | Oracle | 华为 | 存储世界 | 服务器 | 网络设备 | IDC | 安全 | 求职招聘
IT培训 | 数字网校 | 技术专题 | 电子书下载 | 教学视频 | 网页设计 | 平面设计 | 解决方案 | 直播室 | 虚拟考场 | 搜索 | 博客 | 沙龙 | 论坛
中国IT实验室Linux频道
中国IT教育
 
首页 资讯动态 认证考试 新手入门 核心技术 高级技术 J2EE J2ME Java&XML 开源技术 其他技术 RSS订阅 论坛 专题
您现在的位置: 中国IT实验室 >> Java >> 核心技术 >> SwingAwtApplet >> 文章正文

Swing增加透明窗体及不规则窗体

文章来源中国IT实验室收集整理 作者佚名 更新时间2008-5-12 保存本文保存本文 推荐给好友推荐给好友 收藏本页收藏本页

    图 5. 工具提示

    现在我们做相同的动画。当工具提示显示时将颜色调淡些,当它被隐藏起来时把它的颜色渐隐如何?一旦您熟悉了 AWTUtilities API,上述操作不难实现。下面给出 show() 方法的代码:

    @Override public void show() { if (this.toFade) { // mark the popup with 0% opacity this.currOpacity = 0; com.sun.awt.AWTUtilities.setWindowOpacity(popupWindow, 0.0f); } this.popupWindow.setVisible(true); this.popupWindow.pack(); // mark the window as non-opaque, so that the // shadow border pixels take on the per-pixel // translucency com.sun.awt.AWTUtilities.setWindowOpaque(this.popupWindow, false); if (this.toFade) { // start fading in this.fadeInTimer = new Timer(50, new ActionListener() { public void actionPerformed(ActionEvent e) { currOpacity += 20; if (currOpacity <= 100) { com.sun.awt.AWTUtilities.setWindowOpacity(popupWindow, currOpacity / 100.0f); // workaround bug 6670649 - should call // popupWindow.repaint() but that will not repaint the // panel popupWindow.getContentPane()。repaint(); } else { currOpacity = 100; fadeInTimer.stop(); } } }); this.fadeInTimer.setRepeats(true); this.fadeInTimer.start(); } }这时我们用 0% 的不透明度标记弹出窗口。然后我们启动重复计时器进行五次迭代。每一次跌代我们增加窗口不透明度 20% 并重新绘画。最后我们停止计时器。最终的视觉结果是工具提示外观的平滑退色序列,这一序列持续大约 250 毫秒。

    hide() 方法非常类似:

    @Override public void hide() { if (this.toFade) { // cancel fade-in if it's running. if (this.fadeInTimer.isRunning()) this.fadeInTimer.stop(); // start fading out this.fadeOutTimer = new Timer(50, new ActionListener() { public void actionPerformed(ActionEvent e) { currOpacity -= 10; if (currOpacity >= 0) { com.sun.awt.AWTUtilities.setWindowOpacity(popupWindow, currOpacity / 100.0f); // workaround bug 6670649 - should call // popupWindow.repaint() but that will not repaint the // panel popupWindow.getContentPane()。repaint(); } else { fadeOutTimer.stop(); popupWindow.setVisible(false); popupWindow.removeAll(); popupWindow.dispose(); currOpacity = 0; } } }); this.fadeOutTimer.setRepeats(true); this.fadeOutTimer.start(); } else { popupWindow.setVisible(false); popupWindow.removeAll(); popupWindow.dispose(); } }首先检查退色序列是否仍在运行,根据需要将它删除。然后,不立即隐藏窗口,而是将不透明度以 10% 的增量从 100% 改为 0(因此渐隐序列是退色序列的两倍)然后隐藏并处置弹出窗口。注意两种方法参阅了 Boolean toFade 变量 —— 它在工具提示上被设置为 true.弹出窗口的其他类型(菜单、组合框下拉列表)没有退色动画。

    视频反射现在让我们做些更为激动人心的事情。在 Romain Guy 的博客条目 重画管理器演示(第 11 章) 中,它显示了提供反射功能的 Swing 组件。从他与 Chet Haase 合著的 《 肮脏的富客户机 》 书中抽取一段测试应用程序,其中显示该组件提供了 QuickTime 电影的实时反射。在窗口绑定 之外 进行反射如何?

    首先要有实际应用中的反射帧的屏幕截图。图 6 显示了正在播放 “Get a Mac” 广告的形状规则的 Swing 帧( 使用嵌入式 QuickTime 播放器 ), 伴随着覆盖桌面的透明的实时反射:

    图 6. QuickTime 电影的反射

    该实现重用了来自 Romain 的几个构造块并将它们扩展到“桢外”。它还有一个重画管理器 ( 要了解关于重画管理器方面的详细信息,请参见 使用重画管理器的验证覆盖 条目 )以便将主桢内容与反射窗口保持同步。还需要在主桢上注册组件侦听器和窗口侦听器以便确保反射窗口与主窗口的可见性、位置和大小保持同步。除此之外,还要有一个自定义窗格将其内容绘画到脱屏缓冲区。脱屏缓冲区被用于绘画主桢和在反射窗口内的反射。

    让我们看一下代码。主类是扩展 JFrame 的 JReflectionFrame.构造器创建了反射窗口并向其中添加非双重缓冲和透明的面板。还重写了面板的 paintComponent() 以便绘画主桢内容的反射。在初始化反射桢的位置和大小后,我们安装了一个自定义重画管理器。

    public JReflectionFrame(String title) { super(title); reflection = new JWindow(); reflectionPanel = new JPanel() { @Override protected void paintComponent(Graphics g) { // paint the reflection of the main window paintReflection(g); } }; // mark the panel as non-double buffered and non-opaque // to make it translucent. reflectionPanel.setDoubleBuffered(false); reflectionPanel.setOpaque(false); reflection.setLayout(new BorderLayout()); reflection.add(reflectionPanel, BorderLayout.CENTER); // register listeners - see below …… // initialize the reflection size and location reflection.setSize(getSize()); reflection.setLocation(getX(), getY() + getHeight()); reflection.setVisible(true); // install custom repaint manager to force re-painting // the reflection when something in the main window is // repainted RepaintManager.setCurrentManager(new ReflectionRepaintManager()); }下面是保持反射窗口与主桢同步的侦听器:

    this.addComponentListener(new ComponentAdapter() { @Override public void componentHidden(ComponentEvent e) { reflection.setVisible(false); } @Override public void componentMoved(ComponentEvent e) { // update the reflection location reflection.setLocation(getX(), getY() + getHeight()); } @Override public void componentResized(ComponentEvent e) { // update the reflection size and location reflection.setSize(getWidth(), getHeight()); reflection.setLocation(getX(), getY() + getHeight()); } @Override public void componentShown(ComponentEvent e) { reflection.setVisible(true); // if the reflection window is opaque, mark // it as per-pixel translucent if (com.sun.awt.AWTUtilities.isWindowOpaque(reflection)) { com.sun.awt.AWTUtilities.setWindowOpaque(reflection, false); } } }); this.addWindowListener(new WindowAdapter() { @Override public void windowActivated(WindowEvent e) { // force showing the reflection window reflection.setAlwaysOnTop(true); reflection.setAlwaysOnTop(false); } }); 重画管理器相当简单:它强制主桢的整个根窗格重画,然后更新反射窗口。这样可以最优化更新区域反射的同步,对于示例应用程序要达到的目的,这点就足够了。

    private class ReflectionRepaintManager extends RepaintManager { @Override public void addDirtyRegion(JComponent c, int x, int y, int w, int h) { Window win = SwingUtilities.getWindowAncestor(c); if (win instanceof JReflectionFrame) { // mark the entire root pane to be repainted JRootPane rp = ((JReflectionFrame) win)。getRootPane(); super.addDirtyRegion(rp, 0, 0, rp.getWidth(), rp.getHeight()); // workaround bug 6670649 - should call reflection.repaint() // but that will not repaint the panel reflectionPanel.repaint(); } else { super.addDirtyRegion(c, x, y, w, h); } } }主桢 (脱屏缓冲区) 和反射窗口的绘图代码在 Romain 的 反射教程 中进行了详细描述。

    结束语对这一结果我们期待已久,现在终于如愿以偿。尽管创建透明和不规则窗口的 API 还没有官方支持的包,但是它们仍可用于创建可视的富跨平台 UI.从 Romain 的博客 透明和不规则窗口( Extreme GUI Makeover ) 条目展示 JNA 项目,用于创建动画的透明不规则窗口的可视化竞争应用。现在您可以使用核心 JDK 做同样的处理。本文全面介绍了显示实际应用中的核心 JDK API 的三个示例。我确信您能想出更多的例子。

上一页  [1] [2] 

【责编:Ken】

中国IT教育

相关产品和培训
文章评论
 友情推荐链接
 认证培训
 专题推荐

 ·关于Java框架技术专题
 ·XML全攻略技术专题
 ·JAVA开源技术介绍专题
 ·Java嵌入式开发之J2ME技术专题
 ·超前体验 Oracle 11g的5个新特性
 ·揭密使用VB.NET的五个实用技巧
 ·Oracle和SQL Server常用函数对比专题
 ·展现C#世界 C#程序设计专题
 ·Java入门 Tomcat的配置技巧精华专题
 ·Oracle RMAN物理备份技术详解
 今日更新
 社区讨论
 博客论点
 频道精选
 Java 频道导航