1

GridLayout各グリッドに不透明なボタンがある8x8 のボード ゲームを作成しました。8x8 テーブルの形式で表示するように作成しました。ユーザーが任意のセルをクリックすると、何らかのアクションが実行されます。現在、グリッドは次のようになっています。

ここに画像の説明を入力

次のように、角度を付けてアニメーションを介してこれを再配置したい:

ここに画像の説明を入力

Swingを使用してこれを行うことは可能repaintですか? Swingそうでない場合、これをアニメーション化する以外に使用するより良いツールキットはありますか?

4

3 に答える 3

3

ライブ コンポーネントの状態を変更するには、ペイントするだけでは不十分です...

たとえば、Boannの例に基づいて...

ここに画像の説明を入力

Swing でのペイントは複雑で最適化されたプロセスであり、常に直線的に行われるわけではありません。

そうは言っても、方法はありますが、そのためには努力する必要があります。

ここに画像の説明を入力

これは、JXLayer API と pbjar の例に基づいています。

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jdesktop.jxlayer.JXLayer;
import org.pbjar.jxlayer.demo.TransformUtils;
import org.pbjar.jxlayer.plaf.ext.transform.DefaultTransformModel;

public class Twister02 {

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

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

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

    public class ExamplePane extends JPanel {

        private JSlider slider;
        private FieldPane fieldPane;
        private DefaultTransformModel transformModel;

        public ExamplePane() {

            setLayout(new BorderLayout());

            slider = new JSlider(0, 360);
            slider.setValue(0);
            slider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {

                    transformModel.setRotation(Math.toRadians(slider.getValue()));

                }
            });

            fieldPane = new FieldPane();

            transformModel = new DefaultTransformModel();
            transformModel.setRotation(Math.toRadians(0));
            transformModel.setScaleToPreferredSize(true);
            JXLayer<JComponent> rotatePane = TransformUtils.createTransformJXLayer(fieldPane, transformModel);

            add(slider, BorderLayout.NORTH);
            add(rotatePane);

        }
    }

    public class FieldPane extends JPanel {

        public FieldPane() {
            setLayout(new GridLayout(8, 8));
            for (int i = 0; i < 64; i++) {
                add(new JButton("" + i));
            }
        }

    }
}

さて、問題は、pbjar の例がインターネットの表面から消えてしまったようで、非常に残念なことです。

ただし、ここからコピーを取得できます

面白かったので追加…

ここに画像の説明を入力

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jdesktop.jxlayer.JXLayer;
import org.pbjar.jxlayer.demo.TransformUtils;
import org.pbjar.jxlayer.plaf.ext.transform.DefaultTransformModel;

public class Twister02 {

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

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

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

    public class ExamplePane extends JPanel {

        private JSlider rotateSlider;
        private JSlider shearXSlider;
        private JSlider shearYSlider;
        private FieldPane fieldPane;
        private DefaultTransformModel transformModel;

        public ExamplePane() {

            setLayout(new BorderLayout());

            rotateSlider = new JSlider(0, 180);
            rotateSlider.setValue(0);
            rotateSlider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {

                    transformModel.setRotation(Math.toRadians(rotateSlider.getValue()));

                }
            });
            shearXSlider = new JSlider(-100, 100);
            shearXSlider.setValue(0);
            shearXSlider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {

                    double value = shearXSlider.getValue() / 200d;
                    transformModel.setShearX(value);

                }
            });
            shearYSlider = new JSlider(-100, 100);
            shearYSlider.setValue(0);
            shearYSlider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {

                    double value = shearYSlider.getValue() / 200d;
                    transformModel.setShearY(value);

                }
            });

            fieldPane = new FieldPane();

            transformModel = new DefaultTransformModel();
            transformModel.setRotation(Math.toRadians(0));
            transformModel.setScaleToPreferredSize(true);
            JXLayer<JComponent> rotatePane = TransformUtils.createTransformJXLayer(fieldPane, transformModel);

            JPanel sliders = new JPanel(new GridLayout(3, 0));
            sliders.add(rotateSlider);
            sliders.add(shearXSlider);
            sliders.add(shearYSlider);

            add(sliders, BorderLayout.NORTH);
            add(rotatePane);

        }
    }

    public class FieldPane extends JPanel {

        public FieldPane() {
            setLayout(new GridLayout(8, 8));
            for (int i = 0; i < 64; i++) {
                add(new JButton("" + i));
            }
        }

    }
}
于 2013-11-04T04:15:17.407 に答える
1

コンテナーのpaintChildrenメソッドをオーバーライドして、Graphics オブジェクトに変換を適用してから呼び出しますsuper.paintChildren。ボタン グリッドを中心を中心に少し回転させる簡単な例:

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridLayout(8, 8)) {
    @Override
    public void paintChildren(Graphics g1) {
        Graphics2D g = (Graphics2D)g1;
        g.rotate(0.3, getWidth() / 2, getHeight() / 2);
        super.paintChildren(g);
    }
};
frame.add(panel);
for (int i = 0; i < 64; i++) panel.add(new JButton("" + i));

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

それはどのように見えるか(前/後):

ここに画像の説明を入力

編集: 巧妙に見えますが、これらのボタンを回転した位置で実際にクリックすることはできません。AffineTransform オブジェクトを使用してマウス イベントを変換し、それらを正しい子の正しいコンポーネントにリダイレクトすることはおそらく可能ですが、試したことはありません。再描画領域にも問題がある可能性があります。...独自のグリッドを描画すると(@Masudの回答)、Swingの上でこの機能をハックしようとするのを避けることができます。

于 2013-11-04T03:56:51.360 に答える
0

再描画を使用してSwingでこれを行うことは可能ですか? そうでない場合、これをアニメーション化できるように、Swing 以外に使用するより良いツールキットはありますか?

いいえ、できませんGridLayout。でグラフィックスを使用し、JPaneldrawLineアニメーション化しTimerます。

于 2013-11-04T03:32:34.083 に答える