java swing zegar ruch po okręgu

Odpowiedz Nowy wątek
2012-06-28 00:28
0

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();
            }
        });
    }
}

Pozostało 580 znaków

2012-06-28 09:27
0
  1. Co za dziwny pomysł by metoda paint rzucała NumberFormatException?
  2. Nie wystarczy narysować wskazówkę w nowym położeniu, trzeba jeszcze zmazać w starym. Najprostszy sposób, to:
    public void paint(Graphics graphics)
    {
     super.paint(graphics);
     ...
  3. Wzory nie są poprawne, z dwóch powodów: Argumentem funkcji sin() i cos() jest kąt (w radianach), powinieneś wpierw przeliczyć czas w sekundach na kąt. Dla Twoich wzorów położenie "początkowe" to wskazówka skierowana w prawo, zazwyczaj gdy sekundy są równe 0, to wskazówka jest skierowana do góry. Kiedyś pisałem zegar analogowy i do obliczania położenia wskazówki sekundowej używałem takich wzorów (miałem mniejszy niż Ty promień tarczy, tylko 120):
    //angle = 2*Math.PI*((hours*60*60+minutes*60+seconds)/43200.0)-(Math.PI/2); to jest dla wskazówki godzinowej
    angle = 2*Math.PI*(seconds/60.0)-(Math.PI/2);
    x1 = (int)(120*Math.cos(angle));
    y1 = (int)(120*Math.sin(angle));
    g.drawLine(200,200,200+x1,200+y1);

    Tajemnicza stała 43200.0 to ilość sekund w 12 godzinach (606012). Wielkości hours, minutes i seconds były odczytywane z obiektu new GregoranCalendar().


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 2x, ostatnio: bogdans, 2012-06-28 13:24

Pozostało 580 znaków

2012-06-28 12:52
0

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

Pozostało 580 znaków

2012-06-28 12:57
0

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

Pozostało 580 znaków

2012-06-28 13:27
0

Przez pomyłkę wrzuciłem obliczanie kąta dla wskazówki godzinowej. Już poprawiłem, nie ma teraz niczego co wymagałoby wyjaśniania.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell

Pozostało 580 znaków

2012-06-28 14:41
0

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

Pozostało 580 znaków

2012-06-28 15:20
0

Stopnie zamienić na radiany i obliczyć wartości odpowiednich funkcji trygonometrycznych i podstawić je do odpowiednio przekształconego wzoru.


Co kurła debuguj ten kod i streszczaj się klientowi chce się fixa, a jak nie kurła to odpale visuala i ci pomoge a tego byś nie chciał
Mącisz, podałem wzór angle = 2Math.PI(seconds/60.0)-(Math.PI/2); jak wyliczyć radiany. Przeliczanie jest niepotrzebne. - bogdans 2012-06-28 18:58

Pozostało 580 znaków

2012-07-01 18:01
0

angle = 2Math.PI(seconds/60.0)-(Math.PI/2) rozumiem tą część wzoru 2Math.PI(seconds/60.0) jest to obliczanie kąta natomiast -(Math.PI/2) nie bardzo, ale przypuszczam że chodzi o cofnięcie tego kąta czyli żeby wskazówka zaczynała od właściwego kąta i sekundy na zegarze. 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 ;) No i chciałem podziękować użytkownikowi Bogdans za rady ;) 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();
            }
        });
    }
}

Pozostało 580 znaków

2012-07-01 21:46
0

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

Pozostało 580 znaków

2012-07-01 22:22
0

Nie, to nie jest normalne. Ja kiedyś też pisałem w javie program wyświetlający zegar analogowy i żadne migotanie u mnie nie występowało. Tylko, że ja pisałem własne klasy dziedziczące po JComponent/Jpanel i w nich włączałem podwójne buforowanie.

Pozostało 580 znaków

2012-07-01 23:08
0

Ja bym użył do wypisania numerów godzin metody drawString() .
Winny jest raczej Linux, pod windowsem nie ma migotania. Spróbuj uruchomić program z terminala, nie z IDE. IDE służy do pisania i debugowania programów, nie do uruchamiania.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 2x, ostatnio: bogdans, 2012-07-01 23:13

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0