2012-07-02 22 views
5

मैंने हाल ही में एक परियोजना में उपयोग के लिए जेपीनल को विस्तारित किया है जिसे हम और अधिक "3 डी" दिखाना चाहते हैं। यह घटकों पर छाया और गोलाकार कोनों की आवश्यकता के मेरे मालिकों का तरीका है। यह कई ऑनलाइन उदाहरणों पर दिखाए गए के रूप में पूरा किया गया है। मैं इसे इस तरह से किया था:गोलाकार कोनों के साथ जेपीनेल में पृष्ठभूमि छवि जोड़ें

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

और यह की पृष्ठभूमि छवि इस (बिना परिणाम JFrame के contentPane:

Panels

जो मैं वास्तव में करना चाहता हूं वह गोलाकार कोनों के साथ लाल, हरे और नीले पैनल उत्पन्न करता है, लेकिन भर जाता है Color की बजाय एक अलग छवि। मैं अभी भी सही गोलाकार कोनों चाहता हूं, लेकिन मुझे यह सुनिश्चित करने के बारे में अनिश्चितता है कि यह कैसे करें।

यदि मेरे पास एक बड़ा बनावट है, तो क्या मैं इसे RoundedPanel के आकार और आकार में बस एक टुकड़ा "क्लिप" कर सकता हूं? मुझे इसका मूल्यांकन करने की ज़रूरत है, क्योंकि यह मेरे द्वारा टाइप की गई है, लेकिन अगर मैं graphics.fillRoundRect(...) में उपयोग की जाने वाली ज्यामिति का एक टुकड़ा बना सकता हूं और फिर छवि को क्लिप कर सकता हूं, तो यह काम कर सकता है।

क्या ऐसा करने के अन्य तरीके हैं जो मुझे याद आ रही हैं? मैं किसी भी फीडबैक की सराहना करता हूं जो आप पेश कर सकते हैं। धन्यवाद।

संपादित करें:

नीचे चयनित समाधान में विचार के आधार पर, मुझे मिल गया है निम्न परिणाम:

Panels

यह उत्पादन और के लिए आकार में मार पड़ी होने की जरूरत है पृष्ठभूमि छवियों को खराब चुना जाता है, लेकिन एक डेमो के रूप में, निम्नलिखित RoundedPanel कोड हमें उपर्युक्त परिणामों पर ले जाता है:

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- कस्टम-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 के लिए एपीआई दस्तावेज़ में वर्णित सभी प्रतिबंधों से सावधान रहें:

एक मनमाना क्लिप करने के लिए वर्तमान कतरन क्षेत्र सेट करता है आकार। आकार इंटरफ़ेस को लागू करने वाली सभी ऑब्जेक्ट्स को क्लिप सेट करने के लिए उपयोग नहीं किया जा सकता है। एकमात्र आकार ऑब्जेक्ट जिन्हें समर्थित होने की गारंटी दी जाती है वे आकार वस्तुएं हैं जो getClip विधि और आयताकार वस्तुओं के माध्यम से प्राप्त की जाती हैं।

+0

समाधान के साथ मूल पोस्ट संपादित किया गया। धन्यवाद! –

+0

राउंड इतना आसान क्यों नहीं है? – user1708134

संबंधित मुद्दे