85932


Javaで風車が回転するアニメーションを作成しています。  
元々は回転速度をTimerクラスを用いていたのですが、自分で好きな速さにできるように、  
JSliderでスライダーを追加しました。

スライダーを動かしたらそのスライダーの値がTimerクラスの引数になるようにして風車の回転速度を変更できるようにしたいのですがやり方がわかりません。  
どなたか教えていただけると幸いです。

以下、ソースを載せておきます。

MyController.java

[code]

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.Timer;
    
    public class MyController extends JFrame implements ActionListener,ChangeListener
    {
            private Timer timer;
            private MyView mp;
            private Image[]  chara_array;
            private MediaTracker tracker;
    
            private JSlider slider;
            private JLabel label;
            private JPanel panel;
    
    
            public MyController()
            {
                    this.slider = new JSlider();
    
    
                    this.timer = new Timer(90, this); // 0.5秒ごとにthisのactionPerformedメソッドを呼び出す様に設定
                    this.timer.start();                // タイマースタート
    
                    Toolkit tk = Toolkit.getDefaultToolkit();
                    this.tracker = new MediaTracker(this);
    
                    this.slider = new JSlider();
                    this.panel = new JPanel();
    
                    this.slider.setMaximum(5000); /* スライダの最大値 */
                    this.slider.addChangeListener(this);
    
                    this.label = new JLabel();
                    //label.setText("風の強さ：" + slider.getValue());
    
    
    
                    Image[] chara_array = new Image[3]; // Imageクラスの配列
                    for (int i = 0; i < 3; i++)
                            {
                                    chara_array[i] = tk.getImage("husya" + i + ".png"); // chara0.png, ..., chara9.png
                                    this.tracker.addImage(chara_array[i], 1);
                            }
    
                            this.mp = new MyView(chara_array);
    
                            mp.add(slider, BorderLayout.CENTER);
                            mp.add(label, BorderLayout.SOUTH);
    
    
                      super.getContentPane().add(this.mp);
    
            }
    
            public void actionPerformed(ActionEvent e){
                    System.out.println("in actionPerform: ");
                    this.mp.repaint(); // 描画パネル「に対して」再描画を指示する
                    Toolkit.getDefaultToolkit().sync(); // CentOSの不具合対策
            }
    
            public void stateChanged(ChangeEvent e0){
                    this.timer = new Timer(this.slider.getValue(), this);
                    this.timer.start();
                    this.label.setText("風の強さ：" + slider.getValue());
            }
    
    
    
            public static void main(String[] args) {
                MyController a = new MyController();
    
                a.setSize(1600,930);
                a.setLocation(0,0);
                //a.pack();
                a.setVisible(true);
            }
    }
    
[/code]

MyView.java

[code]

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    
    public class MyView extends JPanel
    {
            private int chara_i, chara_x, chara_y;
            private Image[] chara_array;
            private Image image;
            private Image sub;
    
    
            public MyView(Image[] chara_array)
            {
                    MyModel model = new MyModel(chara_array);
                    Toolkit tk = Toolkit.getDefaultToolkit();
                    //model.getImage();
                    this.image = tk.getImage("sogen.png");
                    this.sub = tk.getImage("asi.png");
                    //model.getChara_i();
                    //model.getChara_x();
                    //model.getChara_y();
                    this.chara_i = 0;
                    this.chara_x = 0;
                    this.chara_y = 0;
    
                    //model.setChara_array(chara_array);
                    this.chara_array = chara_array;
    
                    super.setPreferredSize(new Dimension(400, 400));
                    super.setBackground(Color.white);
    
    }
    
    
        /*  public void paint(Graphics g){
                Toolkit tk = Toolkit.getDefaultToolkit();
                Image image = tk.getImage("sogen2.png");
                g.drawImage(image,0,0,this);
            }*/
    
            public void paintComponent(Graphics g)
            {
                    System.out.println("in paintComponent: ");
    
    
                    super.paintComponent(g);
                    g.drawImage(image,0,0,this);
                    g.drawImage(sub,500,300,this);
    
                    /*g.drawImage(this.chara_array[this.chara_i], this.chara_x * 10 + 30, this.chara_y * 10 + 15, this);
                    g.drawImage(this.chara_array[this.chara_i], - this.chara_x * 10 + 530, -this.chara_y * 10 + 500, this);
                    g.drawImage(this.chara_array[this.chara_i], this.chara_x * 10 + 30, -this.chara_y * 10 + 500, this);
                    g.drawImage(this.chara_array[this.chara_i], - this.chara_x * 10 + 530, this.chara_y * 10 + 15, this);
                    */
    
                    g.drawImage(this.chara_array[this.chara_i], 500, 350, this);
                    g.drawImage(this.chara_array[this.chara_i], 500, 350, this);
                    g.drawImage(this.chara_array[this.chara_i], 500, 350, this);
                    g.drawImage(this.chara_array[this.chara_i], 500, 350, this);
    
    
    
    
                    this.chara_i++;
                    this.chara_x++;
                    this.chara_y++;
    
                    if(this.chara_i == 3){
                            this.chara_i = 0;
                    }
    /*
                    if((this.chara_x * 10 + 30) >= 550){
                            this.chara_x = 0;
                            this.chara_y = 0;
    
                    }
    */
    
            }
    }
    
[/code]

[![画像の説明をここに入力](https://i.stack.imgur.com/stzDO.jpg)](https://i.stack.imgur.com/stzDO.jpg)


CC BY-SA 4.0
2022-01-25T13:45:25.520
85927
2022-01-25T18:57:57.310
2022-01-25T16:27:24.427
3060
50923
question
java
Java JSliderとTimerクラスについて


スライダーの値が何を表すのか不明確でしたので、1分あたりの描画更新回数として改変していますが、概ね次のようなコードになるかと思います。

[code]

    public class MyController extends JFrame implements ActionListener,ChangeListener
    {
            // ...
    
            public MyController()
            {
                    // 0.5秒おきに1回呼び出し
                    final int initialValue = 500;
    
                    this.timer = new Timer(initialValue, this); // 0.5秒ごとにthisのactionPerformedメソッドを呼び出す様に設定
    
                    this.slider = new JSlider(1, 5000, initialValue);
                    this.slider.addChangeListener(this);
    
                    Toolkit tk = Toolkit.getDefaultToolkit();
                    this.tracker = new MediaTracker(this);
    
                    this.panel = new JPanel();
                    this.label = new JLabel();
    
                    Image[] chara_array = new Image[3]; // Imageクラスの配列
                    for (int i = 0; i < 3; i++)
                            {
                                    chara_array[i] = tk.getImage("husya" + i + ".png"); // chara0.png, ..., chara9.png
                                    this.tracker.addImage(chara_array[i], 1);
                            }
    
                            this.mp = new MyView(chara_array);
    
                            mp.add(slider, BorderLayout.CENTER);
                            mp.add(label, BorderLayout.SOUTH);
    
    
                      super.getContentPane().add(this.mp);
    
                      // 手動でイベント発火させることで初期状態設定
                      SwingUtilities.invokeLater(()-> stateChanged(new ChangeEvent(this.slider)));
            }
    
            // ...
    
            public void stateChanged(ChangeEvent e0){
                    // スライダーの値を基にタイマーを再設定
                    this.timer.setDelay(((JSlider)e0.getSource()).getValue());
                    this.timer.restart();
                    this.label.setText("風の強さ：" + slider.getValue());
            }
    
            // ...
    
         }
    
    }
    
[/code]

スライダーの値をそのままタイマーの delay
として採用するので、"風の強さ"というラベルに反して、実際には値を大きくすると更新頻度は低下します(要するに、値を大きくすると風が弱くなる)。

ここに違和感が有るようであれば、スライダー値の逆数を delay として採用するといったような対応が考えられます。


CC BY-SA 4.0
2022-01-25T18:57:57.310
85932
2022-01-25T18:57:57.310
2808
85927
answer