【发布时间】:2015-02-08 13:59:09
【问题描述】:
我在 Swing 中使用透明背景时遇到问题。 由于 Swing 没有重新绘制更改的区域,因此产生了很多人工制品。
据我所知,有两种开箱即用的方式来使用透明背景:
- 将透明颜色设置为背景的不透明组件(左侧 txt 字段)
问题:背景的透明部分永远不会刷新 -> 人工制品。
- 将透明颜色设置为背景的非透明组件(右侧 txt 字段)
问题:根本没有绘制背景。
我不想想做的事:
- 使用计时器自动重绘框架(超级糟糕)
- 重写paintComponent 方法(它确实有效,但真的很糟糕)
我在 Win7 x64 上运行
这是我的 SSCCEEE:
更新 1:使用 invokeLater 初始化(仍然无法使用)
public class OpacityBug {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new OpacityBug();
}
});
}
static final Color transparentBlue = new Color(0f, 1f, 0f, 0.5f);
JFrame frame;
JPanel content;
JTextField txt1;
JTextField txt2;
public OpacityBug() {
initFrame();
initContent();
}
void initFrame() {
frame = new JFrame();
frame.setSize(300, 80);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
void initContent() {
content = new JPanel();
content.setDoubleBuffered(true);
content.setBackground(Color.red);
frame.getContentPane().add(content);
txt1 = new JTextField() {
@Override
public void setBorder(Border border) {
super.setBorder(null); //nope border
}
};
txt1.setText("Hi! I am Buggy!");
txt1.setOpaque(true);
txt1.setBackground(transparentBlue);
content.add(txt1);
txt2 = new JTextField() {
@Override
public void setBorder(Border border) {
super.setBorder(null); //nope border
}
};
txt2.setText("And I have no BG!");
txt2.setOpaque(false);
txt2.setBackground(transparentBlue);
content.add(txt2);
content.revalidate();
content.repaint();
}
}
更新 2
正如你们中的一些人所注意到的,Swing 似乎无法绘制透明背景。 但是我还不清楚为什么,我搜索了负责绘制组件背景的代码,并在 ComponentUI.java 中找到了以下代码:
public void update(Graphics g, JComponent c) {
if (c.isOpaque()) {
g.setColor(c.getBackground());
g.fillRect(0, 0, c.getWidth(),c.getHeight());
}
paint(g, c);
}
如您所见,它假定如果组件不是不透明的,则不需要重新绘制背景。我说这是一个非常模糊的假设。
我会建议以下实现:
public void update(Graphics g, JComponent c) {
if(c.isOpaque() || (!c.isOpaque() && c.isBackgroundSet())) {
g.setColor(c.getBackground());
g.fillRect(0, 0, c.getWidth(), c.getHeight());
}
paint(g, c);
}
当组件不透明时,我只是检查是否设置了背景。 这个简单的添加将允许我们在摇摆中使用透明背景。 至少我不知道为什么不应该这样做。
【问题讨论】:
标签: java swing transparency repaint