0

そこで、Timer と paint メソッドを使用して、1 秒ごとに線を回転させようとしています。しかし、何が起こっているのかよくわかりません。関連するメソッドの一部を次に示します。

public static ActionListener taskPerformer = new ActionListener() {

    public void actionPerformed(ActionEvent e) {
        Clock cl = new Clock();
        seconds++;
        cl.repaint();
    }
};


public void paint(Graphics g){
    super.paint(g);
    Graphics2D g2 = (Graphics2D) g;
    for(int c = 0; c<10; c++){
        g2.setPaint(Color.BLACK);
        g2.drawOval(90-c/2,90-c/2,500+c,500+c); //thick outlined circle
    }
    g2.setPaint(Color.WHITE);
    g2.fillOval(90,90,501,501);
    g2.setPaint(Color.BLACK);
    g2.rotate(Math.toRadians(seconds*6));
    g2.drawLine(340,340,340,90);    

}

線は静止したままです。ただし、追加すると

System.out.println("tick");

私のactionPerformedメソッドに対して、コマンドラインは1秒間に3回「ティック」を吐き出します。なぜこれらのことが起こっているのかについてのアイデアはありますか?

いくつかのコンテキスト:

public static int seconds = 0;
public static int minutes = 0;
public static int hours = 0;
public static Clock cl = new Clock();
private ActionListener taskPerformer = new ActionListener() {

    public void actionPerformed(ActionEvent e) {
        System.out.println("tick");
        seconds++;
        cl.repaint();
    }
};
public static Timer timer = new Timer(1000,taskPerformer);

public static void main(String[] args){
    Clock cl = new Clock();
    init();
    SwingUtilities.invokeLater(new Runnable(){
        public void run() {
            createAndShowGUI();
        }
    });
}
public static void init(){
    timer.start();
}
public Clock() {
    super("Clock");
    timer.addActionListener(taskPerformer);

}
4

1 に答える 1

1

ティックごとに新しいクロックを作成しています:

public void actionPerformed(ActionEvent e) {
    Clock cl = new Clock();
    ...

代わりに、既存のインスタンスを使用する必要があります。

// A field in the class:
Clock cl = new Clock();
...

// removed static so that it can access cl
private ActionListener taskPerformer = new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        seconds++;
        cl.repaint();
    }
};

他の場所にアクセスする必要がない場合は、クロックをアクション リスナーのフィールドにすることもできます。

paint()また、通常は をオーバーライドするべきではなく、代わりにオーバーライドする必要があることに注意してくださいpaintComponent()。Swing でのカスタム ペインティングの詳細については、こちらをご覧ください。

編集: より多くのコードが利用できるようになったので、クロックとアクション リスナーを静的にすれば動作するはずだと言えます。ただし、関連するコンポーネントの準備が整ったら、タイマーを開始する必要があります。

public static void main(String[] args){
    // Removed spurious clock here
    SwingUtilities.invokeLater(new Runnable(){
        public void run() {
            createAndShowGUI();
            // Start the timer once the components are ready
            init();
        }
    });
}

アクションリスナーでクロックを作成しないという上記のポイントは依然として有効です。

于 2013-09-15T17:29:46.393 に答える