将图像附加到 JLabel 的边框 [英] Attaching images to JLabel's border

查看:24
本文介绍了将图像附加到 JLabel 的边框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个 JLabel 的自定义子类,它将两个图像附加到边框,可以通过移动鼠标来移动.像这样的真实效果:

I want to write a custom subclass of JLabel that would have two images attached to the border, that can be moved by moving the mouse. Real effects like this:

这是我的子类,如何添加这些附加图片?

Here's my subclass, how could I add these attached images?

public class Rect extends JLabel{
    private int width,height;
    public Rect (int width,int height){
        this.width = width;
        this.height = height;
        setText("b1");
        repaint();
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);

        g.setColor(Color.red);
        g.drawRect(0, 0, this.width, this.height);
    }

    public void reDraw(){
        this.repaint();
    }

    public void setWidth(int width) {
        this.width = width;
        repaint();
    }

    public void setHeight(int height) {
        this.height = height;
        repaint();
    }
}

推荐答案

要做到这一点,您应该做 4 件事:

To do this there are 4 things you should to do:

  • 扩展 AbstractBorder 而不是 Jlabel,然后您可以轻松地将自定义边框添加到任何组件,而不仅仅是 jLabel.立>
  • 覆盖 paintBorder 方法,以便您可以绘制边框.
  • 添加鼠标动作侦听器以跟踪您的边框图像.
  • 最后,您需要一些逻辑来管理您的边框图像.
  • Extend an AbstractBorder not a Jlabel, then you can easily add your custom border to any component, not just a jLabel.
  • Override the paintBorder method so that you can draw your border.
  • Add an mouse action listeners to keep track of your border images.
  • And lastly you need a bit of logic to manage your border images.

我发现这个问题很有趣,所以我尝试制作一些东西作为测试.结果很好,可以做你想做的事,但需要做一些工作才能让它看起来正确.有关每个点的细分,请参见下文.

I found this question interesting so I took a crack at making something as a test. It came out well, and does what you want, but will need a bit of work to get it looking correct. See below for a break down of each point.

我们看代码之前的示例图片:

public class MyCustomBorder extends AbstractBorder
{
    private Color borderColour;
    private int borderThickness = 10;
    private Point firstSlider = new Point(0, 0);
    private Point secondSlider = new Point(0, 0);
    private BufferedImage firstSliderImage;
    private BufferedImage secondSliderImage;

    Boolean draggingFirst = false;
    Boolean draggingSecond = false;

    //See usage info
    public MyCustomBorder(Color colour, int thickness, Point firstSlider, BufferedImage firstSliderImage, Point secondSlider, BufferedImage secondSliderImage)
    {
        borderColour = colour;
        borderThickness = thickness;
        this.firstSlider = firstSlider;
        this.secondSlider = secondSlider;
        this.firstSliderImage = firstSliderImage;
        this.secondSliderImage = secondSliderImage;
    }

覆盖 paintBorder 方法和插入:

Override the paintBorder method and insets:

    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height)
    {
        super.paintBorder(c, g, x, y, width, height);
        Graphics2D g2d = null;

        if (g instanceof Graphics2D)
        {
            g2d = (Graphics2D) g;

            //Draw border fill (currently hard coded to white, but can be changed)
            g2d.setColor(Color.white);
            //Top
            g2d.fill(new Rectangle2D.Double(0, 0, width, borderThickness));
            //Left
            g2d.fill(new Rectangle2D.Double(0, 0, borderThickness, height));
            //Bottom
            g2d.fill(new Rectangle2D.Double(0, height-borderThickness, width, borderThickness));
            //Right
            g2d.fill(new Rectangle2D.Double(width-borderThickness, 0, borderThickness, height));

            //draw black seperator
            g2d.setColor(borderColour);
            //Top
            g2d.fill(new Rectangle2D.Double(borderThickness, borderThickness, width-(borderThickness*2), 1));
            //Left
            g2d.fill(new Rectangle2D.Double(borderThickness, borderThickness, 1, height-(borderThickness*2)));
            //Bottom
            g2d.fill(new Rectangle2D.Double(borderThickness, height-borderThickness-1, width-(borderThickness*2), 1));
            //Right
            g2d.fill(new Rectangle2D.Double(width-borderThickness-1, borderThickness, 1, height-(borderThickness*2)));

            //draw sliders an custom position       
            g2d.drawImage(scale(secondSliderImage), null, secondSlider.x, secondSlider.y);
            g2d.drawImage(scale(firstSliderImage), null, firstSlider.x, firstSlider.y);
        }
    }

    @Override
    public Insets getBorderInsets(Component c)
    {
        return (getBorderInsets(c, new Insets(borderThickness, borderThickness, borderThickness, borderThickness)));
    }

    @Override
    public Insets getBorderInsets(Component c, Insets insets)
    {
        insets.left = insets.top = insets.right = insets.bottom = borderThickness;
        return insets;
    }

    @Override
    public boolean isBorderOpaque()
    {
        return false;
    }
}

添加鼠标动作监听器:

    //listeners for dragging
    void addListeners(Component button)
    {
        button.addMouseMotionListener(new java.awt.event.MouseMotionAdapter()
        {
            public void mouseDragged(java.awt.event.MouseEvent evt)
            {   
            //Only drag if a slider was selected
            if (draggingFirst)
            {
                //update position of silder
                firstSlider = snapToEdge(evt.getPoint(), evt.getComponent());
                evt.getComponent().repaint();
            }
            else if (draggingSecond)
            {
                //update position of silder
                secondSlider = snapToEdge(evt.getPoint(), evt.getComponent());
                evt.getComponent().repaint();
            }
            }
        });
        button.addMouseListener(new java.awt.event.MouseAdapter()
        {
            //check if a slider was selected
            public void mousePressed(java.awt.event.MouseEvent evt)
            {
            if (isInside(evt.getPoint(), firstSlider))
            {
                draggingFirst = true;
            }
            else if (isInside(evt.getPoint(), secondSlider))
            {
                draggingSecond = true;
            }
            }
            public void mouseReleased(java.awt.event.MouseEvent evt)
            {
            //cancel selected slider
            draggingFirst = false;
            draggingSecond = false;
            }
        });
    }

逻辑:

    //check if a slider was selected
    private Boolean isInside(Point clicked, Point toCheck)
    {
        if (clicked.x > toCheck.x && clicked.x < toCheck.x + borderThickness)
        {
            if (clicked.y > toCheck.y && clicked.y < toCheck.y + borderThickness)
            {
            return true;
            }
        }
        return false;
    }

    //snap a sliders co-ords to as edge
    private Point snapToEdge(Point dragged, Component label)
    {   
        //work out how close to each edge
        int topEdge = dragged.y;
        int leftEdge = dragged.x;
        int rightEdge = label.getWidth()- dragged.x;
        int bottomEdge = label.getHeight() - dragged.y;

        //snap to slider co-ords to closest edge
        if (topEdge < leftEdge && topEdge < rightEdge && topEdge < bottomEdge)
        {
            dragged.y = 0;
        }
        else if (leftEdge < rightEdge && leftEdge < bottomEdge)
        {
            dragged.x = 0;
        }
        else if (rightEdge < bottomEdge)
        {
            dragged.x = label.getWidth()-borderThickness;
        }
        else
        {
            dragged.y = label.getHeight()-borderThickness;
        }
        return dragged;
    }

    //scale slider images to fit border size
    public BufferedImage scale(BufferedImage image)
    {
        BufferedImage resizedImage = null;
        if (image != null)
        {
            double border = borderThickness;
            resizedImage = new BufferedImage(borderThickness, borderThickness, TYPE_INT_ARGB);
            Graphics2D g = resizedImage.createGraphics();
            AffineTransform at = AffineTransform.getScaleInstance(border / (double)image.getWidth(), border / (double)image.getHeight());
            g.drawRenderedImage(image, at);
        }
        return resizedImage;
    }

可以在此处找到要复制和粘贴的完整代码:

https://github.com/sorifiend/customBorder/blob/master/MyCustomBorder.java

您可以将此代码放在表单类中,以便为大多数摆动组件添加边框.在本例中,我将其添加到名为 my_jLabel:

You can put this code in your form class to add a border to most swing components. In this example I added it to a jLabel called my_jLabel:

   //Create border
   MyCustomBorder border = new MyCustomBorder(Color.BLACK, 10, new Point(0, 0), img1, new Point(0, 0), img2);

   //Add border to component called my_jLabel
   my_jLabel.setBorder(border);

   //Add action listeners for dragging sliders (very important)
   border.addListeners(my_jLabel);

这篇关于将图像附加到 JLabel 的边框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆