2017-02-13 101 views
0

我已经创建JFrame,设置透明颜色(新颜色(0,0,0,0))作为背景并放置JPanel。我重写了JPanel的paintComponent方法,并在其上绘制了一些带有alpha通道的图像。此外,当用户右键单击我的JPanel时,我会弹出菜单。透明JFrame问题

而我面临的事实是,弹出菜单的图像在应该消失之后仍保留在JFrame上(现在JPanel的图片覆盖了它)。据我了解,在绘制新框架之前,JFrame不会被清除。

public class MainWindow extends JFrame { 

    private MyPanel widget = new MyPanel(); 
    private Action quitAction = new AbstractAction("Quit") { 
     @Override 
     public void actionPerformed(ActionEvent actionEvent) { 
      setVisible(false); 
      dispose(); 
     } 
    }; 

    private MainWindow() { 
     super(); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setUndecorated(true); 
     setBackground(new Color(0, 0, 0, 0)); 
     widget.loadImage("image.png"); 
     setContentPane(widget); 
     pack(); 
     setAlwaysOnTop(true); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(() -> { 
      MainWindow window = new MainWindow(); 
      window.setVisible(true); 
     }); 
    } 

    class MyPanel extends JPanel implements MouseListener { 
     BufferedImage image; 

     MyPanel() { 
      super(); 
      addMouseListener(this); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintCompontent(g); 
      if (characterImage != null) { 
       g.drawImage(characterImage, 0, 0, this); 
      } 
     } 

     @Override 
     public void mouseClicked(MouseEvent e) { 
     } 

     @Override 
     public void mousePressed(MouseEvent e) { 
      clickPos = e.getLocationOnScreen(); 
      if (SwingUtilities.isRightMouseButton(e)) { 
       JPopupMenu popupMenu = new JPopupMenu(); 
       popupMenu.add(quitAction); 
       popupMenu.show(this, e.getX(), e.getY()); 
      } 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
     } 

     @Override 
     public void mouseEntered(MouseEvent e) { 
     } 

     @Override 
     public void mouseExited(MouseEvent e) { 
     } 

     boolean loadImage(String name) { 
      BufferedImage backupImage = image; 
      try { 
       image = ImageIO.read(MainWindow.class.getResourceAsStream("/images/" + name)); 
       setPreferredSize(new Dimension(image.getWidth(), image.getHeight())); 
      } catch (IOException ex) { 
       image = backupImage; 
       return false; 
      } 
      return true; 
     } 

    } 

} 
+0

你也忘了提供一个[可运行示例](https://stackoverflow.com/help/mcve),它演示了你的问题。这不是代码转储,而是您正在做的事情的一个例子,它突出了您遇到的问题。这将导致更少的混淆和更好的反应 – MadProgrammer

+0

我“猜测”,要么你没有调用'super.paintComponent'和/或你使用基于alpha的颜色来设置面板的背景 – MadProgrammer

+0

*“据我所知,在绘制新框架之前,JFrame不会被清除。“* - 只有当您遵守绘画链并确定何时重写任何绘画方法时,您才会调用其超级方法(并且不要尝试将基于Alpha的颜色应用于一个不透明的面板) – MadProgrammer

回答

1

所以,在你的代码松散的基础,一旦我纠正它的工作,我似乎没有什么问题

Transparent Popup Menu

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.AbstractAction; 
import javax.swing.Action; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JPopupMenu; 
import javax.swing.SwingUtilities; 

public class MainWindow extends JFrame { 

    private MyPanel widget = new MyPanel(); 
    private Action quitAction = new AbstractAction("Quit") { 
     @Override 
     public void actionPerformed(ActionEvent actionEvent) { 
      setVisible(false); 
      dispose(); 
     } 
    }; 

    private MainWindow() { 
     super(); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setUndecorated(true); 
     setBackground(new Color(0, 0, 0, 0)); 
     widget.loadImage("MT.png"); 
     setContentPane(widget); 
     pack(); 
     setLocationRelativeTo(null); 
     setAlwaysOnTop(true); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(() -> { 
      MainWindow window = new MainWindow(); 
      window.setVisible(true); 
     }); 
    } 

    class MyPanel extends JPanel implements MouseListener { 

     BufferedImage image; 

     MyPanel() { 
      super(); 
      addMouseListener(this); 
      setOpaque(false); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      g.setColor(Color.RED); 
      g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); 
      if (image != null) { 
       g.drawImage(image, 0, 0, this); 
      } 
     } 

     @Override 
     public void mouseClicked(MouseEvent e) { 
     } 

     @Override 
     public void mousePressed(MouseEvent e) { 
//   clickPos = e.getLocationOnScreen(); 
      if (SwingUtilities.isRightMouseButton(e)) { 
       JPopupMenu popupMenu = new JPopupMenu(); 
       popupMenu.add(quitAction); 
       popupMenu.show(this, e.getX(), e.getY()); 
      } 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
     } 

     @Override 
     public void mouseEntered(MouseEvent e) { 
     } 

     @Override 
     public void mouseExited(MouseEvent e) { 
     } 

     boolean loadImage(String name) { 
      BufferedImage backupImage = image; 
      try { 
       image = ImageIO.read(MainWindow.class.getResourceAsStream("/images/" + name)); 
       setPreferredSize(new Dimension(image.getWidth(), image.getHeight())); 
      } catch (IOException ex) { 
       image = backupImage; 
       return false; 
      } 
      return true; 
     } 

    } 

} 
+0

嗯...我检查了我的代码在Windows 10下,它工作正常。据我所知,您使用Mac OS。看来问题似乎并不总是,但只有在某些条件下。在我的情况下,它是Linux + Gnome 3.但我找到了一个解决方案。 –

0

我在我的代码中发现了问题。为了一切正常工作,我需要在使用paintCompontent中的g.drawImage在图片绘制之前插入此代码。

if (g instanceof Graphics2D) { 
    Graphics2D g2d = (Graphics2D)g; 
    g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC)); 
} 

此外,问题并非在所有情况下都出现。例如,在Windows下它运行得很好。