gpt4 book ai didi

Java Swing JMenu 文本动画无法按预期工作

转载 作者:行者123 更新时间:2023-11-30 09:05:40 27 4
gpt4 key购买 nike

我需要为一些选定的菜单项及其相关菜单制作动画。到目前为止,我得到的解决方案适用于菜单项,但不适用于它们的父菜单。 (解决方案来源:Is it possible to make some items in the menu to fade in with 500 ms onset delay in Java?)。为了对 JMenus 产生同样的效果,我尝试做与 JMenuItems 动画解决方案中相同的事情(覆盖 addNotify() 和 removeNotify() 检查 FadeMenu 类)。

我的代码如下(你可以运行这段代码):

动画引擎.java

package aphemeralmenudemo;

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class FadeMenuDemo {

private AnimationEngine engine;

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

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

engine = new AnimationEngine();

JMenuBar mb = new JMenuBar();
JMenu Level1 = new JMenu("Level 1");
Level1.add("111");
Level1.add("222");
JMenu Level2 = new FadeMenu("Flip");
Level1.add(Level2);

Level2.add(new FadeMenuItem("Fade 1"));
Level2.add(new FadeMenuItem("Fade 2"));

Level2.add("Static 1");
Level2.add("Static 2");





mb.add(Level1);

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

测试面板.java

public class TestPane extends JPanel {

public TestPane() {
}

@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}

淡化菜单项.java

public class FadeMenuItem extends JMenuItem {

public FadeMenuItem(String text) {
super(text);
engine.addTimingListener(new TimingListener() {
@Override
public void timingEvent() {
repaint();
}
});
}

@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(engine.getAlpha()));
super.paintComponent(g2d);
g2d.dispose();
}

@Override
public void removeNotify() {
Container parent = getParent();
if (parent instanceof JPopupMenu) {
JPopupMenu menu = (JPopupMenu) parent;
engine.stop();
}
super.removeNotify();
}

@Override
public void addNotify() {
super.addNotify();
Container parent = getParent();
if (parent instanceof JPopupMenu) {
JPopupMenu menu = (JPopupMenu) parent;
engine.restart();
}
}
}

淡化菜单.java

public class FadeMenu extends JMenu{

public FadeMenu(String text) {
super(text);
engine.addTimingListener(new TimingListener() {
@Override
public void timingEvent() {
repaint();
}
});
}

@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(engine.getAlpha()));
super.paintComponent(g2d);
g2d.dispose();
}

@Override
public void removeNotify() {
Container parent = getParent();
if (parent instanceof JPopupMenu) {
JPopupMenu menu = (JPopupMenu) parent;
engine.stop();
}
super.removeNotify();
}

@Override
public void addNotify() {
super.addNotify();
Container parent = getParent();
if (parent instanceof JPopupMenu) {
JPopupMenu menu = (JPopupMenu) parent;
engine.restart();
}
}

}

定时监听器.java

public interface TimingListener {

public void timingEvent();
}

动画引擎.java

public class AnimationEngine {

private Timer fade;
private float alpha;
private long startTime;
private long duration = 1000;
private List<TimingListener> listeners;

public AnimationEngine() {
listeners = new ArrayList<>(5);
fade = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
long elapsed = System.currentTimeMillis() - startTime;
if (elapsed >= duration) {
((Timer) e.getSource()).stop();
alpha = 1f;
} else {
alpha = (float) elapsed / (float) duration;
}
fireTimingEvent();
}
});
fade.setRepeats(true);
fade.setCoalesce(true);
fade.setInitialDelay(500);
}

public void addTimingListener(TimingListener listener) {
listeners.add(listener);
}

public void removeTimingListener(TimingListener listener) {
listeners.add(listener);
}

protected void fireTimingEvent() {
for (TimingListener listener : listeners) {
listener.timingEvent();
}
}

public void restart() {
fade.stop();
alpha = 0;
fireTimingEvent();
startTime = System.currentTimeMillis();
fade.start();
}

public float getAlpha() {
return alpha;
}

public void stop() {
fade.stop();
}
}

覆盖的方法:

    @Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(engine.getAlpha()));
super.paintComponent(g2d);
g2d.dispose();
}

@Override
public void removeNotify() {
Container parent = getParent();
if (parent instanceof JPopupMenu) {
JPopupMenu menu = (JPopupMenu) parent;
engine.stop();
}
super.removeNotify();
}

@Override
public void addNotify() {
super.addNotify();
Container parent = getParent();
if (parent instanceof JPopupMenu) {
JPopupMenu menu = (JPopupMenu) parent;
engine.restart();
}
}

起初我看起来很好。菜单文本出现在动画中,但是当该动画菜单下的子项选择菜单文本时再次动画。这就是问题所在,我不想在选择子菜单时为菜单文本设置动画。在这方面我真的需要帮助。提前致谢。

最佳答案

This is the problem, I don't want to animate the menu text upon selecting it's submenu.

仅当菜单未被选中时调用repaint

示例代码:

public FadeMenu(String text) {
super(text);
engine.addTimingListener(new TimingListener() {
@Override
public void timingEvent() {
// This condition is added here to stop animation when selected
if (!isSelected()) {
repaint();
}
}
});
}

关于Java Swing JMenu 文本动画无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24790864/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com