私は最近Javaを開始し、GridBagレイアウトを使用しながらアニメーションを作成できるかどうか疑問に思いました。
これらは可能であり、どのようにですか?チュートリアル、ヘルプなどは大歓迎です:)
私は最近Javaを開始し、GridBagレイアウトを使用しながらアニメーションを作成できるかどうか疑問に思いました。
これらは可能であり、どのようにですか?チュートリアル、ヘルプなどは大歓迎です:)
このような種類のアニメーションを実行するには、何らかのプロキシ レイアウト マネージャーが必要になります。
すべてのコンポーネントの現在の位置、つまりレイアウト マネージャーが希望する位置を特定し、それらを所定の位置に移動する必要があります。
次の例は、基本的な考え方を示しています。アニメーション エンジンの使用は非常に基本的であり、スローインおよびスローアウトの基本機能は含まれていませんが、直線的なアプローチを使用しています。
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もご覧ください。
これは、クラスを始めたばかりの頃にずっと前に行ったプログラムです。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);
}
}