用动画调整 JPanel 的大小

问题描述 投票:0回答:1

我想做一个面板,当鼠标进入它时,它的高度平滑增加,当鼠标离开它时,它的高度平滑减小。

public class Main {
    private static final int INITIAL_HEIGHT = 150;
    private static final int TARGET_HEIGHT = 200;
    private static final int ANIMATION_DELAY = 10;
    private static final int INCREMENT = 2;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);

            JPanel panel = new JPanel();
            panel.setPreferredSize(new Dimension(200, INITIAL_HEIGHT));
            panel.setBackground(Color.BLUE);

            frame.add(panel);
            frame.pack();

            panel.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseEntered(MouseEvent e) {
                    new Timer(ANIMATION_DELAY, new ActionListener() {
                        private int currentHeight = INITIAL_HEIGHT;

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            if (currentHeight < TARGET_HEIGHT) {
                                currentHeight += INCREMENT;
                                panel.setPreferredSize(new Dimension(200, currentHeight));
                                panel.revalidate();
                                frame.pack();
                            } else {
                                ((Timer) e.getSource()).stop();
                            }
                        }
                    }).start();
                }
                @Override
                public void mouseExited(MouseEvent e) {
                    new Timer(ANIMATION_DELAY, new ActionListener() {
                        private int currentHeight = TARGET_HEIGHT;

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            if (currentHeight > INITIAL_HEIGHT) {
                                currentHeight -= INCREMENT;
                                panel.setPreferredSize(new Dimension(200, currentHeight));
                                panel.revalidate();
                                frame.pack();
                            } else {
                                ((Timer) e.getSource()).stop();
                            }
                        }
                    }).start();
                }
            });
        });
    }
}

问题是,如果我在更改面板大小时将鼠标移出面板,则无法正常工作。

java swing jpanel
1个回答
0
投票

尝试仅使用一个计时器并添加一个布尔值来跟踪方向并确保动画沿一个方向发生

public class Main {
private static final int INITIAL_HEIGHT = 150;
private static final int TARGET_HEIGHT = 200;
private static final int ANIMATION_DELAY = 10;
private static final int INCREMENT = 2;

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setSize(300, 300); // Adjust frame size to better see the effect

        JPanel panel = new JPanel();
        panel.setPreferredSize(new Dimension(200, INITIAL_HEIGHT));
        panel.setBackground(Color.BLUE);

        frame.add(panel);
        frame.pack();
        frame.setVisible(true);

        Timer timer = new Timer(ANIMATION_DELAY, null);
        boolean growing = false;

        panel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                if (!growing) {
                    growing = true;
                    timer.removeActionListener(timer.getActionListeners()[0]);
                    timer.addActionListener(new ActionListener() {
                        private int currentHeight = panel.getPreferredSize().height;

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            if (currentHeight < TARGET_HEIGHT) {
                                currentHeight += INCREMENT;
                                panel.setPreferredSize(new Dimension(200, currentHeight));
                                panel.revalidate();
                                frame.pack();
                            } else {
                                timer.stop();
                            }
                        }
                    });
                    timer.start();
                }
            }

            @Override
            public void mouseExited(MouseEvent e) {
                if (growing) {
                    growing = false;
                    timer.removeActionListener(timer.getActionListeners()[0]);
                    timer.addActionListener(new ActionListener() {
                        private int currentHeight = panel.getPreferredSize().height;

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            if (currentHeight > INITIAL_HEIGHT) {
                                currentHeight -= INCREMENT;
                                panel.setPreferredSize(new Dimension(200, currentHeight));
                                panel.revalidate();
                                frame.pack();
                            } else {
                                timer.stop();
                            }
                        }
                    });
                    timer.start();
                }
            }
        });
    });
}}
© www.soinside.com 2019 - 2024. All rights reserved.