2010-03-30 36 views
21

Nền JPanel có thể được đặt thành trong suốt không?Làm thế nào để thiết lập một nền trong suốt của JPanel?

khung của tôi là có hai JPanel s:

  • Hình ảnh Bảng điều chỉnh
  • Tính năng Bảng điều chỉnh.

Tính năng Bảng điều chỉnh là chồng chéo Hình ảnh Bảng điều chỉnh. Bảng điều khiển hình ảnh đang hoạt động ở chế độ nền và tải hình ảnh từ một URL từ xa.

Trên Bảng tính năng Tôi muốn vẽ hình dạng. Bây giờ Bảng điều khiển hình ảnh không thể xem được do Màu nền của màn hình chính là.

tôi cần phải thực hiện Tính năng Bảng điều chỉnh nền trong suốt trong khi vẫn vẽ hình dạng của nó và tôi muốn Hình ảnh Bảng điều chỉnh để được nhìn thấy (vì nó đang làm ốp lát và bộ nhớ cache chức năng của hình ảnh).

Tôi đang sử dụng hai JPanel vì tôi cần phải tách riêng hình ảnh và hình dạng bản vẽ.

Có cách nào Jpanel trùng lặp có nền trong suốt không?

+0

JPanel khi ảnh PNG trong suốt được tải và đặt 'JPanel.setOpaque (false);' nó sẽ sử dụng phương thức minh bạch hình ảnh, nếu không nó sẽ hiển thị hình ảnh không trong suốt. – YumYumYum

Trả lời

6

Ngoài ra, hãy xem xét The Glass Pane, thảo luận trong bài viết How to Use Root Panes. Bạn có thể vẽ nội dung "Tính năng" trong phương thức paintComponent() của khung kính.

Phụ Lục: Làm việc với GlassPaneDemo, tôi đã thêm một hình ảnh:

/* Set up the content pane, where the "main GUI" lives. */ 
frame.add(changeButton, BorderLayout.SOUTH); 
frame.add(new JLabel(new ImageIcon("img.jpg")), BorderLayout.CENTER); 

và thay đổi paintComponent() phương pháp khung kính của:

protected void paintComponent(Graphics g) { 
    if (point != null) { 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setRenderingHint(
      RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.setComposite(AlphaComposite.getInstance(
      AlphaComposite.SRC_OVER, 0.3f)); 
     g2d.setColor(Color.yellow); 
     g2d.fillOval(point.x, point.y, 120, 60); 
    } 
} 

image http://i41.tinypic.com/2j0mlv9.png

+2

Sử dụng kính không hoạt động (chính xác) mà không cần setOpaque() (như được mô tả trong bài đăng của tôi) hoạt động. – Nate

24

Gọi setOpaque(false) ở phía trên JPanel sẽ hoạt động.

Từ nhận xét của bạn, có vẻ như bức tranh Swing có thể bị hỏng ở đâu đó -

đầu tiên - có thể bạn muốn ghi đè paintComponent() hơn paint() trong bất cứ thành phần bạn có paint() ghi đè trong

Thứ hai -. Khi bạn ghi đè paintComponent(), trước tiên bạn sẽ muốn gọi super.paintComponent() trước tiên để làm tất cả các công cụ vẽ tranh Swing mặc định (trong đó tôn vinh setOpaque() là một).

Ví dụ -

import java.awt.Color; 
import java.awt.Graphics; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 


public class TwoPanels { 
    public static void main(String[] args) { 

     JPanel p = new JPanel(); 
     // setting layout to null so we can make panels overlap 
     p.setLayout(null); 

     CirclePanel topPanel = new CirclePanel(); 
     // drawing should be in blue 
     topPanel.setForeground(Color.blue); 
     // background should be black, except it's not opaque, so 
     // background will not be drawn 
     topPanel.setBackground(Color.black); 
     // set opaque to false - background not drawn 
     topPanel.setOpaque(false); 
     topPanel.setBounds(50, 50, 100, 100); 
     // add topPanel - components paint in order added, 
     // so add topPanel first 
     p.add(topPanel); 

     CirclePanel bottomPanel = new CirclePanel(); 
     // drawing in green 
     bottomPanel.setForeground(Color.green); 
     // background in cyan 
     bottomPanel.setBackground(Color.cyan); 
     // and it will show this time, because opaque is true 
     bottomPanel.setOpaque(true); 
     bottomPanel.setBounds(30, 30, 100, 100); 
     // add bottomPanel last... 
     p.add(bottomPanel); 

     // frame handling code... 
     JFrame f = new JFrame("Two Panels"); 
     f.setContentPane(p); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setSize(300, 300); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    // Panel with a circle drawn on it. 
    private static class CirclePanel extends JPanel { 

     // This is Swing, so override paint*Component* - not paint 
     protected void paintComponent(Graphics g) { 
      // call super.paintComponent to get default Swing 
      // painting behavior (opaque honored, etc.) 
      super.paintComponent(g); 
      int x = 10; 
      int y = 10; 
      int width = getWidth() - 20; 
      int height = getHeight() - 20; 
      g.drawArc(x, y, width, height, 0, 360); 
     } 
    } 
} 
+0

Tôi đã làm, nhưng nó không hoạt động, tôi nên gọi hàm này trong hàm tạo hoặc trong phương thức paint()? – Imran

+0

@Imran - Trong hàm tạo hoặc trong phương thức paint() của cái gì? Bảng điều khiển chính nó? xem câu trả lời cập nhật ... – Nate

+0

Được rồi, cảm ơn Nate, điều đó đã hiệu quả. trước khi gọi super.paint() tôi đặt Opaque thành false và sau đó trước khi vẽ hình của mình, tôi đặt Opaque là true. cảm ơn buddy – Imran

2
public void paintComponent (Graphics g) 
    { 
((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.0f)); // draw transparent background 
    super.paintComponent(g); 
    ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,1.0f)); // turn on opacity 
    g.setColor(Color.RED); 
    g.fillRect(20, 20, 500, 300); 
    } 

tôi đã cố gắng làm theo cách này, nhưng nó rất dễ vỡ

4
(Feature Panel).setOpaque(false); 

Hy vọng điều này sẽ hữu ích.

5

Trong trường hợp đặc biệt của tôi nó là dễ dàng hơn để làm điều này:

panel.setOpaque(true); 
panel.setBackground(new Color(0,0,0,0,)): // any color with alpha 0 (in this case the color is black 
+0

không hợp lệ - với độ mờ là đúng, bảng điều khiển đảm bảo việc lấp đầy nền hoàn toàn (không có nền trong suốt) – kleopatra

+0

điều bạn nói là đúng, nhưng với mục đích thiết kế mong muốn, đặt bất kỳ màu nào với alpha 0 sẽ để xóa công việc, bên cạnh đó anh ta không được chỉ định nếu anh ta cần có quyền truy cập vào các thành phần của bảng điều khiển nền, vì tôi hiểu bảng điều khiển ở cấp thấp hơn chỉ là đặt hình nền. – Ordiel

0

Như Thrasgod cho thấy một cách chính xác trong câu trả lời của mình, cách tốt nhất là sử dụng paintComponent, mà còn nếu trường hợp là phải có một nửa trong suốt JPanel (hoặc bất kỳ thành phần nào khác, thực sự) và có cái gì đó không minh bạch bên trong. Bạn còn phải ghi đè lên các phương pháp paintChildren và thiết lập giá trị alfa để 1. Trong trường hợp của tôi, tôi mở rộng JPanel như thế:

public class TransparentJPanel extends JPanel { 

private float panelAlfa; 
private float childrenAlfa; 

public TransparentJPanel(float panelAlfa, float childrenAlfa) { 
    this.panelAlfa = panelAlfa; 
    this.childrenAlfa = childrenAlfa; 
} 

@Override 
public void paintComponent(Graphics g) { 
    Graphics2D g2d = (Graphics2D) g; 
    g2d.setColor(getBackground()); 
    g2d.setRenderingHint(
      RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
    g2d.setComposite(AlphaComposite.getInstance(
      AlphaComposite.SRC_OVER, panelAlfa)); 
    super.paintComponent(g2d); 

} 

@Override 
protected void paintChildren(Graphics g) { 
    Graphics2D g2d = (Graphics2D) g; 
    g2d.setColor(getBackground()); 
    g2d.setRenderingHint(
      RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
    g2d.setComposite(AlphaComposite.getInstance(
      AlphaComposite.SRC_ATOP, childrenAlfa)); 

    super.paintChildren(g); 
} 
//getter and setter 
} 

Và trong dự án của tôi, tôi chỉ cần phải nhanh chóng Jpanel jp = new TransparentJPanel(0.3f, 1.0f);, nếu tôi muốn chỉ Jpanel trong suốt. Bạn cũng có thể làm rối tung hình dạng JPanel bằng cách sử dụng g2d.fillRoundRectg2d.drawRoundRect nhưng không nằm trong phạm vi của câu hỏi này.

Các vấn đề liên quan