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

2022-01-24 00:00:00 java swing jpanel jframe awt

我正在尝试添加一个将 JPanel 扩展到另一个 JPanel 的图像面板.这对我来说效果不佳.图像面板的绘制功能不会在 Jpanel 内部调用,但在 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);
    }  
}

推荐答案

让我们从...开始

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

基本上,您已经放弃了 JPanel 的所有内部工作,这些工作使绘制系统知道它应该实际绘制您的面板

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

更新示例

举个例子……

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

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

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

我建议您阅读一下使用 Swing 创建 UI,在特别是关于布局管理器的部分,以及 执行自定义绘画 和 在 AWT 和 Swing 中绘画

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

相关文章