Java 实现动态边界
我正在尝试实现一个动态边框,从中心开始,一直延伸到边缘,在组件的顶部和底部绘制两条线(确切地说,代码中是四条线) 我曾尝试实现Java 实现动态边界,java,swing,border,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.Graphics2
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;
}
}
导入java.awt.Color;
导入java.awt.Component;
导入java.awt.Dimension;
导入java.awt.GradientPaint;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Insets;
导入javax.swing.border.border;
公共类BorderEffect实现了Border{
公共边界效果(c色){
col=c;
}
私人色彩;
私有图形g;
组分c;
专用颜色渐变(颜色基础)
{
返回新颜色(base.getRed(),base.getGreen(),base.getBlue(),70);
}
@凌驾
公共空白画框(组件c、图形g、整数x、整数y、整数宽度、整数高度){
这个.g=g;
这个.c=c;
}
public void go()抛出InterruptedException
{
维度大小=c.getSize();
对于(int i=0;i
我确实将边框添加到了JPanel
中,并在MouseAdapter
中调用了go
方法。但什么也没出现,我甚至不知道缺陷在哪里
我想知道的是:-
下面是一个例子,我的意思是——使用摆动计时器来设置边框的动画。注意,为了安全起见,我扩展了AbstractBorder,以防此类中包含任何内务代码。计时器递增索引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());
}
}
下面是一个例子,我的意思是——使用摆动计时器来设置边框的动画。注意,为了安全起见,我扩展了AbstractBorder,以防此类中包含任何内务代码。计时器递增索引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());
}
}
这不是Swing图形/绘制的方式。不要将图形对象保存为类的字段,也不要从绘制代码中调用
repaint()
。相反,在paintBorder覆盖内执行所有绘制,使用类的状态来决定绘制什么。此外,决不应在事件线程上调用Thread.sleep
(所有绘制都必须在事件线程上完成)。如果您需要延迟或动画,请使用Swing计时器。事实上,您的paintBorder方法不会进行任何绘制,完全破坏了它的预期行为我确实使用了重绘,因为我的代码超出了重绘将使用的任何方法,所以我不会受到StackOverFlowException
的影响,我完全了解swing线程系统,但有点等着代码完全生效后再修改它,,,而且在使用paintBorder
时,它不会产生我想要的动画。Swing graphics/painting不是这样做的。不要将图形对象保存为类的字段,也不要从绘制代码中调用repaint()
。相反,在paintBorder覆盖内执行所有绘制,使用类的状态来决定绘制什么。此外,决不应在事件线程上调用Thread.sleep
(所有绘制都必须在事件线程上完成)。如果您需要延迟或动画,请使用Swing计时器。事实上,您的paintBorder方法不会进行任何绘制,完全破坏了它的预期行为我确实使用了重绘,因为我的代码超出了重绘将使用的任何方法,所以我不会受到StackOverFlowException
的影响,我完全了解swing线程系统,但有点等着代码完全生效后再修改它,,,而且在使用paintBorder
时,它不会使我想要的动画变得令人悲伤。这与我期望的不同,但却很有效!谢谢但我注意到一些渐变的行为像一个正常的颜色?你能指出为什么吗???@alovelyperson我不确定你期望的是什么,你试图创造什么效果,我所做的只是从for循环复制你的代码,并用计时器替换循环。我试图实现的与mozilla fire fox taps动画类似。当您将鼠标移动到点击标签时,它会在顶部创建一条从ce展开的线