2013-03-09 4 views
0

투명하게 JPanel을 만들려고 노력하고 있지만 제대로 작동하지 않습니다. 이것을 할 수 있습니까?투명한 배경을 그리는 방법?

import java.awt.*; 
import javax.swing.*; 

public class ClearPanel extends JPanel{ 
public static void main(String[] args) { 
    ClearPanel c = new ClearPanel(); 
    c.setPreferredSize(new Dimension(200, 200)); 
    c.setOpaque(false); 

    JPanel backPanel = new JPanel(); 
    backPanel.setBackground(Color.CYAN); 

    backPanel.add(c); 

    JFrame f = new JFrame(); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    f.setContentPane(backPanel); 
    f.pack(); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
} 

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    g.fillOval(0, 0, 200, 200); 
    g.clearRect(45, 45, 50, 50); 

    Graphics2D g2 = (Graphics2D) g; 
    g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.0f)); 
    g2.fillRect(75, 75, 50, 50); 
} 
} 

타원은 불투명해야하지만 직사각형은 투명해야합니다. 투명하게, 나는 ClearPanel 뒤에 패널을 볼 수 있어야한다는 것을 의미합니다.

MadProgrammer의 답변에서 벗어나 그 회색 상자를 영역 외부에 놓고 그 영역에있는 곳에 투명하게 유지할 수있는 방법이 있습니까?

@Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Rectangle fill = new Rectangle(getWidth(), getHeight()); 
     Graphics2D g2d = (Graphics2D) g.create(); 

     Rectangle hole = new Rectangle(0, 0, 100, 100); 

     Area area = new Area(fill); 
     area.subtract(new Area(hole)); 
     g2d.setColor(getBackground()); 
     g2d.fill(area); 

     g2d.setColor(Color.RED); 
     g2d.setComposite(AlphaComposite.SrcOver.derive(0.0f)); 
     g2d.fill(hole); 

     g2d.setComposite(AlphaComposite.SrcOver.derive(1.0f)); 
     g2d.setColor(Color.DARK_GRAY); 
     if(area.contains(0,0,100,200)) 
      g2d.fillRect(0, 0, 100, 200); 

     g2d.dispose();  
    } 
+0

'drawRect()'가 요구 사항을 충족시키지 못합니까? – uba

+0

Jubael을 통해 볼 수 없기 때문에 @uba no, 나는 rect가 그려지는 타원을 여전히 볼 수 있습니다. –

+0

* "투명하게 JPanel을 만들려고합니다."* 왜 응용 프로그램 기능을 제공합니까? 아마 그 기능을 달성하는 더 좋은 방법이 있기 때문에 묻습니다. –

답변

4

당신이 가진 문제는 기본적으로이다 JPanel는 다시 그리기가 그 아래에 아무것도 페인트되지 않습니다 것을 의미 불투명하다.

패널을 투명하게 설정 한 다음 배경 그림을 인계해야합니다.

이제 진짜 트릭이 시작됩니다. 단순히 구성 요소를 채우고 그 위에 투명 섹션을 페인팅하면 간단히 불투명 한 배경 위에 투명 섹션을 페인팅합니다 ...별로 도움이되지 않습니다.

해야 할 일은 투명하게 유지하려는 영역을 채우는 것이 아닙니다.

Area 모양을 사용하면이 모양을 추가/추가하고 제거 할 수 있습니다. 조금 이상 내가 기대했다

enter image description here

import java.awt.AlphaComposite; 
import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.geom.Area; 
import java.awt.geom.Ellipse2D; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TransparentPane { 

    public static void main(String[] args) { 
     new TransparentPane(); 
    } 

    public TransparentPane() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException ex) { 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 

       BackgroundPane backgroundPane = new BackgroundPane(); 
       backgroundPane.setBackground(Color.RED); 
       backgroundPane.setLayout(new BorderLayout()); 
       backgroundPane.add(new TranslucentPane()); 

       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(backgroundPane); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class BackgroundPane extends JPanel { 

     private BufferedImage bg; 

     public BackgroundPane() { 
      try { 
       bg = ImageIO.read(new File("/path/to/your/image.jpg")); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return bg == null ? super.getPreferredSize() : new Dimension(bg.getWidth(), bg.getHeight()); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (bg != null) { 
       int width = getWidth() - 1; 
       int height = getHeight() - 1; 
       int x = (width - bg.getWidth())/2; 
       int y = (height - bg.getHeight())/2; 
       g.drawImage(bg, x, y, this); 
      } 
     } 

    } 

    public class TranslucentPane extends JPanel { 

     public TranslucentPane() { 
      setOpaque(false); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Rectangle fill = new Rectangle(getWidth(), getHeight()); 
      Graphics2D g2d = (Graphics2D) g.create(); 

      int width = getWidth() - 1; 
      int height = getHeight() - 1; 
      int radius = Math.min(width, height)/2; 
      int x = (width - radius)/2; 
      int y = (height - radius)/2; 

      Ellipse2D hole = new Ellipse2D.Float(x, y, radius, radius); 

      Area area = new Area(fill); 
      area.subtract(new Area(hole)); 
      g2d.setColor(getBackground()); 
      g2d.fill(area); 

      g2d.setColor(Color.RED); 
      g2d.setComposite(AlphaComposite.SrcOver.derive(0.25f)); 
      g2d.fill(hole); 

      g2d.dispose(); 
     } 

    } 

} 

업데이트

음, ...

enter image description here

는 기본적으로, 우리의 마스크를 작성해야 우리가 표시하고자하는 사각형에서 구멍을 뺀 모양 표시 할 사각형에서 그 결과를 뺍니다.

import java.awt.AlphaComposite; 
import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.geom.Area; 
import java.awt.geom.Ellipse2D; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TransparentPane { 

    public static void main(String[] args) { 
     new TransparentPane(); 
    } 

    public TransparentPane() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException ex) { 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 

       BackgroundPane backgroundPane = new BackgroundPane(); 
       backgroundPane.setBackground(Color.RED); 
       backgroundPane.setLayout(new BorderLayout()); 
       backgroundPane.add(new TranslucentPane()); 

       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(backgroundPane); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class BackgroundPane extends JPanel { 

     private BufferedImage bg; 

     public BackgroundPane() { 
      try { 
       bg = ImageIO.read(new File("/Users/swhitehead/Dropbox/MegaTokyo/Evil_Small.jpg")); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return bg == null ? super.getPreferredSize() : new Dimension(bg.getWidth(), bg.getHeight()); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (bg != null) { 
       int width = getWidth() - 1; 
       int height = getHeight() - 1; 
       int x = (width - bg.getWidth())/2; 
       int y = (height - bg.getHeight())/2; 
       g.drawImage(bg, x, y, this); 
      } 
     } 

    } 

    public class TranslucentPane extends JPanel { 

     public TranslucentPane() { 
      setOpaque(false); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Rectangle fill = new Rectangle(getWidth(), getHeight()); 
      Graphics2D g2d = (Graphics2D) g.create(); 

      int width = getWidth() - 1; 
      int height = getHeight() - 1; 
      int radius = Math.min(width, height)/2; 
      int x = (width - radius)/2; 
      int y = (height - radius)/2; 

      Ellipse2D hole = new Ellipse2D.Float(x, y, radius, radius); 

      Area area = new Area(fill); 
      area.subtract(new Area(hole)); 
      g2d.setColor(getBackground()); 
      g2d.fill(area); 

      g2d.setColor(Color.RED); 
      g2d.setComposite(AlphaComposite.SrcOver.derive(0.0f)); 
      g2d.fill(hole); 
      g2d.dispose(); 

      g2d = (Graphics2D) g.create(); 

      // Basically, we create an area that is subtraction of the window/rectangle 
      // from the whole. This leaves us with a rectangle (with a hole in it) 
      // that doesn't include the area where the whole is... 
      Rectangle win = new Rectangle(
          x + (radius/2), 
          y + (radius/2), radius, (radius/4)); 
      area = new Area(win); 
      area.subtract(new Area(hole)); 

      // Then we create a area that is a subtraction of the original rectangle 
      // from the one with a "hole" in it... 
      Area actual = new Area(win); 
      actual.subtract(area); 
      g2d.setColor(Color.BLUE); 
      g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f)); 
      g2d.fill(actual); 

      g2d.dispose(); 
     }   
    } 
} 
+0

답변을 주셔서 감사합니다. 제 질문을 업데이트하고 싶습니다. 다시 한번 감사드립니다. –

+0

AlphaComposite 유형을 변경하십시오. 당신은 또한 겹치는 사각형의 영역으로 시작하여 투명 부분을 뺀 다음 이것을 불투명으로 채운 다음 동일한 영역으로 시작하여 투명 영역 바깥 부분을 빼서 ​​그 부분을 채울 수 있습니다. – MadProgrammer

+0

업데이트 확인 ... – MadProgrammer

관련 문제