Перейти к содержимому
javascopes.com
Области Java
  • Политика конфиденциальности
  • Политика конфиденциальности
Рубрики
Без рубрики

Создание Приложения Для Черепахи С Логотипом С Помощью Antlr И JavaFX

Этот пост был впервые опубликован в моем личном блоге Этот пост посвящен созданию очень простого приложения… Помеченный java, antlr, javafx.

  • Автор записи Автор: Nikos Katsanos
  • Дата записи 01.01.2022

Этот пост был впервые опубликован в моем личном блоге

Этот пост посвящен созданию очень простого приложения, реализующего подмножество языка программирования Logo вместе с пользовательским интерфейсом, который визуализирует программы с логотипами, введенные пользователями. Использовались технологии Antlr для создания синтаксического анализатора для подмножества правил логотипа, а также JavaFX для создания пользовательского интерфейса, позволяющего пользователям вводить программы с логотипами и предоставлять визуализацию этих программ.

Язык Логотипа

Логотип – это образовательный язык, предназначенный в основном для детей младшего возраста. Это язык, с которым я лично общался еще в младших классах средней школы. Он эффективно предоставляет грамматику правил движения (т.е. вперед, назад, вправо 90 o ) наряду с некоторым потоком управления (т.е. повторением), позволяющим пользователю создавать набор команд. Эти команды в сочетании с программным обеспечением для визуализации могут рисовать векторную графику или в сочетании с роботизированными устройствами могут перемещать робота.

Раньше это был хороший язык для обучения детей программированию, однако в настоящее время существуют более продвинутые языки, такие как Scratch . Однако я выбрал логотип из-за его простой грамматики, поскольку моей главной целью было освежить некоторые знания Antlr, а не создать реальное приложение.

Антлр

Antlr – отличный инструмент для синтаксического анализа структурированного текста (т.Е. Представьте себе регулярные выражения на стероидах). Это инструмент, который можно использовать для анализа грамматических правил и создания приложений на основе его функций. Распространенный подход заключается в создании пользовательских DSL с использованием Antlr. Я не буду подробно описывать Antlr, так как на официальном сайте много хорошей документации, а также я не являюсь экспертом по Antlr. Кроме того, книга Definitive-ANTLR-4-Reference , написанная ее создателем, является хорошим ресурсом.

В этом приложении я фактически определил свой собственный набор правил логотипа, используя грамматику Antlr, и я полагался на возможности анализа Antlr для оценки программ с логотипами и предоставления мне обратных вызовов встреченных команд логотипа.

Большинство людей были бы знакомы с JavaFX. Эффективно ли следующая попытка после Java Swing создать оборудование для создания (современного?) Пользовательские интерфейсы, использующие Java. Мои навыки работы с пользовательским интерфейсом довольно плохи, поэтому я хотел, чтобы что-то заставило меня создать пользовательский интерфейс. Я выбрал JavaFX вместо чего-то более стандартного, такого как фреймворк HTML5 + JS, так как в прошлом я немного занимался Java Swing и хотел попробовать JavaFX в основном из любопытства.

Несмотря на то, что JavaFX очень богат функциями, а модель программирования напоминает часть Java Swing и часть C # WPF (с которой я был немного знаком еще в 2011 году) На меня это не произвело впечатления. Это казалось громоздким в том смысле, что я думал, что вся модель программирования мешает мне, может быть, потому, что я с ней не знаком, а также, может быть, потому, что это просто не очень хорошая модель программирования, оправдывающая отсутствие широкого распространения.

Определение Грамматики Antlr

Как упоминалось выше, Antlr нуждается в определении грамматики, состоящем из правил синтаксического анализа и лексера. Правила лексера используются для извлечения токенов из текста, а правила синтаксического анализа – для извлечения значимых утверждений.

Я решил использовать только небольшое подмножество функций логотипа, поэтому будет поддерживаться следующее:

  • Движение вперед
  • Движение назад
  • Поворот влево/вправо
  • Возможность использования функции пера вверх/вниз, что означает, что при движении пера вверх рисунок не должен появляться, даже если “черепаха” перемещается

Эти правила, переведенные в грамматику Antlr, выглядят как Logo.g4

Кто-то может заметить, что приведенная выше грамматика просто определяет ключевые работы (т.е. вперед , назад , вправо и т. Д.) В качестве правил лексера (он же токены) и выражения программиста (т.е. вперед 50 ) в качестве правил синтаксического анализа. На прикладном уровне Antlr генерирует заглушки прослушивателей для правил синтаксического анализа, которые могут быть реализованы, и пользователь получает обратные вызовы по этим правилам. Затем пользователи могут написать свою логику поверх этого.

Легко понять, насколько полезен Antlr, выполняющий всю тяжелую работу за пользователя. Кому-то просто нужно расширить уже сгенерированный прослушиватель, который распространяет события на код пользователя.

Подключение обратных вызовов анализатора

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

  • Пользовательский ИНТЕРФЕЙС JavaFX
  • Пользовательский ИНТЕРФЕЙС Swing
  • Простая стандартная программа

Приведенная ниже реализация касается этого

public class LogoDriver extends LogoBaseListener {

    private final TurtlePainter painter;

    public LogoDriver(TurtlePainter painter) {
        this.painter = painter;
    }

    @Override
    public void exitForward(final ForwardContext ctx) {
        this.painter.forward(Integer.parseInt(ctx.getChild(1).getText()));
    }

    @Override
    public void exitBack(final BackContext ctx) {
        this.painter.back(Integer.parseInt(ctx.getChild(1).getText()));
    }

    @Override
    public void exitRight(final RightContext ctx) {
        this.painter.right(Integer.parseInt(ctx.getChild(1).getText()));
    }

    @Override
    public void exitLeft(final LeftContext ctx) {
        this.painter.left(Integer.parseInt(ctx.getChild(1).getText()));
    }

    @Override
    public void exitSet(final SetContext ctx) {
        final String[] point = ctx.POINT().getText().split(",");
        final int x = Integer.parseInt(point[0]);
        final int y = Integer.parseInt(point[1]);
        this.painter.set(x, y);
    }

    @Override
    public void exitPenUp(final PenUpContext ctx) {
        this.painter.penUp();
    }

    @Override
    public void exitPenDown(final PenDownContext ctx) {
        this.painter.penDown();
    }

    @Override
    public void exitClearscreen(ClearscreenContext ctx) {
        this.painter.cls();
    }

    @Override
    public void exitResetAngle(ResetAngleContext ctx) {
        this.painter.resetAngle();
    }

    @Override
    public void exitProg(ProgContext ctx) {
        this.painter.finish();
    }
}

Художник Черепаха может быть чем угодно, даже программой, которая записывает команды программы и утверждает их, как шпион JUnit.

Пользовательский интерфейс JavaFX

В нашем случае Turtle Painter – это класс, который преобразует команды в конструкции JavaFX и делегирует потоку пользовательского интерфейса для рисования этих конструкций. Например, реализация команды вперед выглядит следующим образом:

    @Override
    public void forward(int points) {
        JavaFXThreadHelper.runOrDefer(() -> {
            final double radian = this.toRadian(this.direction);
            final double x = this.turtle.getCenterX() + points * Math.cos(radian);
            final double y = this.turtle.getCenterY() - points * Math.sin(radian);

            this.validateBounds(x, y);

            this.moveTurtle(x, y);
        });
    }

    private void moveTurtle(final double x, final double y) {
        JavaFXThreadHelper.runOrDefer(() -> {

            final Path path = new Path();
            path.getElements().add(new MoveTo(this.turtle.getCenterX(), this.turtle.getCenterY()));
            path.getElements().add(new LineTo(x, y));

            final PathTransition pathTransition = new PathTransition();
            pathTransition.setDuration(Duration.millis(this.animationDurationMs));
            pathTransition.setPath(path);
            pathTransition.setNode(this.turtle);

            if (this.isPenDown) {
                final Line line = new Line(this.turtle.getCenterX(), this.turtle.getCenterY(), x, y);
                pathTransition.setOnFinished(onFinished -> this.canvas.getChildren().add(line));
            }

            animation.getChildren().add(pathTransition);

            this.paintTurtle(x, y);
        });
    }

Эффективное рисование линии в пользовательском интерфейсе.

Простую программу с логотипом, которая рисует “ПРИВЕТ, МИР” на экране, можно найти здесь . Результат для этого будет выглядеть так:

Исходный Код

Исходный код проверен в github .

Можно сделать довольно много улучшений, как на стороне пользовательского интерфейса, так и на уровне языка:

  • Реализовать управление потоком логотипов (т.е. циклы)
  • Сделайте черепаху настоящим изображением черепахи, также показав направление ее движения
  • и т.д…

Не стесняйтесь раскошеливаться или отправлять PR для любого дополнения:)

Оригинал: “https://dev.to/nikos_katsanos/building-a-logo-turtle-app-with-antlr-and-javafx-ben”

Читайте ещё по теме:

  • Создайте микросервисы JVM менее чем за 10 МБ с помощью Micronaut
  • Создайте блог на основе уценки с помощью Spring Boot – Часть 4
  • Так что это Ява.
  • Как спланировать свой первый проект с помощью микросервисов и Spring Boot
  • Переоценка TestNG по сравнению с Junit
  • Рефакторинг кода в потоковый API Java 8
  • Метки blog, javafx, logo, post, turtle

← Микропрофильный клиент Rest 2.0 – Первый взгляд → Современный YAML Для Современной Java

© 2026 javascopes.com

Политика конфиденциальности

Сайт работает на WordPress

Наверх ↑ Вверх ↑