【问题标题】:Simplest Code to round corners of JLabel in java [duplicate]java中JLabel圆角的最简单代码[重复]
【发布时间】:2014-11-05 22:35:25
【问题描述】:

我有很多JLabel,希望它们的拐角处平滑。我怎样才能做到这一点?我已经在 SO 上搜索过,但没有找到任何答案。

有人可以帮我提供一个简单而准确的代码来为JLabel's 制作圆角吗?

其他问题是询问一些额外的细节,如边框等,但我只想要精确和最简单的代码来为JLabel's 制作圆角。

【问题讨论】:

    标签: java swing graphics jlabel rounded-corners


    【解决方案1】:

    说真的,最简单的解决方案是在 JLabel 周围画一个 RoundRectangle2D...

    现在,您可以在标签的 paintComponentpaintBorder 方法中执行此操作,但是当您可以制作自己的边框以可重复使用的方式完成工作时,您为什么还要打扰,例如...

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

    现在,如果您想要“平滑”边缘,您将不得不将 RenderingHints 提供给 Graphics 上下文,例如...

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

    【讨论】:

      【解决方案2】:

      您不能在实际的JLabel 区域上进行圆角;它们总是矩形的。但是,一个简单的替代方法是将JLabelImageIcon 设置为具有圆边且不使用边框的图像。设置ImageIcon

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

      您的图像应该具有JLabel 的尺寸。 请注意,如果找不到图像,这将抛出NullPointerException。确保你走对了路!

      创建一个ImageIcon,将其大小调整为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);
      

      编辑:

      这是使用Graphics2D 制作圆角边框的最佳方法。 首先,创建一个名为 RoundedBorder 的新类。将此代码粘贴到其中:

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

      然后,在您的 JFrame 类中,将此设置为 JLabel 的边框,请执行以下操作:

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

      正如 MadProgrammer 所提到的,比画线更有效的方法是使用RoundRectangle2D。要使用它,请将所有 draw 行替换为

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

      随意修改边框。这是使用Graphics2D的语法:

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

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

      我希望这会有所帮助!

      【讨论】:

      • ImageIcon 无法缩放
      【解决方案3】:

      simplest 是使用 LineBorder 类。

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

      但结果并不是城里最好看的圆角;-)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-22
        • 2012-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多