java - 实现动态边框
问题描述
我正在尝试实现一个动态边框,它在 Component 顶部和底部绘制两条线(确切地说是四条线),当鼠标进入时,从中心开始直到它展开到边缘。
我试图实施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;
}
}
我确实将边框添加到 aJPanel
并在 a 中调用了a中的go
方法。但是什么都没有出现,我什至不知道哪里有缺陷。mouseEntered
MouseAdapter
我想知道的是:-
- 问题出在哪里?
- 如何让线条在我想要的时候消失?
解决方案
这是我的意思的一个例子——使用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;
}
}
推荐阅读
- javascript - 我的链接不工作它不会进入当前会话它会自动回家
- node.js - SequelizeJS:在表中获取最小 ID 和最大 ID 的最佳方法
- laravel - 安装版本:不适用
- python - 我正在尝试下一步格式化下拉菜单,但它似乎并没有让我
- arrays - pq: 函数 unnest(unknown) 不是唯一的
- java - 如何改进我的井字游戏设计?
- python - 如何在 Python 和 pyzbar 中检测 QR 码的顶部边缘
- docker - 如何为 java 和 chromedriver 构建 docker 镜像?
- django - passing multiple values from select tag of html
- matlab - 在 Matlab 中使用 ODE 表示热模型