2012-07-02 57 views
5

最近「私たちはもっと3Dに見えるようにするプロジェクトで使用するためにJPanelを拡張しました。これは私の上司がシャドウイングとコンポーネントの角を丸くすることを要求する方法です。それは多くのオンラインの例に示されているように達成されています。私はこのようにそれをやった:私は、次のコードでテストフレーム作成しています丸い角を持つJPanelに背景画像を追加

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); 
      } 
     }); 
    } 
} 

をそして、それは、この(サンセリフ中の背景画像を結果JFramecontentPane

私は本当にやりたい何

Panels

は、角を丸くした、赤、緑、青のパネルを生成しているが、で満たされましたColorの代わりに別のイメージ。私はまだ適切に丸い角が欲しいですが、私はこれを行う方法がわかりません。

大きなテクスチャがある場合は、RoundedPanelのサイズと形状で単純に「クリップ」できますか?私はこれを評価する必要があります。なぜなら、私が入力したときに私に起こったのですが、graphics.fillRoundRect(...)で使用されているもののような幾何学的図形を作成してイメージをクリップすることができます。

私は行方不明のこれを行う他の方法はありますか?あなたが提供できるフィードバックがあれば感謝します。ありがとう。

編集:以下の選択溶液中のアイデアに基づいて

、私が持っている以下の結果:

Panels

それは生産とのための形状にホイップする必要があります背景画像はあまり選択されていませんが、デモとしては次のような結果が表示されます。

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()); 
    } 
} 

ありがとうございました。 「クリッピング領域」

+1

[多分](http://stackoverflow.com/questions/8416295/component-painting-outside-custom-border)または[多分](http://stackoverflow.com/questions/9382426/how-カスタムボタンの枠線の上にストレッチマークをつける) – mKorbel

+0

@mKorbel:最初のリンクはかなり良いです。私は間違った用語で検索していました。ありがとう。 –

答えて

3

てみてください(g.setClip()コールを参照してください):

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ドキュメントに記載された制限に注意してください:

任意のクリップに現在のクリッピング領域を設定します。形状。 Shapeインタフェースを実装するすべてのオブジェクトをクリップの設定に使用できるとは限りません。サポートされるShapeオブジェクトは、getClipメソッドおよびRectangleオブジェクトを介して取得されるShapeオブジェクトのみです。

+0

編集した元の記事を解決しました。ありがとう! –

+0

なぜラウンドは滑らかではありませんか? – user1708134

関連する問題