2017-04-04 72 views
1

我正在处理覆盖JPanel但我有一个小问题,覆盖层的透明度直接看到JFrameJLayeredPane中缺少JPanel

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JLayeredPane; 
import javax.swing.JPanel; 

@SuppressWarnings("serial") 
public class GUI extends JFrame { 
    private GUI() { 
     super("Recorder Part"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     setLayout(new BorderLayout()); 
     JLayeredPane layers = new Overlay(); 
     add(layers); 

     pack(); 

     getContentPane().setBackground(Color.GREEN); 
     setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(() -> new GUI()); 
    } 

    private class Overlay extends JLayeredPane { 
     JPanel base; 
     JPanel overlay; 

     private Overlay() { 
      setPreferredSize(new Dimension(800, 100)); 

      createBase(); 
      createOverlay(); 

      add(base, new Integer(0)); 
      add(overlay, new Integer(1)); 
     } 


     private void createBase() { 
      base = new JPanel(); 
      base.setPreferredSize(new Dimension(800, 100)); 
      base.setBounds(0, 0, 800, 100); 
      base.setBackground(Color.BLUE); 
      base.setOpaque(true); 

      base.add(new JLabel("Hello")); 
     } 

     private void createOverlay() { 
      overlay = new JPanel(); 
      overlay.setPreferredSize(new Dimension(800, 100)); 
      overlay.setBounds(0, 0, 800, 100); 
      overlay.setBackground(new Color(255, 0, 0, 0)); 
     } 
    } 
} 

我怎样才能解决这个问题,这样,当所谓的overlayJPanel透明,叫baseJpanel可以看出,而不是JFrame


编辑

我发现,当覆盖板具有一个尺寸大于或等于所述基板的尺寸仅发生此问题。这可以通过在此示例中调整帧的大小来看到。

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ComponentAdapter; 
import java.awt.event.ComponentEvent; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JLayeredPane; 
import javax.swing.JPanel; 

@SuppressWarnings("serial") 
public class GUI extends JFrame { 
    private GUI() { 
     super("Recorder Part"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     setLayout(new BorderLayout()); 
     JLayeredPane layers = new Overlay(); 
     add(layers); 

     pack(); 

     getContentPane().setBackground(Color.GREEN); 
     setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(() -> new GUI()); 
    } 

    private class Overlay extends JLayeredPane { 
     JPanel base; 
     JPanel overlay; 

     private Overlay() { 
      addComponentListener(new Resize()); 
      setPreferredSize(new Dimension(800, 100)); 

      createBase(); 
      createOverlay(); 

      add(base, new Integer(0)); 
      add(overlay, new Integer(1)); 
     } 


     private void createBase() { 
      base = new JPanel(); 
      base.setLocation(0, 0); 
      base.setBackground(Color.BLUE); 
      base.setOpaque(true); 

      base.add(new JLabel("Hello")); 
     } 

     private void createOverlay() { 
      overlay = new JPanel(); 
      overlay.setLocation(0, 0); 
      overlay.setSize(new Dimension(800, 100)); 
      overlay.setBackground(new Color(255, 0, 0, 128)); 
     } 

     private class Resize extends ComponentAdapter { 
      @Override 
      public void componentResized(ComponentEvent e) { 
       System.out.println("Resized"); 
       base.setSize(new Dimension(getParent().getWidth(), getParent().getHeight())); 
      } 
     } 
    } 
} 

这是不可取的,因为覆盖面板需要与基础面板完全相同的尺寸。我将不胜感激任何帮助。

+1

你快一分钟... –

回答

1

我有感觉这是一个错误。改变边界,因此不会完全重叠基邻看看会发生什么:

overlay.setBounds(0, 0, 799, 100); // or (1, 0, 800, 100) 

可能某种优化,如忽略了一个组件,如果它是由另一个组件被完全掩盖,但不考虑透明度该优化[: - |

编辑

是明确的问题 - JComponent中的paintChildren做某种优化的基于儿童被完全被其他孩子模糊。

我发现了两个解决方案,第一种可能是正确的单叠加设置为非不透明:

overlay.setOpaque(false); 

这具有背景色不被使用在所有的缺点。

二是多workarround - 做出的JLayeredPane为optimizedDrawingEnabled返回true,这将做停止的JComponent:

private class Overlay extends JLayeredPane { 

    /// ... 

    @Override 
    public boolean isOptimizedDrawingEnabled() { 
     return true; 
    } 
} 

,但不知道什么可以停止这样做的工作,所以我宁愿先解决!

+0

我刚刚注意到了这一点。我在编辑中注意到了它。我目前正在使用这个,但希望有人回答一个方法 – Dan

+1

@丹我发现了,看到我编辑的答案 –

+0

谢谢你的帮助。我使用第二个,因为它仍然允许我有一个透明的背景颜色。这很棒 :) – Dan