Передача данных между объектами атрибутами объекта - PullRequest
1 голос
/ 09 апреля 2020

В настоящее время пытаюсь сделать графические c часы в JAVA, я имею дело с проблемой "связи" между элементами. Действительно, моя архитектура видна снизу и состоит из 3 классов:

enter image description here

Ящик используется в качестве «контейнера» путем группировки различных элементов, которые касается данных (класс часов, который позволяет хранить только текущее время) и графиков c (JFrame, а также clockPanel).

ClockPanel - это класс, который должен позволять рисовать часы (для в тот момент, когда я смог нарисовать элементы stati c, как показано ниже).

enter image description here

Моя проблема заключается в том, как передать данные часов в ClockPanel, чтобы нарисовать стрелки часов.

Я думал о передаче часов ClockPanel, но кажется довольно очевидным, что это не решение, которое выберет, оно сделает ящик бесполезным.

Так что я не вижу, как сделать связь между этими двумя элементами. Я стараюсь быть настолько чистым, насколько это возможно, чтобы приобрести наилучшие возможные рефлексы на будущее.

Некоторое время я думал, что моя нынешняя структура совершенно неверна, что вызывает мою проблему.

Ниже приведены фрагменты кода из ящика и функция paintComponent для ClockPanel:

public void initDraw() {
        clockWindow = new JFrame();

        clockWindow.setTitle(getTitle());//Définit un titre pour notre fenêtre
        clockWindow.setSize(getSize(), getSize());//Définit sa taille, elle sera carrée car deux fois size en W et H
        clockWindow.setLocationRelativeTo(null);//Nous demandons maintenant à notre objet de se positionner au centre
        clockWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Termine le processus lorsqu'on clique sur la croix rouge
        clockWindow.setResizable(false);//L'utilisateur ne peux pas redimensionner la fenetre
        clockWindow.setVisible(true);//Et enfin, la rendre visible

        clockPanel =  new ClockPanel(m_clock);
        clockWindow.setContentPane(clockPanel);

}
public void paintComponent(Graphics g){
        super.paintComponent(g);

        m_radiusWhiteCircle = (getWidth()/2)-40; //on prend un rayon qui va donner un cercle qui prend quasiment toute la fenetre
        m_centerX = m_centerY = getWidth()/2; //dans le contexte actuel, la fenetre est carrée, donc qu'on prenne widh ou height c'est pareil (a separe en deux opération si on change)
        System.out.println(getHeight());

        this.setBackground(new Color(160, 196, 235)); //on défini le fond du JPanel
        g.setColor(Color.BLACK);// le prochaine cercle sera noir
        int[] blackCircleSquare = convertCircleCoordsToSquareCoords(m_centerX, m_centerY, m_radiusWhiteCircle + 10); //on convertit les coordonées de notre cercle afin d'obtenir ceux du coin gauche du carré qui va contenri notre cerle
        g.fillOval(blackCircleSquare[0],blackCircleSquare[1],blackCircleSquare[2],blackCircleSquare[2]);//On dessine le contour de l'horlorge en prenant le centre de la fenetre et un rayon un peu supérieur au cercle "principal"

        g.setColor(Color.WHITE);//le prochain cercle sera blanc
        int[] whiteCircleSquare = convertCircleCoordsToSquareCoords(m_centerX, m_centerY, m_radiusWhiteCircle);
        g.fillOval(whiteCircleSquare[0],whiteCircleSquare[1],whiteCircleSquare[2],whiteCircleSquare[2]);

        g.setColor(Color.GREEN);
        int[] greenCircleSquare = convertCircleCoordsToSquareCoords(m_centerX, m_centerY, 10);
        g.fillOval(greenCircleSquare[0],greenCircleSquare[1],greenCircleSquare[2],greenCircleSquare[2]);

        g.setColor(Color.RED);
        g.setFont(new Font("TimesRoman", Font.PLAIN,20));
        for(int i=1;i<=12;i++) {
            int xHour = (int)(m_centerX+(m_radiusWhiteCircle-15)*Math.cos(i*INVARIABLE_ANGLE_HOUR - INVARIABLE_DECALAGE));
            int yHour = (int)(m_centerY+(m_radiusWhiteCircle-20)*Math.sin(i*INVARIABLE_ANGLE_HOUR - INVARIABLE_DECALAGE));
            g.drawString(String.valueOf(i),xHour,yHour);
        }
}

1 Ответ

1 голос
/ 12 апреля 2020

На мой взгляд, следующие шаги:

  1. Вы можете использовать уже существующие классы для обработки времени (классы в java.time пакете). Я знаю, что на первый взгляд это может показаться более сложным, чем класс ручной работы Clock, но у него больше возможностей. В конечном счете, вы можете быть вынуждены узнать об этом, потому что вам понадобится этот потенциал. У нас больше шансов, что кто-то еще, кто будет поддерживать наш код в будущем, узнает об уже существующем API, а не о наших собственных классах ручной работы. А также, изучив его сейчас, вы также можете начать использовать его сейчас.
  2. Что касается диаграммы классов, я думаю, что можно сказать, что объектами являются: время, графическое представление времени и окно (имеющее графическое представление времени). Так что это привело бы меня к созданию подкласса Icon для графического представления времени, использования уже существующих классов обработки времени (или создания их тогда и только тогда, когда они еще не существовали) и, наконец, окна (которое уже существует). как JFrame).
  3. Итак, как предоставить Icon окну? ... Через JLabel.
  4. Затем создайте объект Timer для обновления Значок / представление JLabel время от времени (по мере необходимости).

В следующем примере демонстрируется код:

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.time.LocalTime;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Main {

    public static class ClockIcon implements Icon {
        @Override
        public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
            //The clock's painting goes here...
            g.fillOval(x, y, getIconWidth() - 1, getIconHeight() - 1);
            g.setColor(Color.CYAN.darker());
            g.drawString(LocalTime.now().toString(), x + 14, y + 5 + getIconHeight() / 2);
        }

        @Override
        public int getIconWidth() {
            return 100; //The clock's width goes here...
        }

        @Override
        public int getIconHeight() {
            return 100; //The clock's height goes here...
        }
    }

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(() -> {

            final JLabel label = new JLabel(new ClockIcon(), SwingConstants.CENTER);

            final Timer engine = new Timer(500, e -> label.repaint());
            engine.setRepeats(true);
            engine.start();

            final JFrame frame = new JFrame("Clock");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(label);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

Простой учебник по использованию времени. классы я бы предложил это . Если вам более любопытно, вы можете начать с документации пакета здесь .

Надеюсь, это поможет.

Некоторые примечания: я бы посоветовал вам не быть в спешите принять / мой ответ, если он не поможет вам так, как вы хотели. Не стесняйтесь сначала попросить разъяснений в комментариях или просто подождите больше, чтобы более авторитетные источники ответили на ваш вопрос. Мое мнение таково, что в вашем случае у вас нет сложной диаграммы классов для работы: просто подкласс Icon и передайте это JLabel и Timer. Наконец, я должен сказать, что размещение MRE в вопросе о том, что вы пытались, помогает получить лучшие ответы.

...