如何在Jframe内的jpanel中添加imagepanel?

时间:2013-07-14 23:41:24

标签: java swing jframe jpanel awt

我正在尝试添加一个将JPanel扩展到另一个JPanel的imagepanel。这对我来说效果不佳。图像面板的绘制功能不会在Jpanel中调用,但在JFrame中可以正常工作。任何想法或帮助将不胜感激。

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

2 个答案:

答案 0 :(得分:5)

让我们从...开始......

  • 请勿使用getGraphics。这不是如何执行自定义绘画。 getGraphics可能会返回null,并且最多只能是一个快照,当下一个绘制周期发生时,该快照将被丢弃。
  • JPanel已经有getWidthgetHeightsetSize方法,您永远不需要覆盖它们。相反,您应该覆盖getPreferredSize并返回父布局管理器可以使用的大小提示。
  • 如果您创建Graphics上下文,则应该dispose。在paint方法中,您使用gh.create,这会消耗资源,在某些系统下,在处置Graphics上下文之前,它实际上可能不会绘制任何内容。
  • 请勿覆盖paint,而应使用paintComponent
  • 请勿修改剪辑矩形。说真的,这会给你带来更多你想象的问题。
  • 请勿使用null布局管理器,但没有充分的理由。
  • JPanel有一个setBounds方法,而在正常情况下,你不需要使用它,因为你已经扔掉了布局管理器,你应该使用它。

基本上,你放弃了JPanel的所有内部工作方式,使油漆系统能够知道它应该实际绘制你的面板

更新了示例

作为一个例子......

我不使用剪辑,而是使用遮罩技术,并在源图像上遮盖我想要的形状。我也缓冲了结果,这应该使它更加内存保守以及渲染更快

enter image description here enter 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

答案 1 :(得分:1)

您所要做的就是将面板Layout的{​​{1}}设置为jp1,然后将图片面板BorderLayout添加到t1,就像这样:

BorderLayout.CENTER