О насБлогКонтакты
Веб-разработка25 апреля 1999 г. 6 мин 101Обновлено: 22 июня 2026 г.

Java-апплеты: настоящая интерактивность в браузере (1999)

AunimedaAunimeda
📋 Содержание

Sun Microsystems запустила Java в 1995 году с конкретным обещанием: «Write Once, Run Anywhere» - написать один раз, запустить где угодно. Для веб-разработки это означало Java-апплеты - скомпилированные Java-программы, работающие прямо в браузере через плагин JVM. Идея звучала убедительно: полноценная графика, анимация, звук, работа с сетью и обработка ввода - всё внутри тега <applet> на обычной HTML-странице.

В 1999 году, если вам нужна была интерактивная графика - реальный график в реальном времени, перетаскиваемая диаграмма, анимированная визуализация - Java-апплеты были единственным серьёзным вариантом. JavaScript был ограничен валидацией форм и простыми манипуляциями DOM. Flash существовал, но был проприетарным и дорогим. Java был открытым, стандартизированным и поддерживался Sun.

Мы писали апплеты. Вот как это выглядело.


Архитектура: JDK 1.1 и AWT

Java-апплеты использовали Abstract Window Toolkit (AWT) для графики и интерфейса. Модель - событийная: браузер вызывал методы жизненного цикла апплета (init(), start(), stop(), destroy()), а разработчик переопределял paint() для отрисовки на экране.

// StockTickerApplet.java - JDK 1.1, 1999 год
// Бегущая строка с котировками - классический use case для апплетов

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class StockTickerApplet extends Applet implements Runnable {

    // Данные передаются из HTML через теги <param>
    private String tickerText  = "MSFT 89.50 (+1.25)  AAPL 28.75 (-0.50)  SUNW 42.00 (+2.00)";
    private int    scrollSpeed = 2;         // пикселей за кадр
    private Color  bgColor     = Color.black;
    private Color  textColor   = Color.green;   // зелёный на чёрном - стиль 1999

    private Thread animationThread;
    private int    xPosition;
    private int    textWidth;
    private Font   tickerFont;

    @Override
    public void init() {
        String paramText  = getParameter("text");
        String paramSpeed = getParameter("speed");

        if (paramText  != null) tickerText  = paramText;
        if (paramSpeed != null) scrollSpeed = Integer.parseInt(paramSpeed);

        tickerFont = new Font("Monospaced", Font.BOLD, 14);
        setBackground(bgColor);

        FontMetrics fm = getFontMetrics(tickerFont);
        textWidth = fm.stringWidth(tickerText);
        xPosition = getSize().width;
    }

    @Override
    public void start() {
        if (animationThread == null || !animationThread.isAlive()) {
            animationThread = new Thread(this);
            animationThread.start();
        }
    }

    @Override
    public void stop() {
        animationThread = null;   // остановить цикл при уходе со страницы
    }

    @Override
    public void run() {
        while (Thread.currentThread() == animationThread) {
            xPosition -= scrollSpeed;
            if (xPosition < -textWidth) {
                xPosition = getSize().width;
            }
            repaint();
            try {
                Thread.sleep(40);   // ~25 кадров в секунду
            } catch (InterruptedException e) {
                break;
            }
        }
    }

    @Override
    public void paint(Graphics g) {
        g.setFont(tickerFont);
        g.setColor(textColor);
        g.drawString(tickerText, xPosition, getSize().height / 2 + 5);
    }

    // Двойная буферизация - обязательна в AWT 1999 года
    // Без неё каждый repaint() вызывал видимое мерцание
    private Image    offscreenImage;
    private Graphics offscreenGraphics;

    @Override
    public void update(Graphics g) {
        Dimension d = getSize();
        if (offscreenImage == null) {
            offscreenImage    = createImage(d.width, d.height);
            offscreenGraphics = offscreenImage.getGraphics();
        }
        offscreenGraphics.setColor(bgColor);
        offscreenGraphics.fillRect(0, 0, d.width, d.height);
        paint(offscreenGraphics);
        g.drawImage(offscreenImage, 0, 0, this);
    }
}

Компиляция и деплой:

# Компиляция JDK 1.1
javac StockTickerApplet.java
# Результат: StockTickerApplet.class

# Упаковка в JAR для уменьшения числа HTTP-запросов
jar cvf ticker.jar StockTickerApplet.class

Вставка в HTML:

<!-- Тег <applet> - стандарт HTML 4.0 -->
<applet code="StockTickerApplet.class"
        archive="ticker.jar"
        width="500"
        height="30"
        alt="Для просмотра требуется Java">
  <param name="text"  value="MSFT 89.50 (+1.25)  AAPL 28.75 (-0.50)">
  <param name="speed" value="3">
  <!-- Фолбэк для браузеров без плагина -->
  <p>Ваш браузер не поддерживает Java-апплеты.</p>
</applet>

Интерактивный пример: диаграмма с подсветкой

// BarChartApplet.java - интерактивная столбчатая диаграмма
// Столбцы подсвечиваются при наведении мыши
// Такое было невозможно в JavaScript 1999 года

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class BarChartApplet extends Applet implements MouseMotionListener {

    private String[] labels = {"Янв", "Фев", "Мар", "Апр", "Май", "Июн"};
    private int[]    values = {42, 67, 55, 89, 73, 91};
    private int      hoveredBar = -1;

    @Override
    public void init() {
        addMouseMotionListener(this);
        setBackground(Color.white);
    }

    @Override
    public void paint(Graphics g) {
        int w      = getSize().width;
        int h      = getSize().height;
        int margin = 30;
        int barW   = (w - 2 * margin) / values.length - 4;
        int maxVal = 0;
        for (int v : values) if (v > maxVal) maxVal = v;

        // Оси
        g.setColor(Color.black);
        g.drawLine(margin, h - margin, w - margin, h - margin);
        g.drawLine(margin, margin, margin, h - margin);

        // Столбцы
        for (int i = 0; i < values.length; i++) {
            int barH = (int)((double)values[i] / maxVal * (h - 2 * margin));
            int x    = margin + i * (barW + 4) + 4;
            int y    = h - margin - barH;

            g.setColor(i == hoveredBar ? Color.orange : new Color(51, 102, 204));
            g.fillRect(x, y, barW, barH);
            g.setColor(Color.black);
            g.drawRect(x, y, barW, barH);

            g.setFont(new Font("SansSerif", Font.PLAIN, 10));
            g.drawString(labels[i], x, h - 15);
            g.drawString(String.valueOf(values[i]), x, y - 2);
        }
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        int w      = getSize().width;
        int margin = 30;
        int barW   = (w - 2 * margin) / values.length - 4;

        int newHovered = -1;
        for (int i = 0; i < values.length; i++) {
            int x = margin + i * (barW + 4) + 4;
            if (e.getX() >= x && e.getX() <= x + barW) {
                newHovered = i;
                break;
            }
        }
        if (newHovered != hoveredBar) {
            hoveredBar = newHovered;
            repaint();
        }
    }

    @Override public void mouseDragged(MouseEvent e) {}
}

В 1999 году это производило сильное впечатление. Диаграмма, реагирующая на движение мыши - на JavaScript это было принципиально невозможно. Максимум доступный в JS: swap картинок через onmouseover. Java давал настоящую программируемую графику.


Почему апплеты умерли

Время загрузки. Плагин JVM должен был инициализироваться перед первым апплетом. На модеме 56 кбит/с пользователи смотрели на серый прямоугольник 10-30 секунд. Многие уходили, не дождавшись.

Фрагментация версий. IE поставлялся с Microsoft JVM. Netscape использовал плагин Sun JVM. Java 1.0, 1.1 и 1.2 имели несовместимые API. Апплет, работавший идеально в IE/Windows, ломался в Netscape/Mac или наоборот. Обещание «Write Once, Run Anywhere» не выполнялось на практике.

// Код, выявлявший различия между JVM:
String javaVersion = System.getProperty("java.version");
// Разветвление по версии - что полностью разрушало идею WORA

// Microsoft JVM не включал некоторые классы RMI
// Реализация Thread.sleep() в Netscape JVM давала баги в отдельных версиях
// Поведение java.awt.Color различалось между JDK 1.0 и 1.1

Flash был зрелищнее. Macromedia Flash 4 (1999) и Flash 5 (2000) предлагали векторную анимацию, потоковое аудио и программирование на ActionScript с несравнимо лучшим инструментарием для дизайнеров. Flash загружался быстрее, не требовал JVM, позволял создавать интерактивный контент без Java-разработчиков. К 2001 году Flash выиграл нишу «интерактивный веб».


Что оставили апплеты в наследство

Java-апплеты, несмотря на провал как массовой веб-технологии, доказали: браузер может быть платформой для полноценных приложений, а не только для отображения документов. Эта идея никуда не ушла: Flash, Silverlight, HTML5 Canvas, WebGL, WebAssembly - все они преследовали ту же цель.

Архитектурные паттерны разработки апплетов - методы жизненного цикла (init/start/stop/destroy), слушатели событий, двойная буферизация - прослеживаются в каждом UI-фреймворке, который последовал за ними. Жизненный цикл Activity в Android прямо унаследован от жизненного цикла апплета. Компонентная модель React и Web Components следует тому же паттерну init/render/destroy.

Провал был поучительным: «Write Once, Run Anywhere» требует не только переносимости языка, но и стандартизации runtime-окружения. JVM не был идентичен у разных поставщиков браузеров. Урок этого провала привёл к решению строить веб-платформу вокруг одного согласованного runtime - JavaScript-движка.

Читайте также

Разработка сайта в Самаре в 2026 году - цены, сроки, технологииaunimeda
Веб-разработка

Разработка сайта в Самаре в 2026 году - цены, сроки, технологии

Сколько стоит разработка сайта в Самаре в 2026 году. Реальные цены на лендинги, корпоративные сайты и интернет-магазины. Что влияет на стоимость и как выбрать подрядчика.

Google Chrome и V8: когда JavaScript стал быстрым (2008)aunimeda
Веб-разработка

Google Chrome и V8: когда JavaScript стал быстрым (2008)

2 сентября 2008 года Google выпустил Chrome. Не браузер - манифест. Внутри был V8: JIT-компилятор JavaScript, написанный с нуля. SunSpider показал, что V8 в 10 раз быстрее Firefox 3. За один день ожидания от JavaScript радикально изменились. Начался browser war 2.0.

Ajax: имя, изменившее веб (2005)aunimeda
Веб-разработка

Ajax: имя, изменившее веб (2005)

18 февраля 2005 года Джесси Джеймс Гаррет опубликовал статью «Ajax: новый подход к веб-приложениям». Технология не была новой - XMLHttpRequest существовал с 1999 года. Но имя изменило всё: разработчики получили паттерн, словарь и разрешение думать о браузере как о платформе приложений.

Нужна IT-разработка для вашего бизнеса?

Разрабатываем сайты, мобильные приложения и AI-решения для бизнеса в России. Бесплатная консультация.

Разработка сайтов

Получить консультацию Все статьи