Java滑动JPanels

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23785804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 01:12:21  来源:igfitidea点击:

Java sliding JPanels

javaanimationslideeffects

提问by spongyboss

I have a menu that has a variety of buttons on display, I'm able to make the buttons call their respective JPanels when clicked. The thing is I would like to make the Jpanel slide in when its called instead of instantaneously popping in. I tried using tween engine and as Java beginner, I find it really overwhelming, so I decided to use timed animation. I was able to make the Jpanel on top to slide to one side but for some reason the next panel doesn't want to display, im really tired, can someone help please! There code is below:

我有一个显示各种按钮的菜单,我可以让按钮在单击时调用它们各自的 JPanel。问题是我想让 Jpanel 在它被调用时滑入而不是立即弹出。我尝试使用 tween 引擎,作为 Java 初学者,我发现它真的让人不知所措,所以我决定使用定时动画。我能够让顶部的 Jpanel 滑动到一侧,但由于某种原因下一个面板不想显示,我真的很累,有人可以帮忙吗!有代码如下:

public class Listener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {

        new Timer(0, new ActionListener() {
           public void actionPerformed(ActionEvent e) {                

              mainpane.setLocation(mainpane.getX() - 10, 0);
              if (mainpane.getX() + mainpane.getWidth() == 0) 
              {
                 ((Timer) e.getSource()).stop();
                   System.out.println("Timer stopped");
              } 
           }
        }).start();   
   } 
}

采纳答案by Java42

Sliding panels can be tricky. Here is some starter code. Modify to fit your needs. Add error checking and exception handling as necessary.

滑动面板可能很棘手。这是一些入门代码。修改以满足您的需求。根据需要添加错误检查和异常处理。

This example uses JButtons and a JTree as content but you can use just about any type of content.

此示例使用 JButton 和 JTree 作为内容,但您几乎可以使用任何类型的内容。

Example Slider

示例滑块

Usage:

用法:

static public void main(final String[] args) throws Exception {
    SwingUtilities.invokeAndWait(new Runnable() {
        @Override
        public void run() {
            final JFrame jFrame = new JFrame() {
                {
                    final PanelSlider42<JFrame> slider = new PanelSlider42<JFrame>(this);
                    final JPanel jPanel = slider.getBasePanel();

                    slider.addComponent(new JButton("1"));
                    slider.addComponent(new JButton("22"));
                    slider.addComponent(new JButton("333"));
                    slider.addComponent(new JButton("4444"));

                    getContentPane().add(jPanel);
                    setSize(300, 300);
                    setLocationRelativeTo(null);
                    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    setVisible(true);
                }
            };
        }
    });
}

The impl is lengthy ...

impl 很长...

package com.java42.example.code;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;

public class PanelSlider42<ParentType extends Container> {

private static final int           RIGHT             = 0x01;
private static final int           LEFT              = 0x02;
private static final int           TOP               = 0x03;
private static final int           BOTTOM            = 0x04;
private final JPanel               basePanel         = new JPanel();
private final ParentType           parent;
private final Object               lock              = new Object();
private final ArrayList<Component> jPanels           = new ArrayList<Component>();
private final boolean              useSlideButton    = true;
private boolean                    isSlideInProgress = false;

private final JPanel               glassPane;
{
    glassPane = new JPanel();
    glassPane.setOpaque(false);
    glassPane.addMouseListener(new MouseAdapter() {
    });
    glassPane.addMouseMotionListener(new MouseMotionAdapter() {
    });
    glassPane.addKeyListener(new KeyAdapter() {
    });
}

public PanelSlider42(final ParentType parent) {
    if (parent == null) {
        throw new RuntimeException("ProgramCheck: Parent can not be null.");
    }
    if ((parent instanceof JFrame) || (parent instanceof JDialog) || (parent instanceof JWindow) || (parent instanceof JPanel)) {
    }
    else {
        throw new RuntimeException("ProgramCheck: Parent type not supported. " + parent.getClass().getSimpleName());
    }
    this.parent = parent;
    attach();
    basePanel.setSize(parent.getSize());
    basePanel.setLayout(new BorderLayout());
    if (useSlideButton) {
        final JPanel statusPanel = new JPanel();
        basePanel.add(statusPanel, BorderLayout.SOUTH);
        statusPanel.add(new JButton("Slide Left") {
            private static final long serialVersionUID = 9204819004142223529L;
            {
                setMargin(new Insets(0, 0, 0, 0));
            }
            {
                addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(final ActionEvent e) {
                        slideLeft();
                    }
                });
            }
        });
        statusPanel.add(new JButton("Slide Right") {
            {
                setMargin(new Insets(0, 0, 0, 0));
            }
            private static final long serialVersionUID = 9204819004142223529L;
            {
                addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(final ActionEvent e) {
                        slideRight();
                    }
                });
            }
        });
        statusPanel.add(new JButton("Slide Up") {
            {
                setMargin(new Insets(0, 0, 0, 0));
            }
            private static final long serialVersionUID = 9204819004142223529L;
            {
                addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(final ActionEvent e) {
                        slideTop();
                    }
                });
            }
        });
        statusPanel.add(new JButton("Slide Down") {
            {
                setMargin(new Insets(0, 0, 0, 0));
            }
            private static final long serialVersionUID = 9204819004142223529L;
            {
                addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(final ActionEvent e) {
                        slideBottom();
                    }
                });
            }
        });
    }
}

public JPanel getBasePanel() {
    return basePanel;
}

private void attach() {
    final ParentType w = this.parent;
    if (w instanceof JFrame) {
        final JFrame j = (JFrame) w;
        if (j.getContentPane().getComponents().length > 0) {
            throw new RuntimeException("ProgramCheck: Parent already contains content.");
        }
        j.getContentPane().add(basePanel);
    }
    if (w instanceof JDialog) {
        final JDialog j = (JDialog) w;
        if (j.getContentPane().getComponents().length > 0) {
            throw new RuntimeException("ProgramCheck: Parent already contains content.");
        }
        j.getContentPane().add(basePanel);
    }
    if (w instanceof JWindow) {
        final JWindow j = (JWindow) w;
        if (j.getContentPane().getComponents().length > 0) {
            throw new RuntimeException("ProgramCheck: Parent already contains content.");
        }
        j.getContentPane().add(basePanel);
    }
    if (w instanceof JPanel) {
        final JPanel j = (JPanel) w;
        if (j.getComponents().length > 0) {
            throw new RuntimeException("ProgramCheck: Parent already contains content.");
        }
        j.add(basePanel);
    }
}

public void addComponent(final Component component) {
    if (jPanels.contains(component)) {
    }
    else {
        jPanels.add(component);
        if (jPanels.size() == 1) {
            basePanel.add(component);
        }
        component.setSize(basePanel.getSize());
        component.setLocation(0, 0);
    }
}

public void removeComponent(final Component component) {
    if (jPanels.contains(component)) {
        jPanels.remove(component);
    }
}

public void slideLeft() {
    slide(LEFT);
}

public void slideRight() {
    slide(RIGHT);
}

public void slideTop() {
    slide(TOP);
}

public void slideBottom() {
    slide(BOTTOM);
}

private void enableUserInput(final ParentType w) {
    if (w instanceof JFrame) {
        ((JFrame) w).getGlassPane().setVisible(false);
    }
    if (w instanceof JDialog) {
        ((JDialog) w).getGlassPane().setVisible(false);
    }
    if (w instanceof JWindow) {
        ((JWindow) w).getGlassPane().setVisible(false);
    }
}

private void disableUserInput(final ParentType w) {
    if (w instanceof JFrame) {
        ((JFrame) w).setGlassPane(glassPane);
    }
    if (w instanceof JDialog) {
        ((JDialog) w).setGlassPane(glassPane);
    }
    if (w instanceof JWindow) {
        ((JWindow) w).setGlassPane(glassPane);
    }
    glassPane.setVisible(true);
}

private void enableTransparentOverylay() {
    if (parent instanceof JFrame) {
        ((JFrame) parent).getContentPane().setBackground(jPanels.get(0).getBackground());
        parent.remove(basePanel);
        parent.validate();
    }
    if (parent instanceof JDialog) {
        ((JDialog) parent).getContentPane().setBackground(jPanels.get(0).getBackground());
        parent.remove(basePanel);
        parent.validate();
    }
    if (parent instanceof JWindow) {
        ((JWindow) parent).getContentPane().setBackground(jPanels.get(0).getBackground());
        parent.remove(basePanel);
        parent.validate();
    }
}

private void slide(final int slideType) {
    if (!isSlideInProgress) {
        isSlideInProgress = true;
        final Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                disableUserInput(parent);
                slide(true, slideType);
                enableUserInput(parent);
                parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                isSlideInProgress = false;
            }
        });
        t0.setDaemon(true);
        t0.start();
    }
    else {
        Toolkit.getDefaultToolkit().beep();
    }
}

private void slide(final boolean useLoop, final int slideType) {
    if (jPanels.size() < 2) {
        System.err.println("Not enough panels");
        return;
    }
    synchronized (lock) {
        Component componentOld = null;
        Component componentNew = null;
        if ((slideType == LEFT) || (slideType == TOP)) {
            componentNew = jPanels.remove(jPanels.size() - 1);
            componentOld = jPanels.get(0);
            jPanels.add(0, componentNew);
        }
        if ((slideType == RIGHT) || (slideType == BOTTOM)) {
            componentOld = jPanels.remove(0);
            jPanels.add(componentOld);
            componentNew = jPanels.get(0);
        }
        final int w = componentOld.getWidth();
        final int h = componentOld.getHeight();
        final Point p1 = componentOld.getLocation();
        final Point p2 = new Point(0, 0);
        if (slideType == LEFT) {
            p2.x += w;
        }
        if (slideType == RIGHT) {
            p2.x -= w;
        }
        if (slideType == TOP) {
            p2.y += h;
        }
        if (slideType == BOTTOM) {
            p2.y -= h;
        }
        componentNew.setLocation(p2);
        int step = 0;
        if ((slideType == LEFT) || (slideType == RIGHT)) {
            step = (int) (((float) parent.getWidth() / (float) Toolkit.getDefaultToolkit().getScreenSize().width) * 40.f);
        }
        else {
            step = (int) (((float) parent.getHeight() / (float) Toolkit.getDefaultToolkit().getScreenSize().height) * 20.f);
        }
        step = step < 5 ? 5 : step;
        basePanel.add(componentNew);
        basePanel.revalidate();
        if (useLoop) {
            final int max = (slideType == LEFT) || (slideType == RIGHT) ? w : h;
            final long t0 = System.currentTimeMillis();
            for (int i = 0; i != (max / step); i++) {
                switch (slideType) {
                    case LEFT: {
                        p1.x -= step;
                        componentOld.setLocation(p1);
                        p2.x -= step;
                        componentNew.setLocation(p2);
                        break;
                    }
                    case RIGHT: {
                        p1.x += step;
                        componentOld.setLocation(p1);
                        p2.x += step;
                        componentNew.setLocation(p2);
                        break;
                    }
                    case TOP: {
                        p1.y -= step;
                        componentOld.setLocation(p1);
                        p2.y -= step;
                        componentNew.setLocation(p2);
                        break;
                    }
                    case BOTTOM: {
                        p1.y += step;
                        componentOld.setLocation(p1);
                        p2.y += step;
                        componentNew.setLocation(p2);
                        break;
                    }
                    default:
                        new RuntimeException("ProgramCheck").printStackTrace();
                        break;
                }

                try {
                    Thread.sleep(500 / (max / step));
                } catch (final Exception e) {
                    e.printStackTrace();
                }
            }
            final long t1 = System.currentTimeMillis();
        }
        componentOld.setLocation(-10000, -10000);
        componentNew.setLocation(0, 0);
    }
}
}

回答by Andrew_Dublin

I have searched for that problem some time ago.I found this sample code somewhere - saved in my evernote for future reference. This is the shortest way to implement that when I googled that in the past

我前段时间搜索过这个问题。我在某处找到了这个示例代码 - 保存在我的印象笔记中以备将来参考。这是实现这一点的最短方法,当我过去用谷歌搜索时

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class SlidingPanel {

   JPanel panel;

   public void makeUI() {
      panel = new JPanel();
      panel.setBackground(Color.RED);
      panel.setBounds(0, 0, 400, 400);

      JButton button = new JButton("Click");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            ((JButton) e.getSource()).setEnabled(false);
            new Timer(1, new ActionListener() {
               public void actionPerformed(ActionEvent e) {
                  panel.setLocation(panel.getX() - 1, 0);
                  if (panel.getX() + panel.getWidth() == 0) {
                     ((Timer) e.getSource()).stop();
               System.out.println("Timer stopped");
            }
               }
            }).start();
         }
      });
      panel.add(button);
      JFrame frame = new JFrame("Sliding Panel");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(400, 400);
      frame.setLocationRelativeTo(null);
      frame.setLayout(null);
      frame.add(panel);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            new SlidingPanel().makeUI();
         }
      });
   }
}