Simplest Code to round corners of JLabel in java [duplicate]

☆樱花仙子☆ 提交于 2020-01-07 08:27:26

问题


I have many JLabel's and want smooth around corners on them. How can I make this? I already searched on SO but I didn't find any answer.

Could someone help me with a simple and exact code for making round corners for JLabel's?

Other questions are asking some extra details like border and others but I want just exact and simplest code for making round corners for JLabel's.


回答1:


You cannot round corners on the actual JLabel area; they are always rectangular. However, a simple alternative is to set the ImageIcon of the JLabel to an image with rounded edges and not use a border. To set an ImageIcon:

yourLabel.setIcon(new ImageIcon(getClass().getResource("/path/to/your/image.png"));
// Note: Relative path, starts from root of project

Your image should have the dimensions of your JLabel. Note that this will throw a NullPointerException if the image is not found. Make sure you get the right path!

To create an ImageIcon that resizes to the size of the JLabel:

ImageIcon ico = new ImageIcon("/path/to/your/image.png");
Image img = ico.getImage();
BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
g.drawImage(img, 0, 0, yourLabel.getWidth(), yourLabel.getHeight(), null);
IconImage newIco = new IconImage(bi);
yourLabel.setIcon(newIco);

EDIT:

Here is the best way to make a border with rounded corners, using Graphics2D. First, make a new class called RoundedBorder. Paste this code into it:

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.geom.Line2D;
import javax.swing.border.AbstractBorder;

public class RoundedBorder extends AbstractBorder {

public RoundedBorder(Color c, int g) {
    color = c;
    gap = g;
}

@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;
    if (g instanceof Graphics2D) {
        g2d = (Graphics2D) g;
        g2d.setColor(color);
        System.out.println(x + y);
        g2d.draw(new Line2D.Double((double)x, (double)y + 10, (double)x + 3, (double)y + 3));
        g2d.draw(new Line2D.Double((double)x + 3, (double)y + 3, (double)x + 10, (double)y));
        g2d.draw(new Line2D.Double((double)x + 10, (double)y, (double)x + 30, (double)y));
        g2d.draw(new Line2D.Double((double)x + 30, (double)y, (double)x + 33, (double)y + 2));
        g2d.draw(new Line2D.Double((double)x + 33, (double)y + 2, (double)x + 36, (double)y + 8));
        g2d.draw(new Line2D.Double((double)x + 36, (double)y + 8, (double)x + 36, (double)y + 28));
        g2d.draw(new Line2D.Double((double)x + 36, (double)y + 28, (double)x + 34, (double)y + 31));
        g2d.draw(new Line2D.Double((double)x + 34, (double)y + 31, (double)x + 32, (double)y + 33));
        g2d.draw(new Line2D.Double((double)x + 32, (double)y + 33, (double)x + 6, (double)y + 33));
        g2d.draw(new Line2D.Double((double)x + 6, (double)y + 33, (double)x + 3, (double)y + 31));
        g2d.draw(new Line2D.Double((double)x + 3, (double)y + 31, (double)x, (double)y + 27));
        g2d.draw(new Line2D.Double((double)x, (double)y + 27, (double)x, (double)y + 10));
    }
}

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

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

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

// Variable declarations
private final Color color;
private final int gap;
}

Then, in your JFrame class, to set this as the border of a JLabel, do:

yourLabel.setBorder(new RoundedBorder(Color.black, 10));

As MadProgrammer mentioned, a more efficient way than drawing lines is to use a RoundRectangle2D. To use this, replace all of the draw lines with

g2d.draw(new RoundRectangle2D.Double(x, y, width - 1, height - 1, gap, gap));

Feel free to modify the border as you wish. Here is the syntax for using Graphics2D:

g2d.draw(new Line2D.Double((double)x1, (double)y1, (double)x2, (double)y2));

OR

g2d.draw(new Line2D.Double(Point2D p1, Point2D p2));

I hope this helped!




回答2:


Seriously, the easiest solution would be to paint a RoundRectangle2D around the JLabel...

Now, you could do this within the label's paintComponent or paintBorder methods, but why would you bother, when you could just make your own border which did the job in a reusable manner, for example...

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.AbstractBorder;

public class TestRoundedBorder {

    public static void main(String[] args) {
        new TestRoundedBorder();
    }

    public TestRoundedBorder() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setBackground(Color.RED);
            setLayout(new GridBagLayout());
            JLabel label = new JLabel("Test");
            label.setBorder(new RoundedBorder(Color.BLACK, 20));
            add(label);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

    public class RoundedBorder extends AbstractBorder {

        private final Color color;
        private final int gap;

        public RoundedBorder(Color c, int g) {
            color = c;
            gap = g;
        }

        @Override
        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(color);
            g2d.draw(new RoundRectangle2D.Double(x, y, width - 1, height - 1, gap, gap));
            g2d.dispose();
        }

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

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

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

}

Now, if you want "smooth" edges, you're going to have to supply RenderingHints to the Graphics context, for example...

public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
    Graphics2D g2d = (Graphics2D) g.create();
    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);
    g2d.setColor(color);
    g2d.draw(new RoundRectangle2D.Double(x + 1, y + 1, width - 2, height - 2, gap, gap));
    g2d.dispose();
}



回答3:


The simplest is to use the LineBorder class.

import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

public class RoundedLineBorder extends JPanel {

  public RoundedLineBorder() {
    super(true);

    JLabel label = new JLabel("<html>Stack<br/>Overflow</html>");
    LineBorder line = new LineBorder(Color.blue, 1, true); // color, thickness, rounded
    label.setBorder(line);
    add(label, BorderLayout.CENTER);
  }

  public static void main(String s[]) {
    JFrame frame = new JFrame("Rounded Line Border");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(500, 200);
    frame.setContentPane(new RoundedLineBorder());
    frame.setVisible(true);
  }
} 

but the result is not really the best looking rounded corners in town ;-)



来源:https://stackoverflow.com/questions/25796572/simplest-code-to-round-corners-of-jlabel-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!