setBackgrounds在Windows中抛出异常(但不在MacOSX中)

时间:2012-10-05 11:24:43

标签: java swing cross-platform

我试图拥有图像背景,因此我在JFrame中创建了以下代码:

@Override
public void paint(Graphics g) {
    super.paint(g);
    try {
        final Image image = ImageIO.read(getClass().getResource("/images/login/gentlenoise100.png"));
        int iw = 256;
        int ih = 256;
        for (int x = 0; x < getWidth(); x += iw) {
            for (int y = 0; y < getHeight(); y += ih) {
                g.drawImage(image, x, y, iw, ih, this);
            }
        }
    } catch (IOException ex) {
        Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
    }
    for(Component componente:getComponents()){
        componente.repaint();
    }

}

我看到背景颜色有某种偏好,我决定把它设置为隐形:

setBackground(new java.awt.Color(0,0,0,0));

它在Mac OS X(java 1.6)中工作得很好,我不得不在Windows中探测它,如果我删除了setBackground调用它没有显示我的背景,如果我保持背景颜色不可见它会抛出异常并说框架装饰好了!

我尝试使用setUndecorate(true)但是在macosx中它会丢失标题栏(当然),在Windows中它给了我一个透明的窗口。

我该如何解决?

2 个答案:

答案 0 :(得分:1)

使用

有三种方法
  1. JComponent#setOpaque()如果您不想喘气背景

  2. How to Create Translucent and Shaped Windows在Win,OSX上有几个*** unix

  3. Transparency have to change value of AlphaComposite


  4. 不要paint()JFrame投放JPanel并覆盖paintComponent()

答案 1 :(得分:1)

如果你可以避免它,不要覆盖顶级容器的paint方法(如JFrame),它们可以用于许多重要的事情。

在这种情况下,您最好使用JPanel并将帧内容窗格设置为它...

像...一样的东西。

public class BackgroundPane extends JPanel {

    private Image background;
    public BackgroundPane() {
        try {
            background = ImageIO.read(getClass().getResource("/images/login/gentlenoise100.png"));
        } catch (IOException ex) {
            Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        int iw = 256;
        int ih = 256;
        for (int x = 0; x < getWidth(); x += iw) {
            for (int y = 0; y < getHeight(); y += ih) {
                g.drawImage(background, x, y, iw, ih, this);
            }
        }
    }
}

//...

JFrame frame = new JFrame();
frame.setContentPane(new BackgroundPane());
//...

不要在paint方法中做任何耗时或可能导致重绘管理器安排组件再次重​​新绘制的内容

像......这样的事情。

final Image image = ImageIO.read(getClass().getResource("/images/login/gentlenoise100.png"));

for(Component componente:getComponents()){
    componente.repaint();
}

在你内部绘画方法是一个非常糟糕的主意。

第二个可能导致重绘管理器决定父容器(你的框架)需要重新绘制,反复重复,最终消耗你的CPU ......

请注意,从Java 7开始,使用setBackground上包含小于255的alpha值的颜色调用Window将导致窗口变为透明。

  

Window.setBackground(Color)将新Color(0,0,0,alpha)传递给此   方法,其中alpha小于255,安装每像素半透明

如果窗口被装饰,这也会抛出异常......