Java swing zegar ruch po okręgu


(marcinkk) #1

witam, chcę zaprogramować zegar ze wskazówkami, mam problem z określeniem współrzędnych x i y punktów na okręgu po którym się poruszają wskazówki zegara, próbuje najpierw zaprogramować wskazówkę sekundową ale mam problem z tym żeby wskazówka poruszała się co sekundę czyli 6 stopni no i zaczynała się poruszać od godziny 12 ale to tylko kwestia właściwej wartości początkowej licznika, chciałem się dowiedzieć czy wzory z których korzystam są poprawne i co źle robię.

/*

 * To change this template, choose Tools | Templates

 * and open the template in the editor.

 */

package javaswingzegarv2;


import java.awt.Dimension;

import java.awt.Graphics;

import java.awt.GridLayout;

import java.awt.Point;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.Timer;


/**

 *

 * @author marcin kaszuba

 */

public class ZegarGui extends JFrame{


    private JPanel jPanel = new JPanel();

    private GridLayout gridLayout = new GridLayout(1, 1);

    private int width = 400;

    private int height = 400;

    private int pozycja_okna_x = 500;

    private int pozycja_okna_y = 200;

    private Timer timer;

    private double i = 0, x = 0, y = 0;


    public ZegarGui(){

        setTitle("zegar wskazowkowy !");

        setLocation(new Point(pozycja_okna_x, pozycja_okna_y));

        setPreferredSize(new Dimension(width, height));

        pack();

        setVisible(true);

        setResizable(false);

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        add(jPanel);


        jPanel.setLayout(gridLayout);


        timer = new Timer(1000, new ActionListener() {


            @Override

            public void actionPerformed(ActionEvent e) {

                repaint();

            }

        });

        timer.start();

    }


    //@Override

    //public void actionPerformed(ActionEvent e) {

    //}


    @Override

    public void paint(Graphics graphics)throws NumberFormatException{

        double x2, y2;

        x2 = 200 + Math.cos(x++) * 140;

        y2 = 200 + Math.sin(y++) * 140;

        graphics.fillRoundRect(190, 190, 20, 20, 360, 360);//okrag

        graphics.drawRoundRect(50, 50, 300, 300, 360, 360);//srodek

        //graphics.drawLine(200, 200, 200, 70);//wskazowka minutowa

        //graphics.drawLine(200, 200, 100, 180);//wskazowka godzinowa

        graphics.drawLine(200, 200, (int)x2, (int)y2);

    }


}

//x = a + cos(alfa) * r

//y = b + sin(alfa) * r


/*

 * To change this template, choose Tools | Templates

 * and open the template in the editor.

 */

package javaswingzegarv2;


import javax.swing.SwingUtilities;


/**

 *

 * @author marcin

 */

public class JavaSwingZegarV2 {


    /**

     * @param args the command line arguments

     */

    public static void main(String[] args) {

        // TODO code application logic here

        SwingUtilities.invokeLater(new Runnable() {


            @Override

            public void run() {

                ZegarGui zegarGui = new ZegarGui();

            }

        });

    }

}[/code]

(kostek135) #2
Nieaktualne...

Wskazówki będą odrobinę krzywe, bo PI jest niewymierne i dla dyskretnego komputera nie do ogarnięcia :wink: Aczkolwiek lepsza dokładność może pomóc.


(marcinkk) #3

ruch po okręgu to materiał z gimnazjum i z liceum, ale niestety wiedza ta ulotniła mi się ;D

-- Dodane 28.06.2012 (Cz) 12:56 --

możesz mi objaśnić ten wzór albo wysłać link do jakieś strony??


(kostek135) #4
x2 = 200 + Math.cos(Math.PI / 30 * (x)) * 140;

y2 = 200 + Math.sin(Math.PI / 30 * (x++)) * 140;

zapisz tak a x ustaw na 45 będzie mniej obliczeń.

Wejdź na jakąkolwiek stronę o geometrii, myślałeś, źe podawałeś miarę stopniową jak mniemam, musimy podawać miarę łukową.


(marcinkk) #5

jak mam zastosować radiany do określenia współrzędnych końca odcinka?? chciałbym żeby mi ktoś to łopatologicznie wyjaśnił ;(


(kostek135) #6

Nie masz, radiany są tylko potrzebne do wyznaczenia kąta.Wyobraź sobie, że funkcje trygonometryczne zakreślają okrąg o promieniu jednostkowym (bierze się to z jedynki trygonometrycznej). Potem ten wektor jednostkowy skalujesz, aby uzyskać dłuższą "wskazówkę".


(marcinkk) #7

wstawiam poprawiony kod, mam jeszcze tylko problem z ustawieniem jLabela na właściwej pozycji żeby wypisać godziny od 1 do 12 przy kreskach. mam pomysł żeby stworzyć 12 JLabelów i za pomocą metody setBounds ustawiać pozycję, pozycje x i y pobierac z katRadKreski = 2.0 * Math.PI * (i / 60.0) - (Math.PI / 2.0); x1Kreski = (int)(150 * (Math.cos(katRadKreski))); y1Kreski = (int)(150 * (Math.sin(katRadKreski))); Prosiłbym o rady :wink: o to kod, działa wszystko prócz wypisywania godzin od 1 do 12

/*

 * To change this template, choose Tools | Templates

 * and open the template in the editor.

 */

package javaswingzegarv2;


import java.awt.Dimension;

import java.awt.Graphics;

import java.awt.GridLayout;

import java.awt.Point;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.GregorianCalendar;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.Timer;


/**

 *

 * @author marcin kaszuba

 */

public class ZegarGui extends JFrame{


    private JPanel jPanel = new JPanel();

    private GridLayout gridLayout = new GridLayout(1, 1);

    private JLabel jLabel = new JLabel();

    private int width = 400;

    private int height = 400;

    private int pozycja_okna_x = 500;

    private int pozycja_okna_y = 200;

    private Timer timer;

    private int j = 0, x2Sekundy, y2Sekundy, x2Minuty, y2Minuty, x2Godziny, y2Godziny, x1Kreski, y1Kreski, x2Kreski, y2Kreski;

    private double katRadSekund, katRadMinut, katRadGodzin, katRadKreski, sekundy, minuty, godziny;


    public ZegarGui(){

        setTitle("zegar wskazowkowy !");

        setLocation(new Point(pozycja_okna_x, pozycja_okna_y));

        setPreferredSize(new Dimension(width, height));

        pack();

        setVisible(true);

        setResizable(false);

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        add(jPanel);


        jPanel.setLayout(gridLayout);

        jPanel.add(jLabel);


        timer = new Timer(1000, new ActionListener() {


            @Override

            public void actionPerformed(ActionEvent e) {

                repaint();

            }

        });

        timer.start();

    }


    @Override

    public void paint(Graphics graphics){

        super.paint(graphics);

        GregorianCalendar gregorianCalendar = new GregorianCalendar();


        graphics.fillRoundRect(190, 190, 20, 20, 360, 360);//okrag

        graphics.drawRoundRect(50, 50, 300, 300, 360, 360);//srodek

        for(int i = 0; i < 60; ++i){

            if( i % 5 == 0){

                katRadKreski = 2.0 * Math.PI * (i / 60.0) - (Math.PI / 2.0);

                x1Kreski = (int)(150 * (Math.cos(katRadKreski)));

                y1Kreski = (int)(150 * (Math.sin(katRadKreski)));

                x2Kreski = (int)(130 * (Math.cos(katRadKreski)));

                y2Kreski = (int)(130 * (Math.sin(katRadKreski)));

                graphics.drawLine(200 + x1Kreski, 200 + y1Kreski, 200 + x2Kreski, 200 + y2Kreski);//kreska wskaznikowa

                //jLabel.setText(String.valueOf(++j));

                //jLabel.setBounds(200 + x1Kreski, 200 + y1Kreski, 8, 8);

            } else {

                katRadKreski = 2.0 * Math.PI * (i / 60.0) - (Math.PI / 2.0);

                x1Kreski = (int)(150 * (Math.cos(katRadKreski)));

                y1Kreski = (int)(150 * (Math.sin(katRadKreski)));

                x2Kreski = (int)(140 * (Math.cos(katRadKreski)));

                y2Kreski = (int)(140 * (Math.sin(katRadKreski)));

                graphics.drawLine(200 + x1Kreski, 200 + y1Kreski, 200 + x2Kreski, 200 + y2Kreski);//kreska wskaznikowa

            }

        }


        sekundy = gregorianCalendar.getTime().getSeconds();

        minuty = gregorianCalendar.getTime().getMinutes();

        godziny = gregorianCalendar.getTime().getHours();


        katRadSekund = 2.0 * Math.PI * (sekundy / 60.0) - (Math.PI / 2.0);

        katRadMinut = 2.0 * Math.PI * (minuty / 60.0) - (Math.PI / 2.0);

        katRadGodzin = 2.0 * Math.PI * ((godziny * 60.0 * 60.0 + minuty * 60.0 + sekundy) / 43200.0) - (Math.PI / 2.0);


        x2Sekundy = (int)(140 * (Math.cos(katRadSekund)));

        y2Sekundy = (int)(140 * (Math.sin(katRadSekund)));


        x2Minuty = (int)(125 * (Math.cos(katRadMinut)));

        y2Minuty = (int)(125 * (Math.sin(katRadMinut)));


        x2Godziny = (int)(100 * (Math.cos(katRadGodzin)));

        y2Godziny = (int)(100 * (Math.sin(katRadGodzin)));


        graphics.drawLine(200, 200, 200 + x2Sekundy, 200 + y2Sekundy);//wskazowka sekundowa

        graphics.drawLine(200, 200, 200 + x2Minuty, 200 + y2Minuty);//wskazowka minutowa

        graphics.drawLine(200, 200, 200 + x2Godziny, 200 + y2Godziny);//wskazowka godzinowa

    }


}

/*

 * To change this template, choose Tools | Templates

 * and open the template in the editor.

 */

package javaswingzegarv2;


import javax.swing.SwingUtilities;


/**

 *

 * @author marcin

 */

public class JavaSwingZegarV2 {


    /**

     * @param args the command line arguments

     */

    public static void main(String[] args) {

        // TODO code application logic here

        SwingUtilities.invokeLater(new Runnable() {


            @Override

            public void run() {

                ZegarGui zegarGui = new ZegarGui();

            }

        });

    }

}[/code]




-- [b]Dodane 01.07.2012 (N) 21:44[/b] --



dlaczego występuje efekt migania?? co kilka sekund występuje efekt migania całego zegara, to normalne jest w javie?? programuje pod linuxem



-- [b]Dodane 02.07.2012 (Pn) 0:49[/b] --



wstawiam wersje z wyświetlaniem godzin na tarczy zegara, niestety nadal występuje migotanie ;)

a to kod dla potomności ;)

[code]/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package javaswingzegarv2; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Calendar; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; /** * * @author marcin kaszuba */ public class ZegarGui extends JFrame{ private JPanel jPanel = new JPanel(); private GridLayout gridLayout = new GridLayout(1, 1); //private JLabel jLabel = new JLabel(); private int width = 400; private int height = 400; private int pozycja_okna_x = 500; private int pozycja_okna_y = 200; private Timer timer; private int xGodziny, yGodziny, x2Sekundy, y2Sekundy, x2Minuty, y2Minuty, x2Godziny, y2Godziny, x1Kreski, y1Kreski, x2Kreski, y2Kreski, sekundy, minuty, godziny; private double katRadSekund, katRadMinut, katRadGodzin, katRadKreski, katRadGodziny; public ZegarGui(){ setTitle("zegar wskazowkowy !!-- Dodane 02.07.2012 (Pn) 14:05 -- trochę poszukałem o podwójnym buforowaniu i napisałem metodę która powinna zapobiegać migotaniu. niestety efekt ten też występuje pod windowsem także to nie wina linuxa. wstawiam nowy kod i proszę o rady :wink:

/*

 * To change this template, choose Tools | Templates

 * and open the template in the editor.

 */

package javaswingzegarv2;


import java.awt.Color;

import java.awt.Dimension;

import java.awt.Graphics;

import java.awt.GridLayout;

import java.awt.Image;

import java.awt.Point;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.Calendar;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.Timer;


/**

 *

 * @author marcin kaszuba

 */

public class ZegarGui extends JFrame{


    private JPanel jPanel = new JPanel(true);

    private GridLayout gridLayout = new GridLayout(1, 1);

    private int width = 400;

    private int height = 400;

    private int pozycja_okna_x = 500;

    private int pozycja_okna_y = 200;

    private Timer timer;

    private Image buffor;

    private Graphics bgraphics;

    private int xGodziny, yGodziny, x2Sekundy, y2Sekundy, x2Minuty, y2Minuty, x2Godziny, y2Godziny, x1Kreski, y1Kreski, x2Kreski, y2Kreski, sekundy, minuty, godziny;

    private double katRadSekund, katRadMinut, katRadGodzin, katRadKreski, katRadGodziny;


    public ZegarGui(){

        setTitle("zegar wskazowkowy !");

        setLocation(new Point(pozycja_okna_x, pozycja_okna_y));

        setPreferredSize(new Dimension(width, height));

        pack();

        setVisible(true);

        setResizable(false);

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        add(jPanel);


        jPanel.setLayout(gridLayout);


        timer = new Timer(1000, new ActionListener() {


            @Override

            public void actionPerformed(ActionEvent e) {

                repaint();

            }

        });

        timer.start();


        buffor = createImage(width, height);

        bgraphics = buffor.getGraphics();

    }


    @Override

    public void update(Graphics graphics){

        bgraphics.clearRect(0, 0, width, height);

        paint(bgraphics);

        graphics.drawImage(buffor, 0, 0, jPanel);

    }


    @Override

    public void paint(Graphics graphics){

        super.paint(graphics);

        Calendar calendar = Calendar.getInstance();


        graphics.fillRoundRect(190, 190, 20, 20, 360, 360);//okrag

        graphics.drawRoundRect(50, 50, 300, 300, 360, 360);//srodek

        int j = 0;

        for(int i = 0; i 60; ++i){

            if( i % 5 == 0){

                katRadKreski = 2.0 * Math.PI * (i / 60.0) - (Math.PI / 2.0);

                katRadGodziny = 2.0 * Math.PI * (i / 60.0) - (Math.PI / 3.0);

                x1Kreski = (int)(150 * (Math.cos(katRadKreski)));

                y1Kreski = (int)(150 * (Math.sin(katRadKreski)));

                x2Kreski = (int)(130 * (Math.cos(katRadKreski)));

                y2Kreski = (int)(130 * (Math.sin(katRadKreski)));

                xGodziny = (int)(160 * (Math.cos(katRadGodziny)));

                yGodziny = (int)(160 * (Math.sin(katRadGodziny)));

                graphics.drawLine(200 + x1Kreski, 200 + y1Kreski, 200 + x2Kreski, 200 + y2Kreski);//kreska wskaznikowa

                graphics.drawString(String.valueOf(++j), 195 + xGodziny, 205 + yGodziny);//numer godziny

            } else {

                katRadKreski = 2.0 * Math.PI * (i / 60.0) - (Math.PI / 2.0);

                x1Kreski = (int)(150 * (Math.cos(katRadKreski)));

                y1Kreski = (int)(150 * (Math.sin(katRadKreski)));

                x2Kreski = (int)(140 * (Math.cos(katRadKreski)));

                y2Kreski = (int)(140 * (Math.sin(katRadKreski)));

                graphics.drawLine(200 + x1Kreski, 200 + y1Kreski, 200 + x2Kreski, 200 + y2Kreski);//kreska wskaznikowa

            }

        }


        sekundy = calendar.get(Calendar.SECOND);

        minuty = calendar.get(Calendar.MINUTE);

        godziny = calendar.get(Calendar.HOUR);


        katRadSekund = 2.0 * Math.PI * (sekundy / 60.0) - (Math.PI / 2.0);

        katRadMinut = 2.0 * Math.PI * (minuty / 60.0) - (Math.PI / 2.0);

        katRadGodzin = 2.0 * Math.PI * ((godziny * 60.0 * 60.0 + minuty * 60.0 + sekundy) / 43200.0) - (Math.PI / 2.0);


        x2Sekundy = (int)(140 * (Math.cos(katRadSekund)));

        y2Sekundy = (int)(140 * (Math.sin(katRadSekund)));


        x2Minuty = (int)(125 * (Math.cos(katRadMinut)));

        y2Minuty = (int)(125 * (Math.sin(katRadMinut)));


        x2Godziny = (int)(100 * (Math.cos(katRadGodzin)));

        y2Godziny = (int)(100 * (Math.sin(katRadGodzin)));


        graphics.setColor(Color.red);

        graphics.drawLine(200, 200, 200 + x2Sekundy, 200 + y2Sekundy);//wskazowka sekundowa

        graphics.setColor(Color.BLACK);

        graphics.drawLine(200, 200, 200 + x2Minuty, 200 + y2Minuty);//wskazowka minutowa

        graphics.drawLine(200, 200, 200 + x2Godziny, 200 + y2Godziny);//wskazowka godzinowa

    }


}

/*

 * To change this template, choose Tools | Templates

 * and open the template in the editor.

 */

package javaswingzegarv2;


import javax.swing.SwingUtilities;


/**

 *

 * @author marcin

 */

public class JavaSwingZegarV2 {


    /**

     * @param args the command line arguments

     */

    public static void main(String[] args) {

        // TODO code application logic here

        SwingUtilities.invokeLater(new Runnable() {


            @Override

            public void run() {

                ZegarGui zegarGui = new ZegarGui();

            }

        });

    }

}[/code]