我目前正在设计游戏的标题屏幕。设计徽标时,我决定在边缘周围使用彩虹边框:

java - Java Swing:JComponent的彩虹边框-LMLPHP

之后,我想在标题屏幕上用类似的彩虹边框(特别是JButtons)实现其余组件。在寻找实现方法时,我遇到了AbstractBorder类。我的问题是,这是否有可能?如果是,使用Abstract border类根据组件的大小生成彩虹边框的最有效方法是什么?

最佳答案

基本方法是使用LinearGradientPaint绘制彩虹效果,例如...

public class RainbowBorder extends AbstractBorder {

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

    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        Graphics2D g2d = (Graphics2D) g.create();
        LinearGradientPaint lpg = new LinearGradientPaint(
            new Point(x, y),
            new Point(x, y + height),
            new float[]{0.0f, 0.25f, 0.5f, 0.75f, 1.0f},
            new Color[]{Color.YELLOW, Color.GREEN, Color.CYAN, Color.BLUE, Color.MAGENTA});
        g2d.setPaint(lpg);
        g2d.draw(new Rectangle2D.Double(x, y, width - 1, height - 1));
        g2d.dispose();
    }

}


并作为概念证明

java - Java Swing:JComponent的彩虹边框-LMLPHP

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.geom.Rectangle2D;
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;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;

public class TextOutline {

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

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

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

    public class RainbowBorder extends AbstractBorder {

        @Override
        public Insets getBorderInsets(Component c) {
            return super.getBorderInsets(c); //To change body of generated methods, choose Tools | Templates.
        }

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

        @Override
        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
            Graphics2D g2d = (Graphics2D) g.create();
            LinearGradientPaint lpg = new LinearGradientPaint(
                new Point(x, y),
                new Point(x, y + height),
                new float[]{0.0f, 0.25f, 0.5f, 0.75f, 1.0f},
                new Color[]{Color.YELLOW,    Color.GREEN, Color.CYAN, Color.BLUE, Color.MAGENTA});
            g2d.setPaint(lpg);
            g2d.draw(new Rectangle2D.Double(x, y, width - 1, height - 1));
            g2d.dispose();
        }

    }

    class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());
            setBorder(
                new CompoundBorder(
                    new EmptyBorder(10, 10, 10, 10),
                    new CompoundBorder(
                        new RainbowBorder(),
                        new EmptyBorder(10, 10, 10, 10))
            ));
            add(new JLabel("Rainbow and unicorns"));
        }
    }
}

10-08 01:24