我尝试从PNG图片构建我的个人JFrame。但是Mac OSX 10.8和Windows7的行为不同(我必须使用JDK 6)。
下面是我的代码:
[...]
public Fenetre()
{
    this.setLocationRelativeTo(null);
    this.setUndecorated(true);
    this.setBackground(new Color(0,0,0,0));
    try {
        image = ImageIO.read(this.getClass().getResource("/Images/frame.png"));     
    } catch (IOException e) {
        e.printStackTrace();
    }
    this.setSize(image.getWidth(),image.getHeight());                
    this.setLayout(null);
    panel = new JPanel();
    JButton quit = new JButton("Quitter");
    panel.add(quit);
    Dimension size = panel.getPreferredSize();
    panel.setBounds(67, 45, size.width, size.height);
    this.add(panel);
    this.addMouseListener(this);
    this.addMouseMotionListener(this);
    this.setVisible(true);      
}
public void paint(Graphics g) {
    Graphics2D g2 =(Graphics2D) g;
    g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC)); // SRC_ATOP > Windows
    g2.drawImage(image, 0, 0, this);
    panel.update(panel.getGraphics());
}
[...]在MacOSX10.8上的结果(AlphaComposite = SRC):
http://imageshack.us/photo/my-images/15/maczr.png/
然后,在Windows7 (AlphaComposite = SRC_ATOP)上,在启动和移动它时,我可以看到:
http://imageshack.us/photo/my-images/16/windowsqu.jpg/
如何做到这一点?
发布于 2013-02-04 08:28:16
你不尊重颜料链
public void paint(Graphics g) {
    // You must call super.paint somewhere here...
    Graphics2D g2 =(Graphics2D) g;
    g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC)); // SRC_ATOP > Windows
    g2.drawImage(image, 0, 0, this);
    panel.update(panel.getGraphics());
}您永远不应该调用Component#update。
    panel.update(panel.getGraphics());这是由重绘管理器代表您调用的,该管理器调用paint。
paint调用paintComponent、paintBorder和paintChildren失败意味着这些方法都没有被调用,而且它们非常重要
正如camickr所指出的,你永远不需要重写像JFrame这样的顶级容器的paint方法。
相反,创建一个能够为您执行绘制的自定义组件,并将其设置为框架内容窗格……
this.setLocationRelativeTo(null);
this.setUndecorated(true);
this.setBackground(new Color(0,0,0,0));
setContentPane(new FancyPaintPane());
pack();和FancyPaintPane
public class FancyPaintPane extends JPanel {
    private BufferedImage image;
    public FancyPaintPane() {
        try {
            image = ImageIO.read(this.getClass().getResource("/Images/frame.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        setOpaque(false);
    }
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(image.getWidth(), image.getHeight());
    }
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC)); // SRC_ATOP > Windows
        g2.drawImage(image, 0, 0, this);
        g2.dispose();
    }
}您也不应该在不恢复Graphics上下文的情况下对其进行修改。这些是同一顶层容器中所有组件之间的共享资源。更好的方法是创建一个副本,您可以在完成后对其进行操作和处理。
您还试图显示具有透明元素的组件,而不首先将该组件标记为透明。这可能会产生令人讨厌的绘画伪影。您应该调用向其传递false值的JComponent#setOpaque。
我也强烈建议您不要使用null布局。它们有一个坏习惯,就是回来咬你。
使用简单的示例更新了

public class CirclePaneTest {
    public static void main(String[] args) {
        new CirclePaneTest();
    }
    public CirclePaneTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }
                CirclePane circlePane = new CirclePane();
                circlePane.setLayout(new BorderLayout());
                circlePane.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        if (e.getClickCount() == 2) {
                            System.exit(0);
                        }
                    }
                });
                JLabel label = new JLabel("Look Ma, I'm a circle");
                label.setHorizontalAlignment(JLabel.CENTER);
                label.setVerticalAlignment(JLabel.CENTER);
                JFrame frame = new JFrame("Test");
                frame.setUndecorated(true);
                frame.setBackground(new Color(0, 0, 0, 0));
                frame.setContentPane(circlePane);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(label);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
    public class CirclePane extends JPanel {
        public CirclePane() {
            setOpaque(false);
        }
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
        protected int getRadius() {
            return Math.min(getWidth(), getHeight()) - 1;
        }
        @Override
        public Insets getInsets() {
            int radius = getRadius();
            int xOffset = (getWidth() - radius) / 2;
            int yOffset = (getHeight() - radius) / 2;
            Insets insets = new Insets(
                    radius / 6,
                    radius / 6,
                    radius / 6,
                    radius / 6);
            return insets;
        }
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int radius = getRadius();
            int xOffset = (getWidth() - radius) / 2;
            int yOffset = (getHeight() - radius) / 2;
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(getBackground());
            g2d.fillOval(xOffset, yOffset, radius, radius);
            g2d.setColor(Color.GRAY);
            g2d.drawOval(xOffset, yOffset, radius, radius);
            g2d.dispose();
        }
    }
}使用Java7的代码更新了
应使用以下代码将框架设置为在Java6下是透明的。
JFrame frame = new JFrame("Test");
frame.setAlwaysOnTop(true);
frame.setUndecorated(true);
try {
    Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
    if (awtUtilsClass != null) {
        Method method = awtUtilsClass.getMethod("setWindowOpaque", Window.class, boolean.class);
        method.invoke(null, frame, false);
    }
} catch (Exception exp) {
}
//frame.setBackground(new Color(0, 0, 0, 0));
frame.setContentPane(circlePane);发布于 2013-02-04 08:15:30
您的代码不完整,但在我看来,您似乎覆盖了JFrame的paint()方法。您永远不应该这样做(除非您知道自己在做什么并且调用了super.paint(..))!
如果要在帧中显示图像,请执行以下任一操作:
a)将带有图片的JLabel添加到框架中
b)或者通过重写paintComponent()方法在JPanel上进行自定义绘制,然后将面板添加到框架中。
https://stackoverflow.com/questions/14678831
复制相似问题