2013-07-14 161 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

欢迎:) –