2012-07-02 24 views
5

köşeleri yuvarlatılmış Jpanel bir arka plan resmi ekleme. Bu benim patronlarımın bileşenleri üzerinde gölgelenme ve yuvarlatılmış köşeler gerektirme biçimidir. Birçok çevrimiçi örnekte gösterildiği gibi gerçekleştirildi. Böyle yaptım: Aşağıdaki kod ile bir test çerçevesi oluşturmaSadece son zamanlarda daha "3D" olarak görünmesini istediğiniz bir projede kullanılmak üzere Jpanel uzattığımızı

public class RoundedPanel extends JPanel 
{ 
    protected int _strokeSize = 1; 
    protected Color _shadowColor = Color.BLACK; 
    protected boolean _shadowed = true; 
    protected boolean _highQuality = true; 
    protected Dimension _arcs = new Dimension(30, 30); 
    protected int _shadowGap = 5; 
    protected int _shadowOffset = 4; 
    protected int _shadowAlpha = 150; 

    protected Color _backgroundColor = Color.LIGHT_GRAY; 

    public RoundedPanel() 
    { 
     super(); 
     setOpaque(false); 
    } 

    @Override 
    public void setBackground(Color c) 
    { 
     _backgroundColor = c; 
    } 

    @Override 
    protected void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 

     int width = getWidth(); 
     int height = getHeight(); 
     int shadowGap = this._shadowGap; 
     Color shadowColorA = new Color(_shadowColor.getRed(), _shadowColor.getGreen(), _shadowColor.getBlue(), _shadowAlpha); 
     Graphics2D graphics = (Graphics2D) g; 

     if(_highQuality) 
     { 
      graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     } 

     if(_shadowed) 
     { 
      graphics.setColor(shadowColorA); 
      graphics.fillRoundRect(_shadowOffset, _shadowOffset, width - _strokeSize - _shadowOffset, 
        height - _strokeSize - _shadowOffset, _arcs.width, _arcs.height); 
     } 
     else 
     { 
      _shadowGap = 1; 
     } 

     graphics.setColor(_backgroundColor); 
     graphics.fillRoundRect(0, 0, width - shadowGap, height - shadowGap, _arcs.width, _arcs.height); 
     graphics.setStroke(new BasicStroke(_strokeSize)); 
     graphics.setColor(getForeground()); 
     graphics.drawRoundRect(0, 0, width - shadowGap, height - shadowGap, _arcs.width, _arcs.height); 
     graphics.setStroke(new BasicStroke()); 
    } 
} 

:

public class UITest 
{ 
    private static JFrame mainFrame; 
    private static ImagePanel mainPanel; 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       mainFrame = new JFrame(); 
       mainFrame.setVisible(true); 

       try 
       { 
        mainPanel = new ImagePanel(ImageIO.read(this.getClass().getResource("/content/diamondPlate_Light.jpg"))); 
        //mainPanel.setBounds(0, 0, 800, 600); 
       } 
       catch(IOException e) 
       { 

       } 
       mainPanel.setLayout(null); 

       RoundedPanel rPanel = new RoundedPanel(); 
       rPanel.setBounds(10, 10, 200, 200); 
       rPanel.setBackground(new Color(168, 181, 224)); 

       mainPanel.add(rPanel); 

       rPanel = new RoundedPanel(); 
       rPanel.setBounds(220, 10, 560, 200); 
       rPanel.setBackground(new Color(168, 224, 168)); 

       mainPanel.add(rPanel); 

       rPanel = new RoundedPanel(); 
       rPanel.setBounds(10, 220, 770, 300); 
       rPanel.setBackground(new Color(224, 168, 168)); 

       mainPanel.add(rPanel); 

       mainFrame.setSize(800, 600); 
       mainFrame.getContentPane().add(mainPanel); 
      } 
     }); 
    } 
} 

Ve bu (sans arka plan görüntüsünü sonuçlanan JFrame 'ın contentPane:

Panels

Gerçekten yapmak istediğim, yuvarlatılmış köşeleri olan kırmızı, yeşil ve mavi panelleri oluşturmaktır, ancak Color yerine farklı bir resim. Hala düzgün bir şekilde yuvarlanmış köşeleri istiyorum, ama bunu nasıl yapacağımdan emin değilim. Büyük bir doku var ise

, can ben sadece "klip" RoundedPanel boyutuna ve şekline bir o parça dışarı? Bunu sadece ben daktilo olarak aklıma beri, bu değerlendirmek gerekiyor ama görüntü klibi ardından graphics.fillRoundRect(...) kullanılan ve ne gibi geometri bir parça oluşturabilir, bu işe yarayabilir. Kaçırdığım bunu yapmanın başka yolları

var mı? Sunduğunuz herhangi bir geri bildirim için teşekkür ederiz. Teşekkürler.

Düzenleme: aşağıda seçilen çözümde fikri dayanarak

, bende şu sonuçlar:

Panels

Bu üretim ve için şekle çırpılmış gerekiyor arkaplan görüntüleri kötü seçilmiştir, ancak bir demo olarak, aşağıdaki RoundedPanel kodu bizi yukarıdaki sonuçlara götürür:

public class RoundedPanel extends JPanel 
{ 
    protected int strokeSize = 1; 
    protected Color _shadowColor = Color.BLACK; 
    protected boolean shadowed = true; 
    protected boolean _highQuality = true; 
    protected Dimension _arcs = new Dimension(30, 30); 
    protected int _shadowGap = 5; 
    protected int _shadowOffset = 4; 
    protected int _shadowAlpha = 150; 

    protected Color _backgroundColor = Color.LIGHT_GRAY; 
    protected BufferedImage image = null; 

    public RoundedPanel(BufferedImage img) 
    { 
     super(); 
     setOpaque(false); 

     if(img != null) 
     { 
      image = img; 
     } 
    } 

    @Override 
    public void setBackground(Color c) 
    { 
     _backgroundColor = c; 
    } 

    @Override 
    protected void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 

     int width = getWidth(); 
     int height = getHeight(); 
     int shadowGap = this._shadowGap; 
     Color shadowColorA = new Color(_shadowColor.getRed(), _shadowColor.getGreen(), _shadowColor.getBlue(), _shadowAlpha); 
     Graphics2D graphics = (Graphics2D) g; 

     if(_highQuality) 
     { 
      graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     } 

     if(shadowed) 
     { 
      graphics.setColor(shadowColorA); 
      graphics.fillRoundRect(_shadowOffset, _shadowOffset, width - strokeSize - _shadowOffset, 
        height - strokeSize - _shadowOffset, _arcs.width, _arcs.height); 
     } 
     else 
     { 
      _shadowGap = 1; 
     } 

     RoundRectangle2D.Float rr = new RoundRectangle2D.Float(0, 0, (width - shadowGap), (height - shadowGap), _arcs.width, _arcs.height); 

     Shape clipShape = graphics.getClip(); 

     if(image == null) 
     { 
      graphics.setColor(_backgroundColor); 
      graphics.fill(rr); 
     } 
     else 
     { 
      RoundRectangle2D.Float rr2 = new RoundRectangle2D.Float(0, 0, (width - strokeSize - shadowGap), (height - strokeSize - shadowGap), _arcs.width, _arcs.height); 

      graphics.setClip(rr2); 
      graphics.drawImage(this.image, 0, 0, null); 
      graphics.setClip(clipShape); 
     } 

     graphics.setColor(getForeground()); 
     graphics.setStroke(new BasicStroke(strokeSize)); 
     graphics.draw(rr); 
     graphics.setStroke(new BasicStroke()); 
    } 
} 
Yardım için 10

teşekkürler.

+1

[belki] (http://stackoverflow.com/questions/8416295/component-painting-outside-custom-border) veya [belki] (http://stackoverflow.com/questions/9382426/how- to-remove-streç-on-özel düğmeli-sınırındaki işaretleri-) – mKorbel

+0

@mKorbel: ilk bağlantı oldukça iyidir. Görünüşe göre yanlış terminolojiyi araştırıyordum. Teşekkürler. –

cevap

3

deneyin "kırpma alanı" (g.setClip() çağrıyı bakınız):

public static void main(String[] args) { 
    JFrame f = new JFrame(); 
    f.setSize(new Dimension(600, 400)); 
    f.getContentPane().setLayout(null); 
    RoundPanel rp = new RoundPanel(); 
    rp.setBounds(100, 50, 400, 300); 
    f.getContentPane().add(rp); 
    f.setVisible(true); 
} 

static class RoundPanel extends JPanel { 
    @Override 
    protected void paintComponent(Graphics g) { 
     // Prepare a red rectangle 
     BufferedImage bi = new BufferedImage(400, 300, BufferedImage.TYPE_INT_ARGB); 
     Graphics2D gb = bi.createGraphics(); 
     gb.setPaint(Color.RED); 
     gb.fillRect(0, 0, 400, 300); 
     gb.dispose(); 

     // Set a rounded clipping region: 
     RoundRectangle2D r = new RoundRectangle2D.Float(0, 0, 400, 300, 20, 20); 
     g.setClip(r); 

     // Draw the rectangle (and see whether it has round corners) 
     g.drawImage(bi, 0, 0, null); 
    } 
} 

Graphics.setClip API doc belirtilen kısıtlamalara dikkat:

keyfi bir klibe akım kırpma alanını belirler şekillendirirler. Şekil arayüzünü uygulayan tüm nesneler klibi ayarlamak için kullanılamaz. Desteklenmesi garanti edilen tek Şekil nesneleri, getClip yöntemi ve Rectangle nesneleri aracılığıyla elde edilen Şekil nesneleridir.

+0

Çözümle orijinal gönderi düzenlendi. Teşekkürler! –

+0

Neden yuvarlak bu kadar pürüzsüz değil? – user1708134

İlgili konular