我工作在图形用户界面窗口与Swing,我想创建一个导航菜单。当鼠标悬停在导航菜单的按钮上时,我想给它们添加一个动画。
像这样的东西:

我不能使用鼠标侦听器,因为它只是在没有动画的情况下在颜色之间切换,就像这样

翻滚需要gif,不同的屏幕大小需要不同的gif大小。
有没有办法做到这一点呢?如何抛出代码?
发布于 2018-08-19 23:16:06
这是一个比MadProgrammer建议的简单得多的实现。它做了一些天真的假设,比如线性颜色插值。它也不会尝试动画颜色的alpha混合。而且它不支持响应键盘导航的动画。
内部Fader类使用javax.swing.Timer在一个方向上制作动画。为每个JMenuItem指定两个渐变对象,一个用于过渡到高光颜色,另一个用于过渡回常规背景颜色。
还有必要重写UI委托对象,因为大多数外观都希望强制使用自己的颜色,而不管JMenuItem的背景是什么,无论是在菜单项始终具有键盘焦点时都是如此。
import java.util.Objects;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.Timer;
import javax.swing.plaf.basic.BasicMenuItemUI;
public class FadingMenuTest {
private static final int animDurationMillis = 500;
private static final int frameCount = 8;
private static class Fader {
private final Component component;
private final Color normalBackground;
private final float[] normalRGBA;
private final float[] targetRGBA;
private final float[] rgba = new float[4];
private final Timer timer = new Timer(animDurationMillis / frameCount,
e -> updateBackground());
private int frameNumber;
Fader(Component component,
Color targetBackground,
Color normalBackground) {
this.component = Objects.requireNonNull(component);
this.normalBackground = normalBackground;
this.normalRGBA = normalBackground.getComponents(null);
this.targetRGBA = targetBackground.getComponents(null);
}
private void updateBackground() {
if (++frameNumber > frameCount) {
timer.stop();
return;
}
for (int i = rgba.length - 1; i >= 0; i--) {
float normal = normalRGBA[i];
float target = targetRGBA[i];
rgba[i] =
normal + (target - normal) * frameNumber / frameCount;
}
component.setBackground(
new Color(rgba[0], rgba[1], rgba[2], rgba[3]));
}
void start() {
frameNumber = 0;
timer.restart();
component.setBackground(normalBackground);
}
void stop() {
timer.stop();
component.setBackground(normalBackground);
}
}
static void addFadeOnHover(Component component,
Color targetBackground,
Color normalBackground) {
Fader entryFader =
new Fader(component, targetBackground, normalBackground);
Fader exitFader =
new Fader(component, normalBackground, targetBackground);
component.addMouseListener(new MouseAdapter() {
private static final long serialVersionUID = 1;
@Override
public void mouseEntered(MouseEvent event) {
exitFader.stop();
entryFader.start();
}
@Override
public void mouseExited(MouseEvent event) {
entryFader.stop();
exitFader.start();
}
});
}
static void show() {
Color foreground = Color.WHITE;
Color background = new Color(0, 0, 128);
Color highlight = Color.BLUE;
JPopupMenu menu = new JPopupMenu();
menu.setBackground(background);
menu.add(new JMenuItem(String.format("%c Backup", 0x1f5ce)));
menu.add(new JMenuItem(String.format("%c Screenshots", 0x1f5b5)));
menu.add(new JMenuItem("\u26ed Settings"));
// Most look-and-feels will override any colors we set, especially
// when a menu item is selected.
BasicMenuItemUI ui = new BasicMenuItemUI() {
{
selectionForeground = foreground;
selectionBackground = background;
}
@Override
public void paintBackground(Graphics g,
JMenuItem item,
Color background) {
super.paintBackground(g, item, item.getBackground());
}
};
for (Component item : menu.getComponents()) {
AbstractButton b = (AbstractButton) item;
b.setContentAreaFilled(false);
b.setOpaque(true);
b.setUI(ui);
item.setForeground(foreground);
item.setBackground(background);
addFadeOnHover(item, highlight, background);
}
JLabel label = new JLabel("Right click here");
label.setBorder(BorderFactory.createEmptyBorder(200, 200, 200, 200));
label.setComponentPopupMenu(menu);
JFrame frame = new JFrame("Fading Menu Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(label);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> show());
}
}https://stackoverflow.com/questions/51903228
复制相似问题