这几天我在写一个记事本程序,为了方便记事本记事,我准备将记事本界面透明化。于是上网查了一下资料。然后将透明化界面做了出来。

可是在做的过程中我还是遇到了一些小小的问题,所以就把它记录了下来。

问题1:奇怪的错误(访问限制:Access restriction)

透明化窗体中有这样一段代码:

// 判断系统是否支持窗体透明化
if (com.sun.awt.AWTUtilities.isWindowOpaque(this)) {
	// 设置窗体透明化, 透明参数值[0, 1](float类型)
	com.sun.awt.AWTUtilities.setWindowOpacty(this, 0.5f);
} else {
	JOptionPane.showMessageDialog(this, "系统不支持 JDK版本过低或JRE系统库缺损");
]

这段代码明明是没有错的,但是Eclipse却偏偏报了错,这是为什么呢?
通过错误提示,点击 “Configure problem severity” ,我发现了问题所在,原来是eclipse的配置问题。

解决方法如下:

菜单栏找到 Window -> Preferences -> Java Compiler(中间可能省略几步,你可以搜索) -> Errors/Warnings -> Deprecated and restricted API -> Forbidden reference(access rules) 后面的 Error 下拉改成 Warning 或者 Ignore -> 确定。
然后就 OK 了!

问题二:郁闷的异常(IllegalComponentStateException)

当我所有的代码都写完之后,一运行,结果出现了编译异常。当时我想把它抛出去,但是我又是遇到问题不能放的人。所以就找了一下原因。

Exception in thread "main" java.awt.IllegalComponentStateException: The frame is decorated
at java.awt.Frame.setOpacity(Unknown Source)
at java.awt.Window$1.setOpacity(Unknown Source)
at com.sun.awt.AWTUtilities.setWindowOpacity(Unknown Source)
at Opacity.<init>(Opacity.java:18)
at Opacity.main(Opacity.java:7)

最后我终于发现了错误的原因,原来是由于我写的窗体是可显示的所以抛出了这样一个异常。

之后我在我的源代码之上加了这么一句就好了。

this.setUndecorated(true);  // 禁用窗体装饰,加在前面就好了

关于这个函数我在 《JDK API 1.6.0中文版》查了一下,上面是这样说的。

/*setUndecorated
public void setUndecorated(boolean undecorated)禁用或启用此窗体的装饰。只有在窗体不可显示时才调用此方法。 

参数:
undecorated - 如果没有启用窗体装饰,则为 true;如果启用了窗体装饰,则为 false。 
抛出: 
IllegalComponentStateException - 如果窗体是可显示的。
从以下版本开始: 
1.4 
另请参见:
isUndecorated(), Component.isDisplayable(), JFrame.setDefaultLookAndFeelDecorated(boolean)*/

测试源码:

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class Opacity extends JFrame {
	public static void main(String[] args) {
		new Opacity();
	}
	Opacity() {
		this.setTitle("窗体透明化测试");
		
		JButton btn = new JButton();
		this.add(btn);
		double value = 0.4;
		// 判断是否支持透明度
		this.setUndecorated(true); // 禁用或启用此窗体的修饰。只有在窗体不可显示时
								   //才调用此方法。
		if (com.sun.awt.AWTUtilities.isWindowOpaque(this)) {
			com.sun.awt.AWTUtilities.setWindowOpacity(this, (float)(1 - value));
		} else {
			JOptionPane.showMessageDialog(this, "系统不支持 JDK版本过低或 JRE 系统库缺损");
		}
		
		this.setBounds(400,400,400,300);
		this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
		this.setVisible(true);
	}
}