1

私は最近Javaを開始し、GridBagレイアウトを使用しながらアニメーションを作成できるかどうか疑問に思いました。

これらは可能であり、どのようにですか?チュートリアル、ヘルプなどは大歓迎です:)

4

2 に答える 2

10

このような種類のアニメーションを実行するには、何らかのプロキシ レイアウト マネージャーが必要になります。

すべてのコンポーネントの現在の位置、つまりレイアウト マネージャーが希望する位置を特定し、それらを所定の位置に移動する必要があります。

次の例は、基本的な考え方を示しています。アニメーション エンジンの使用は非常に基本的であり、スローインおよびスローアウトの基本機能は含まれていませんが、直線的なアプローチを使用しています。

public class TestAnimatedLayout {

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

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

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestAnimatedLayoutPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestAnimatedLayoutPane extends JPanel {

        public TestAnimatedLayoutPane() {
            setLayout(new AnimatedLayout(new GridBagLayout()));
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            add(new JLabel("Value:"), gbc);
            gbc.gridx++;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 1;
            add(new JComboBox(), gbc);

            gbc.gridx = 0;
            gbc.gridy++;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.gridwidth = 2;
            add(new JScrollPane(new JTextArea()), gbc);

            gbc.gridwidth = 0;
            gbc.gridy++;
            gbc.gridx++;
            gbc.weightx = 0;
            gbc.weighty = 0;
            gbc.fill = GridBagConstraints.NONE;
            gbc.anchor = GridBagConstraints.EAST;
            add(new JButton("Click"), gbc);
        }

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

    }

    public class AnimatedLayout implements LayoutManager2 {

        private LayoutManager2 proxy;
        private Map<Component, Rectangle> mapStart;
        private Map<Component, Rectangle> mapTarget;
        private Map<Container, Timer> mapTrips;
        private Map<Container, Animator> mapAnimators;

        public AnimatedLayout(LayoutManager2 proxy) {
            this.proxy = proxy;
            mapTrips = new WeakHashMap<>(5);
            mapAnimators = new WeakHashMap<>(5);
        }

        @Override
        public void addLayoutComponent(String name, Component comp) {
            proxy.addLayoutComponent(name, comp);
        }

        @Override
        public void removeLayoutComponent(Component comp) {
            proxy.removeLayoutComponent(comp);
        }

        @Override
        public Dimension preferredLayoutSize(Container parent) {
            return proxy.preferredLayoutSize(parent);
        }

        @Override
        public Dimension minimumLayoutSize(Container parent) {
            return proxy.minimumLayoutSize(parent);
        }

        @Override
        public void layoutContainer(Container parent) {
            Timer timer = mapTrips.get(parent);
            if (timer == null) {
                System.out.println("...create new trip");
                timer = new Timer(125, new TripAction(parent));
                timer.setRepeats(false);
                timer.setCoalesce(false);
                mapTrips.put(parent, timer);
            }
            System.out.println("trip...");
            timer.restart();
        }

        protected void doLayout(Container parent) {

            System.out.println("doLayout...");

            mapStart = new HashMap<>(parent.getComponentCount());

            for (Component comp : parent.getComponents()) {
                mapStart.put(comp, (Rectangle) comp.getBounds().clone());
            }

            proxy.layoutContainer(parent);

            LayoutConstraints constraints = new LayoutConstraints();
            for (Component comp : parent.getComponents()) {
                Rectangle bounds = comp.getBounds();
                Rectangle startBounds = mapStart.get(comp);
                if (!mapStart.get(comp).equals(bounds)) {
                    comp.setBounds(startBounds);
                    constraints.add(comp, startBounds, bounds);
                }
            }

            System.out.println("Items to layout " + constraints.size());
            if (constraints.size() > 0) {
                Animator animator = mapAnimators.get(parent);
                if (animator == null) {
                    animator = new Animator(parent, constraints);
                    mapAnimators.put(parent, animator);
                } else {
                    animator.setConstraints(constraints);
                }
                animator.restart();
            } else {
                if (mapAnimators.containsKey(parent)) {
                    Animator animator = mapAnimators.get(parent);
                    animator.stop();
                    mapAnimators.remove(parent);
                }
            }

        }

        @Override
        public void addLayoutComponent(Component comp, Object constraints) {
            proxy.addLayoutComponent(comp, constraints);
        }

        @Override
        public Dimension maximumLayoutSize(Container target) {
            return proxy.maximumLayoutSize(target);
        }

        @Override
        public float getLayoutAlignmentX(Container target) {
            return proxy.getLayoutAlignmentX(target);
        }

        @Override
        public float getLayoutAlignmentY(Container target) {
            return proxy.getLayoutAlignmentY(target);
        }

        @Override
        public void invalidateLayout(Container target) {
            proxy.invalidateLayout(target);
        }

        protected class TripAction implements ActionListener {

            private Container container;

            public TripAction(Container container) {
                this.container = container;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("...trip");
                mapTrips.remove(container);
                doLayout(container);
            }

        }

    }

    public class LayoutConstraints {

        private List<AnimationBounds> animationBounds;

        public LayoutConstraints() {
            animationBounds = new ArrayList<AnimationBounds>(25);
        }

        public void add(Component comp, Rectangle startBounds, Rectangle targetBounds) {

            add(new AnimationBounds(comp, startBounds, targetBounds));

        }

        public void add(AnimationBounds bounds) {

            animationBounds.add(bounds);

        }

        public int size() {
            return animationBounds.size();
        }

        public AnimationBounds[] getAnimationBounds() {

            return animationBounds.toArray(new AnimationBounds[animationBounds.size()]);

        }

    }

    public class AnimationBounds {

        private Component component;
        private Rectangle startBounds;
        private Rectangle targetBounds;

        public AnimationBounds(Component component, Rectangle startBounds, Rectangle targetBounds) {
            this.component = component;
            this.startBounds = startBounds;
            this.targetBounds = targetBounds;
        }

        public Rectangle getStartBounds() {
            return startBounds;
        }

        public Rectangle getTargetBounds() {
            return targetBounds;
        }

        public Component getComponent() {
            return component;
        }

        public Rectangle getBounds(float progress) {

            return calculateProgress(getStartBounds(), getTargetBounds(), progress);

        }

    }

    public static Rectangle calculateProgress(Rectangle startBounds, Rectangle targetBounds, float progress) {

        Rectangle bounds = new Rectangle();

        if (startBounds != null && targetBounds != null) {

            bounds.setLocation(calculateProgress(startBounds.getLocation(), targetBounds.getLocation(), progress));
            bounds.setSize(calculateProgress(startBounds.getSize(), targetBounds.getSize(), progress));

        }

        return bounds;

    }

    public static Point calculateProgress(Point startPoint, Point targetPoint, float progress) {

        Point point = new Point();

        if (startPoint != null && targetPoint != null) {

            point.x = calculateProgress(startPoint.x, targetPoint.x, progress);
            point.y = calculateProgress(startPoint.y, targetPoint.y, progress);

        }

        return point;

    }

    public static Dimension calculateProgress(Dimension startSize, Dimension targetSize, float progress) {

        Dimension size = new Dimension();

        if (startSize != null && targetSize != null) {

            size.width = calculateProgress(startSize.width, targetSize.width, progress);
            size.height = calculateProgress(startSize.height, targetSize.height, progress);

        }

        return size;

    }

    public static int calculateProgress(int startValue, int endValue, float fraction) {

        int value = 0;
        int distance = endValue - startValue;
        value = (int) ((float) distance * fraction);
        value += startValue;

        return value;

    }

    public class Animator implements ActionListener {

        private Timer timer;
        private LayoutConstraints constraints;
        private int tick;
        private Container parent;

        public Animator(Container parent, LayoutConstraints constraints) {
            setConstraints(constraints);
            timer = new Timer(16, this);
            timer.setRepeats(true);
            timer.setCoalesce(true);
            this.parent = parent;
        }

        private void setConstraints(LayoutConstraints constraints) {
            this.constraints = constraints;
        }

        public void restart() {
            tick = 0;
            timer.restart();
        }

        protected void stop() {
            timer.stop();
            tick = 0;
        }

        @Override
        public void actionPerformed(ActionEvent e) {

            tick += 16;
            float progress = (float)tick / (float)1000;
            if (progress >= 1f) {
                progress = 1f;
                timer.stop();
            }

            for (AnimationBounds ab : constraints.getAnimationBounds()) {
                Rectangle bounds = ab.getBounds(progress);
                Component comp = ab.getComponent();
                comp.setBounds(bounds);
                comp.invalidate();
                comp.repaint();
            }

            parent.repaint();

        }

    }

}

アップデート

AurelianRibbon/Sliding-Layoutもご覧ください。

于 2013-01-26T21:16:24.170 に答える
0

これは、クラスを始めたばかりの頃にずっと前に行ったプログラムです。Javaさまざまなタブで簡単なアニメーションを作成しましたJTabbedPane(必要に応じて画像/サウンドファイルのパスを変更します)。これが役立つことを願っています:

アップデート:

Swing で同時実行性に従っていないことについて申し訳ありません。

更新された回答は次のとおりです。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class ClassTestHello extends JApplet {
  private static JPanel j1;
  private JLabel jl;
  private JPanel j2;
  private Timer timer;
  private int i = 0;
  private int[] a = new int[10];

  @Override
  public void init() {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        start();
        paint();
      }
    });
  }

  public void paint() {
    jl = new JLabel("hiii");
    j1.add(jl);

    a[0] = 1000;
    a[1] = 800;
    a[2] = 900;
    a[3] = 2000;
    a[4] = 500;

    ActionListener actionListener = new ActionListener() {
      public void actionPerformed(ActionEvent actionEvent) {
        if(i % 2 == 0)
          jl.setText("hiii");
        else
          jl.setText("byee");

        i++;
        if(i > 4)
          i=0;
        timer.setDelay(a[i]);
      }
    };

    timer = new Timer(a[i], actionListener);
    timer.setInitialDelay(0);
    timer.start();
  }

  @Override
  public void start() {
    j1 = new JPanel();
    j2 = new JPanel();

    JTabbedPane jt1 = new JTabbedPane();

    ImageIcon ic = new ImageIcon("e:/guitar.gif");
    JLabel jLabel3 = new JLabel(ic);
    j2.add(jLabel3);

    jt1.add("one", j1);
    jt1.addTab("hii", j2);

    getContentPane().add(jt1);    
  } 
}
于 2013-01-26T18:51:23.973 に答える