java - 实现动态边框

标签 java swing border

我正在尝试实现一个动态边框,它在组件顶部绘制两条线(确切地说是代码中的四条线),当鼠标进入时在底部绘制一条线,从中心开始直到扩展到边缘。

我尝试实现java.awt.Border 但没有任何结果!

我的代码:

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import javax.swing.border.Border;


public class BorderEffect implements Border {

    public BorderEffect(Color c) {
        col = c;
    }

    private Color col;
    private Graphics g;
    Component c;
    private Color fade (Color base)
    {
        return new Color (base.getRed(),base.getGreen(),base.getBlue(),70);
    }
    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        this.g = g;
        this.c = c;
    }
    public void go () throws InterruptedException
    {
            Dimension size = c.getSize();
            for (int i = 0; i < size.getWidth(); i++) {
                System.out.println("start");
                Thread.sleep(0, 1);
                GradientPaint upLeft = new GradientPaint((float) (size.getWidth()/2), 5, col, (float)((size.getWidth()/2)+i), 5,     fade(col),false);
            GradientPaint downLeft = new GradientPaint((float) (size.getWidth()/2), (int)size.getHeight(), col, (float)((size.getWidth()/2)+i), (int)size.getHeight(), fade(col),false);
            GradientPaint upRigth = new GradientPaint((float) (size.getWidth()/2)-i, 0, fade(col), (float)((size.getWidth()/2)), 0, col,false);
            GradientPaint downRigth = new GradientPaint((float) (size.getWidth()/2)-i, (int)size.getHeight(), fade(col), (float)((size.getWidth()/2)), (int)size.getHeight(), col,false);
            Graphics2D g2 = (Graphics2D) g;
            g2.setPaint(upLeft);
            g2.fillRect((int)(size.getWidth()/2), 0, i, 3);
            g2.setPaint(upRigth);
            g2.fillRect((int)(size.getWidth()/2), 0, i, 3);
            g2.setPaint(downLeft);
            g2.fillRect((int)(size.getWidth()/2)-i, (int)size.getHeight()-5, i, 3);
            g2.setPaint(downRigth);
            g2.fillRect((int)(size.getWidth()/2)-i, (int)size.getHeight()-5, i, 3);

            c.repaint();
        }

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

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

}

我确实将边框添加到了 JPanel 中,并在 MouseAdaptermouseEntered 中调用了 go 方法。但什么也没有出现,我什至不知道哪里有缺陷。

我想知道的是:-

  1. 问题出在哪里?
  2. 如何让线条在我想要的时候消失?

最佳答案

下面是我的意思的一个例子——使用 Swing Timer 来设置边框动画。请注意,出于安全原因,我扩展了 AbstractBorder,以防此类中包含任何内务代码。 Timer 递增索引 i,并调用 repaint,然后 paintBorder 方法使用 i 来决定要绘制的内容:

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.*;

@SuppressWarnings("serial")
public class BorderTest extends JPanel {
    private JPanel testPanel = new JPanel();

    public BorderTest() {
        testPanel.setPreferredSize(new Dimension(400, 300));
        testPanel.setBorder(new BorderEffect2(testPanel, Color.BLUE));
        testPanel.setBackground(Color.WHITE);

        setPreferredSize(new Dimension(500, 400));
        setLayout(new GridBagLayout());
        add(testPanel);
    }

    private static void createAndShowGui() {
        BorderTest mainPanel = new BorderTest();

        JFrame frame = new JFrame("BorderTest");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

@SuppressWarnings("serial")
class BorderEffect2 extends AbstractBorder implements Border {
    public static final int TIMER_DELAY = 10;
    private int i = 0;
    private JPanel testPanel;
    private Color color;
    private Timer timer;

    public BorderEffect2(JPanel testPanel, Color color) {
        this.testPanel = testPanel;
        this.color = color;

        testPanel.addMouseListener(new MouseAdapt());
    }

    private class MouseAdapt extends MouseAdapter {
        @Override
        public void mouseEntered(MouseEvent e) {
            if (timer != null && timer.isRunning()) {
                return;
            }
//            System.out.println("here");
            timer = new Timer(TIMER_DELAY, new TimerListener());
            timer.start();
        }
    }

    private class TimerListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            i++;
            if (i >= testPanel.getWidth()) {
                ((Timer) timer).stop();
                i = 0;
            }
            testPanel.repaint();
        }
    }

    private Color fade(Color base) {
        return new Color(base.getRed(), base.getGreen(), base.getBlue(), 70);
    }

    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        super.paintBorder(c, g, x, y, width, height);
        Dimension size = c.getSize();

        GradientPaint upLeft = new GradientPaint((float) (size.getWidth() / 2), 5, color,
                (float) ((size.getWidth() / 2) + i), 5, fade(color), false);
        GradientPaint downLeft = new GradientPaint((float) (size.getWidth() / 2),
                (int) size.getHeight(), color, (float) ((size.getWidth() / 2) + i),
                (int) size.getHeight(), fade(color), false);
        GradientPaint upRigth = new GradientPaint((float) (size.getWidth() / 2) - i, 0,
                fade(color), (float) ((size.getWidth() / 2)), 0, color, false);
        GradientPaint downRigth = new GradientPaint((float) (size.getWidth() / 2) - i,
                (int) size.getHeight(), fade(color), (float) ((size.getWidth() / 2)),
                (int) size.getHeight(), color, false);
        Graphics2D g2 = (Graphics2D) g;
        g2.setPaint(upLeft);
        g2.fillRect((int) (size.getWidth() / 2), 0, i, 3);
        g2.setPaint(upRigth);
        g2.fillRect((int) (size.getWidth() / 2), 0, i, 3);
        g2.setPaint(downLeft);
        g2.fillRect((int) (size.getWidth() / 2) - i, (int) size.getHeight() - 5, i, 3);
        g2.setPaint(downRigth);
        g2.fillRect((int) (size.getWidth() / 2) - i, (int) size.getHeight() - 5, i, 3);
    }

    @Override
    public Insets getBorderInsets(Component c) {
        // return super.getBorderInsets(c);
        return new Insets(3, 0, 3, 0);
    }

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

}

关于java - 实现动态边框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54724399/

相关文章:

java - 向下和向上滑动 ListView 并附加数据(最初隐藏,然后单击后显示)

java - MySQL 中的文本版本控制

java - 限制 html JLabel 中的行数

java - 在Java中清除一组单选按钮

java - 如何向 JScrollPane 添加水平/垂直滚动条

javascript - 需要有关 Div 标签内 Img 的帮助显示在 flex 边框上方

html - 使部分div边框透明html

java - 当没有条件语句时,为什么我的 for 循环会跳过我的扫描仪函数之一

java - 从 Scala(或 Java)使用 python 代码的最佳方式是什么?

html - 带有背景图像的 thead 和 tfoot 中的边界半径