Как сделать, чтобы цифры выглядели как в "Матрице"? JFrame/JLabel

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

import javax.swing.*;
import java.awt.*;
import java.util.Random;

public class BigProject extends JFrame {
    public static void main(String[] args) throws Exception {

        int R = 0;
        int G = 255;
        int B = 0;
        int repeat = 250;

        JFrame j = new JFrame();
        Robot robot = new Robot();
        Random random = new Random();

        j.getContentPane().setBackground(Color.BLACK);
        j.setExtendedState(Frame.MAXIMIZED_BOTH);
        j.setDefaultCloseOperation(EXIT_ON_CLOSE);
        j.setTitle("Matrix");
        j.setLayout(new FlowLayout());
        j.setVisible(true);

        FlowLayout setting = new FlowLayout(0, 0, 0);
        j.getContentPane().setLayout(setting);

        for (int Repeat = 0;Repeat != repeat; Repeat++) {
            int i = random.nextInt(10);
            JLabel label = new JLabel(String.valueOf(i), JLabel.CENTER);
            label.setPreferredSize(new Dimension(100, 60));
            label.setFont(label.getFont().deriveFont(45.0F));
            label.setVisible(true);
            j.add(label);
        }
    }
}

Получается такой результат: введите сюда описание изображения


Ответы (1 шт):

Автор решения: Nowhere Man

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

  1. Окно следует делать видимым после того, как оно было заполнено лейблами
  2. Установить цвет в лейблах (также случайным образом), чтобы всё стало зелёное и кросивое, вызвав метод setForeground(Color fg)

Дополнительные улучшения:

  • Рассчитать количество лейблов вместо использования константы.
    Не стоит полагаться на какое-то фиксированное количество лейблов, записанное в repeat, например, для дисплея размером хотя бы 1920х1080 250 лейблов окажется недостаточно.
    Поэтому количество лейблов придётся рассчитать, узнав размер дисплея в пикселях при помощи метода java.awt.Toolkit::getScreenSize
  • Удалить экземпляр класса Robot, так как он нигде не используется
  • Улучшить именование переменных (например j больше подходит в качестве целочисленного индекса во вложенном цикле, а не для обозначения окна) и прочие мелочи
  • Использовать ключевое слово var, доступное в Java 10+, так как все переменные в данном коде -- локальные
  • Убрать заголовок и системные кнопки окна, вызвав метод Frame::setUndecorated
  • Подготовить отдельный массив символов для печати, чтобы не создавать каждый раз новые строки.

Вариант исправленного решения:

import javax.swing.*;
import java.awt.*;
import java.util.Random;

import static java.lang.Math.floorDiv;
import static javax.swing.SwingConstants.CENTER;

public class BigProject extends JFrame {
    public static void main(String[] args) {
        var frame = new JFrame();

        frame.getContentPane().setBackground(Color.BLACK);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setUndecorated(true);

        frame.getContentPane().setLayout(new FlowLayout(CENTER, 0, 0));

        var screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        var labelSize = new Dimension(100, 60);

        var rw = floorDiv((int) screenSize.getWidth(), (int) labelSize.getWidth());
        var rh = floorDiv((int) screenSize.getHeight(), (int) labelSize.getHeight());
        var repeat = rw * rh;

        var symbols = new String[] {
                "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
        };
        var random = new Random();

        for (var i = 0; i < repeat; i++) {
            var number = random.nextInt(symbols.length);
            var label = new JLabel(symbols[number], CENTER);
            label.setPreferredSize(labelSize);
            label.setFont(label.getFont().deriveFont(45.0F));
            // все позеленеет
            label.setForeground(new Color(0, 63 + random.nextInt(192), 0));
            label.setVisible(true);
            frame.add(label);
        }
        // растяжка окна
        frame.setExtendedState(Frame.MAXIMIZED_BOTH);
        // окно заполнено, не стыдно показать
        frame.setVisible(true);
    }
}

введите сюда описание изображения

→ Ссылка