2013-07-14 110 views
1

我想添加一個將JPanel擴展到另一個JPanel的imagepanel。這對我來說效果不好。圖像面板的繪畫功能不會在Jpanel中調用,但在JFrame中可以正常工作。任何想法或幫助將不勝感激。如何添加Jpanel中的jpanel imagepanel?

import javax.swing.*; 
import java.awt.*; 
import java.awt.geom.RoundRectangle2D; 
import java.awt.image.BufferedImage; 

class ImagePanel extends JPanel 
{ 
    int g_h=10,g_w=10; 
    int width=50,height=50; 
    int cornerradius; 
    Image castle; 
    Dimension size; 
    protected int x1,y1; 

    Color c1=new Color(255, 0, 0); 
    Rectangle rec; 
    boolean b=false; 
    boolean imboo=false; 
    boolean roundb= false; 

    Graphics g= this.getGraphics(); 
    protected int strokeSize = 1; 
    protected Color shadowColor = Color.BLACK; 
    boolean shadowed = false; 

    public ImagePanel() 
    {  
     //super(); 
     setOpaque(false); 
     setLayout(null); 
     System.out.println("it executed"); 
    } 

    public ImagePanel(int x, int y) 
    { 
     setSize(x, y); 
    } 

    public void setSize(int x,int y){ 
     width=x; 
     height=y; 
    } 

    public int getheight(){ 
     return height; 
    } 

    public int getwidth(){ 
     return width; 
    } 

    public void setImagePanelBounds(
      int x, int y, int width, int height){ 
     x1=x; 
     y1=y; 
     this.width= width; 
     this.height= height; 
     System.out.println("6it executed"); 
    } 

    public void setroundcorners(boolean b, int i){ 
     roundb=b; 
     cornerradius=i; 
     System.out.println("5it executed"); 
    } 

    public void setImage(String s){ 
     imboo=true; 
     size = new Dimension(); 
     castle = new ImageIcon(s).getImage(); 
     size.width = castle.getWidth(null); 
     size.height = castle.getHeight(null); 
     setPreferredSize(size); 
     System.out.println("4it executed"); 
    } 

    public void paint(Graphics gh){ 
     System.out.println("it executed p"); 
     {int x=this.getWidth(); 
     int j=20,a=20; 
     Graphics2D g2= (Graphics2D)gh.create(); 
     { 
      g2.setColor(Color.WHITE); 
      g2.setComposite(AlphaComposite.Src); 
      g2.setRenderingHint(
       RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 
      g2.setComposite(AlphaComposite.SrcAtop);  
      rec= new Rectangle(x1, y1, width, height); 
      //Start of If-else 

      if(roundb){ 
       g2.setClip(new RoundRectangle2D.Float(
         (int)rec.getX(),(int)rec.getY(), 
          (int)rec.getWidth(),(int)rec.getHeight(), 
              cornerradius, cornerradius)); 
       System.out.println("it executed"); 
      } 
      // End of If-Else 
      // Image condition Starts 
      if (imboo){ 
       g2.drawImage(castle, (int)rec.getX(), 
        (int)rec.getY(), (int)rec.getWidth(), 
           (int)rec.getHeight(), null); 
       //g.drawImage(castle, (int)rec.getX(),(int)rec.getY(), null); 
      } 
      // Image condition Ends 
      g2.setColor(Color.BLUE); 
     } 
     } 
    } 

    public static void main(String[]args) 
    { 
     ImagePanel t1=new ImagePanel(); 
     JPanel jp1= new JPanel(); 
     jp1.add(t1); 
     jp1.setLayout(null); 
     jp1.setBounds(0, 0, 600, 600); 
     JFrame jf1= new JFrame("Testing"); 
     t1.setImage("icons/1.png"); 
     //t1.setImage("1.jpg"); 
     t1.setLayout(null); 
     t1.setroundcorners(true, 10); 
     //t1.setShadow(true); 
     t1.add(new JLabel("niak")); 
     //t1.setShadowDimensions(18, 18, 305, 305, 12); 
     t1.setImagePanelBounds(20, 20, 100, 100); 
     // jf1.add(t1); 
     jf1.setSize(600, 600); 
     jf1.setDefaultCloseOperation(jf1.EXIT_ON_CLOSE); 
     jf1.setVisible(true); 
     //jf1.revalidate(); 
     jf1.setLayout(null); 
    } 
} 
+1

那麼我可以給你的最好的建議是隻刪除你試圖覆蓋的額外JPanel。這個類本身就是一個JPanel,因此,所有你需要做的工作都是myJFrame。添加(本);重繪();因此圖形呈現 – user2277872

+1

在JPanel頂部添加一個JPanel就像是說在冷毯上添加一個帶有加熱器的毯子。它並不真正起作用,也沒有幫助。 – user2277872

回答

4

讓我們先從...

  • 不要使用getGraphics。這不是如何執行自定義繪畫。 getGraphics可能會返回null,最好是一個快照,在下一次繪製週期發生時將被放棄。
  • JPanel已經有getWidthgetHeightsetSize方法,你永遠不應該有必要重寫它們。相反,您應該覆蓋getPreferredSize並返回父佈局管理器可以使用的大小提示。
  • 如果您創建了Graphics上下文,則應該是其中的dispose。在您的paint方法中,您使用gh.create,這消耗了資源並且在某些系統下,直到Graphics上下文被處置,它可能實際上不會繪製任何東西。
  • 請勿重寫paint,改爲使用paintComponent
  • 請勿修改剪裁矩形。嚴重的是,這會給你帶來更多的問題,然後你可以想象。
  • 不要使用null佈局管理器沒有極端的好理由。
  • JPanel有一個setBounds方法,而在正常情況下,你不需要使用它,因爲你丟掉了佈局管理器,你應該使用它。

基本上,你已經放棄JPanel,使塗料系統的所有內部工作要知道,它實際上應該畫你的面板

與例如

舉個例子更新。 ..

而不是使用剪輯,我使用屏蔽技術,並在源圖像上掩蓋我想要的形狀。我也緩衝了結果,應該讓更多的內存保守以及渲染速度更快

enter image description hereenter 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.Insets; 
import java.awt.RenderingHints; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.border.EmptyBorder; 

public class ImagePaneExample { 

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

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

       try { 
        BufferedImage img = ImageIO.read(new File("C:\\hold\\thumbnails\\2005-09-29-3957.jpeg")); 
        ImagePane imgPane = new ImagePane(); 
        imgPane.setImage(img); 
        imgPane.setRounded(true); 
        imgPane.setBorder(new EmptyBorder(20, 20, 20, 20)); 

        JFrame frame = new JFrame("Testing"); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.setLayout(new BorderLayout()); 
        frame.add(imgPane); 
        frame.pack(); 
        frame.setLocationRelativeTo(null); 
        frame.setVisible(true); 
       } catch (Exception exp) { 
        exp.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public class ImagePane extends JPanel { 

     private BufferedImage img; 
     private BufferedImage renderImg; 
     private boolean rounded; 

     public ImagePane() { 
     } 

     public void setRounded(boolean value) { 
      if (value != rounded) { 
       rounded = value; 
       renderImg = null; 
       firePropertyChange("rounded", !rounded, rounded); 
       repaint(); 
      } 
     } 

     public boolean isRounded() { 
      return rounded; 
     } 

     public void setImage(BufferedImage value) { 
      if (value != img) { 
       BufferedImage old = img; 
       img = value; 
       renderImg = null; 
       firePropertyChange("image", old, img); 
       repaint(); 
      } 
     } 

     public BufferedImage getImage() { 
      return img; 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      Dimension size = img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight()); 
      Insets insets = getInsets(); 
      size.width += (insets.left + insets.right); 
      size.height += (insets.top + insets.bottom); 
      return size; 
     } 

     protected void applyQualityRenderHints(Graphics2D g2d) { 
      g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); 
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); 
      g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); 
      g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); 
      g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
      g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 
      g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); 
     } 

     protected BufferedImage getImageToRender() { 

      if (renderImg == null) { 
       BufferedImage source = getImage(); 
       if (source != null) { 
        if (isRounded()) { 
         BufferedImage mask = new BufferedImage(source.getWidth(), source.getHeight(), BufferedImage.TYPE_INT_ARGB); 
         Graphics2D g2d = mask.createGraphics(); 
         applyQualityRenderHints(g2d); 
         g2d.setBackground(new Color(255, 255, 255, 0)); 
         g2d.clearRect(0, 0, mask.getWidth(), mask.getHeight()); 
         g2d.setBackground(new Color(255, 255, 255, 255)); 
         g2d.fillRoundRect(0, 0, mask.getWidth(), mask.getHeight(), 40, 40); 
         g2d.dispose(); 

         BufferedImage comp = new BufferedImage(source.getWidth(), source.getHeight(), BufferedImage.TYPE_INT_ARGB); 
         g2d = comp.createGraphics(); 
         applyQualityRenderHints(g2d); 
         g2d.setBackground(new Color(255, 255, 255, 0)); 
         g2d.clearRect(0, 0, source.getWidth(), source.getHeight()); 
         g2d.drawImage(source, 0, 0, this); 
         g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN)); 
         g2d.drawImage(mask, 0, 0, this); 
         g2d.dispose(); 

         renderImg = comp; 
        } else { 
         renderImg = source; 
        } 
       } 
      } 

      return renderImg; 

     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      BufferedImage img = getImageToRender(); 
      System.out.println(img); 
      if (img != null) { 
       Insets insets = getInsets(); 
       Graphics2D g2d = (Graphics2D) g.create(); 
       int width = getWidth(); 
       int height = getHeight(); 
       int x = ((width - img.getWidth())/2); 
       int y = ((height - img.getHeight())/2); 
       g2d.drawImage(img, x, y, this); 
       g2d.dispose(); 
      } 
     } 
    } 
} 

我建議一些更多的閱讀通過Creating a UI with Swing,特別是在佈局管理器的部分,如以及Performing Custom PaintingPainting in AWT and Swing

+0

感謝您的建議,我會讓他們在我心中!謝謝你,先生 !!! :) –

+0

@SunnyDhaliwal嘗試更新;) – MadProgrammer

1

所有你需要做的就是你的面板jp1Layout設置爲BorderLayout和圖像面板t1添加到BorderLayout.CENTER,像這樣:

JPanel jp1= new JPanel(new BorderLayout()); 
jp1.add(t1, BorderLayout.CENTER); 
+0

非常感謝!!!!!!! –

+0

歡迎:) –