`
sunsonavaj
  • 浏览: 9000 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

AWTUtilities.setWindowOpaque引起的字体质量问题的一种解决方案

阅读更多
  上个周末,将三号管家更新到了V1.0.4,其实主要是修改了SwingC,管家本身只改了版本号。更新说明里我写的是“优化菜单字体显示”。请大家仔细观察下面的截图:

    这张图片是在三号管家V1.0.3中抓取的,左边是菜单有一部分超出了主界面的范围(那部分是全透明的,所以不能说人家不存在),右边是菜单全部显示在主界面区域内。很明显,左边菜单中字体的质量要差很多,这还是我在绘制的时候修改了某些参数优化过的,未经参数优化的比现在看到的效果还要差很多。为什么会这样呢?TWaver的那位刀客在他的“Swing是一把刀”系列中曾经提到过,我在这里再说一下。可以认为这是JDK的一个bug,具体问题是:java.awt.Window及其子类如果使用com.sun.awt.AWTUtilities.setWindowOpaque(window, false)设为全透明,那么这个窗体及其下的所有子组件所显示的字体都会变得很粗糙。既然是窗体的问题,为什么会影响到菜单呢?原因就在于JPopupMenu显示的区域如果未超出其父窗体的范围,那么它是一个轻量级的JComponent,但是一旦超出了,那这个时候显示出来的实际上是一个重量级的Window。为了实现弹出菜单边框半透明的模糊效果,我重写了setVisible,如果显示的是重量级的Window,直接使用AWTUtilities.setWindowOpaque(window, false)将其置为全透明,所以字体质量就严重下降了。

    这是个很棘手的问题,我使劲的谷歌、百度一番过后,仍一无所获。TWaver的刀客采用的解决方案是在JFrame之上放一个JDialog,然后采取一些手段使它们保持同步,所以看起来仍然是一个窗体,但我这个仅仅只是弹出菜单,如果使用这个方案感觉成本太高。经过几番研究和尝试之后,发现在绘制字体的时候改改某些参数的默认值可以稍稍优化一下,不至于和正常字体的效果差太多,但终究还是有差,这也就是上面图片中大家看到的效果。心头之痛哪,但是没有更好的解决方案只能如此了。

    再然后就到了2011年的某一天,灵感突然告诉我,有个办法或许可行,于是试之,果然没让老三失望。我先把代码帖上来吧,后面再慢慢说闲话。
   


Java代码 
1.public void paint(Graphics g) 
2.    { 
3.        if(!buffered) 
4.        { 
5.            super.paint(g);  
6.        } 
7.        else 
8.        { 
9.            Insets insets = this.getInsets(); 
10.            int x = insets.left; 
11.            int y = insets.top; 
12.            int width = this.getWidth(); 
13.            int height = this.getHeight(); 
14.            int contentWidth = width - insets.left - insets.right; 
15.            int contentHeight = height - insets.top - insets.bottom; 
16.            BufferedImage image = UIUtil.getGraphicsConfiguration(this) 
17.                .createCompatibleImage(width, height, Transparency.TRANSLUCENT); 
18.            BufferedImage contentImage = UIUtil.getGraphicsConfiguration(this) 
19.                .createCompatibleImage(contentWidth, contentHeight, Transparency.OPAQUE); 
20.            Graphics2D g2d = image.createGraphics(); 
21.            Graphics2D contentG2d = contentImage.createGraphics(); 
22.            contentG2d.translate(-x, -y); 
23.            super.paint(g2d); 
24.            super.paint(contentG2d); 
25.            g2d.dispose(); 
26.            contentG2d.dispose(); 
27.            g.drawImage(image, 0, 0, this); 
28.            g.drawImage(contentImage, x, y, this); 
29.        } 
30.    } 

    代码很简单,创建了两个BufferedImage。注意createCompatibleImage中最后一个参数,第一张图片使用Transparency.TRANSLUCENT,这种类型的图片可以设置透明度,用它来绘制边框的半透明模糊效果,为了避免复杂的计算,直接将菜单的所有内容都绘制上去,但这种类型的图片上面显示的字体效果依然很差,所以在中间内容部分用另外一张图片来填充,前提是这张图片不能覆盖掉边框的效果,于是它的长和宽都比第一张图片小,起始位置也跳过了边框,这就是第二个BufferedImage,类型为Transparency.OPAQUE(即完全不透明,默认背景为黑色)。在这种类型的图片上绘制字体,效果与JComponent组件正常的字体完全一致,最后再将这两张图片绘制到组件上。问题就这么解决了,这也就是三号管家V1.0.4中的菜单效果。上面这段代码呢,只做讲解使用,大家如果要用的话可能还需要实际情况实际绘制,但是方法就是这么个方法,万变不离其踪。
分享到:
评论

相关推荐

    java中透明窗口 再也不用局限于矩形窗口了

    com.sun.awt.AWTUtilities.setWindowOpaque(f,false);//设置窗体透明 JPanel p=new JPanel(){ public void paintComponent(Graphics g){//重写paintComponent super.paintComponent(g);//继承的绘制组件...

    java AWTUtilities库

    包含java界面设计中com.sun.awt.AWTUtilities ,及组件开发com.corba等开发库

    透明和不规则

    然而,为了优化视觉效果,还需结合`AWTUtilities.setWindowOpaque(Window, boolean)`方法使用,以消除边缘锯齿效应。 #### 结论与展望 透明和不规则窗口功能的引入,标志着Java Swing在提升跨平台GUI应用的视觉...

    AWTUtilities

    AWTUtilities

    java创建以任意图片为背景的窗口

    使用 Java 创建以任意图片为背景的窗口需要掌握多种技术,包括使用 AWTUtilities.setWindowOpaque() 方法、使用 JPanel 实现背景图片的绘制、使用 JLabel 和 JTextField 实现 UI 组件的添加、实现窗口的边框去除、...

    圣诞倒计时小软件_实现系统托盘背景透明依附边沿自动隐藏

    窗体的透明效果通过`com.sun.awt.AWTUtilities.setWindowOpaque(frame, false)`实现,这是一个非标准的Java API,可能在某些平台上不可用。为了支持窗体拖动,程序监听了鼠标点击事件,记录点击坐标,并在鼠标移动时...

    取标题栏窗体的移动与窗体形状的改变

    这里使用`Polygon`类创建了一个多边形对象,并通过`AWTUtilities.setWindowShape()`方法将其设置为窗体的新形状。 4. **实现窗体拖动:** ```java this.addMouseListener(new MouseAdapter() { public void ...

    基于swing开发弹幕播放器

    AWTUtilities.setWindowOpaque(this, false); } } ``` 然而,这个方法在Windows下可以正常工作,在Linux中可能就不行了,具体是怎样的效果要看Linux使用的图形桌面环境(GNOME下背景是透明的,但是文字飘过后会...

    java 透明界面 java 透明界面

    AWTUtilities.setWindowOpacity(this, js.getValue() / 100.0f); } public static void main(String[] args) { JFrame.setDefaultLookAndFeelDecorated(true); new WindowOpacity().setVisible(true); } } ``...

    java编写的金山词霸

    AWTUtilities.setWindowOpacity(jf, 0.9f); ``` 这使得主窗口具有一定的透明效果。 ### 5. 图像和资源加载 代码中使用`Toolkit.getDefaultToolkit().getImage()`方法来加载图像资源,例如: ```java Image image =...

    Java透明窗体的设置方法

    在Java编程中,创建透明窗体是一项常见的需求,特别是在设计具有现代感和独特视觉效果的应用程序时。本文将详细介绍如何在Java中设置透明窗体,并提供相关知识点。 首先,Java透明窗体的实现依赖于特定的API,这里...

    java实现jframe透明窗体示例

    在构造函数中,我们调用了`AWTUtilities.setWindowOpacity(this, 0.6f);`这行代码来设置窗口的不透明度。这里的`this`指代当前的`TansluFrame`实例,即我们的JFrame对象。`0.6f`是一个浮点数,代表窗口的透明度,...

    MUtilities:MATLAB 访问选定的 Java SwingUtilities、AWTUtilities 和 HG 对象的类似函数-matlab开发

    MUtilities 是一个 MATLAB 类,它提供一组静态方法,类似于 Java SwingUtilities 和新的 AWTUtilities 集合中的一些方法,并包括其中的一些方法。 -------------------------------------------------- -----------...

    java创建快捷方式

    Java 创建快捷方式是一种常见的自动化操作,特别是在开发工具或者系统集成中。这个过程涉及到Java的桌面集成API,允许程序与用户的操作系统进行交互,如创建、修改或打开文件、URL等。以下将详细介绍如何使用Java来...

    基于Java的即时通讯工具

    基于java语言设计的简单即时通讯软件 一下是他的突出特点...2.运用awtutilities 类实现了不规则界面 3.实现最小化托盘和边缘隐藏 4可以添加好友和好友列表 5.注意引入项目后加载mysql的驱动 6.文件中包含数据库表结构

    停车场管理系统_2整理.pdf

    - **AWTUtilities**:辅助类,可能用于访问底层图形系统。 综合以上信息,我们可以看出文档主要讨论了一个停车场管理系统的后端数据库设计、前端界面设计以及基于Java Swing的编程实现。尽管文档内容有些模糊和不...

    Java版给爱人表白的玫瑰花程序代码

    在本程序中,我们使用了 Java 的 AWTUtilities 类,设置了 JFrame 对象的透明度,使得玫瑰花图片显示在屏幕中央,并具有渐入效果。 知识点5: 线程编程 在本程序中,我们使用了 Java 的线程编程机制,创建了一个 ...

Global site tag (gtag.js) - Google Analytics