Sunny Dhaliwal
Sunny Dhaliwal

Reputation: 87

How to add imagepanel in jpanel inside Jframe?

I'm trying to add an imagepanel which extends JPanel to another JPanel. Which is not working well for me. The paint function of image panel don't get invoked inside Jpanel but works fine in JFrame. Any ideas or help will be appreciated.

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

Upvotes: 1

Views: 4742

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347314

Let's start with...

  • Don't use getGraphics. This is not how to perform custom painting. getGraphics may return null and is, at best, a snapshot, which will be discard when the next paint cycle occurs.
  • JPanel already has getWidth, getHeight and setSize methods, you should never have a need to overridden them. Instead, you should override getPreferredSize and return a size hint back that the parent layout manager can use.
  • If you create a Graphics context, you should dispose of it. In your paint method, you use gh.create, this is consuming resources and under some systems, until the Graphics context is disposed, it may not actually paint anything.
  • Don't override paint, instead use paintComponent
  • DO NOT modify the clip rectangle. Seriously, this is going to cause you more issues then you can imagine.
  • Don't use null layout managers without EXTREMELY good reason.
  • JPanel has a setBounds method, while, under normal circumstances, you shouldn't need to use it, since you've thrown away the layout manager, you should use it.

Basically, you've discard all the inner workings of the JPanel that enable the paint system to know that it should actually paint your panel

Updated with example

As an example...

Instead of using the clip, I use a masking technique, and mask the shape I want over the source image. I also buffer the result, which should make it more memory conservative as well as render faster

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

I'd recommend some more reading through Creating a UI with Swing, in particular the section on layout managers, as well as Performing Custom Painting and Painting in AWT and Swing

Upvotes: 5

Syed Muhammad Humayun
Syed Muhammad Humayun

Reputation: 459

All you have to do is to set the Layout of your panel jp1 to BorderLayout and add the image panel t1 to BorderLayout.CENTER, like this:

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

Upvotes: 1

Related Questions