Класс MyPro
мы напишем в отдельном файле. Он является таким же стандартным классом, как и первые два. Точнее это обязательная часть нашего шаблона. Но в отличие от первых двух классов, которые написаны практически полностью, этот класс можно наращивать бесконечно. Сейчас мы запишем в него только то, что нам нужно в данный момент, то есть для данного проекта. Ниже я показываю сразу весь текст, который надо сохранить в файле MyPro.java
Так как этот класс выполняет стандартные функции, то его можно ставить в любую программу без изменений, даже не понимая, что тут написано. Это очень похоже на примитивные языки, в которых можно было использовать чужие библиотеки не разбираясь в их коде и зная только то, что надо подать на вход и получить на выходе. Но так как наша задача научиться программировать, то начнем комментировать.
Первая функция readLine
имеет два аргумента: строку fn
с именем файла в текущей папке программы (или полного, если в ней указан весь путь к файлу) и номер строки внутри этого файла. Прежде всего формируется объект класса File
по имени файла. Логическая функция exists()
этого объекта выдает true
если файл существует. В этом случае начинаем работать. Строка
объявляет объект ins
, способный читать наш файл. Мы заказали процесс двухступенчатого чтения файла. Сначала файл большими кусками (в нашем случае размер куска по умолчанию) считывается из файла в буфер в памяти компьютера, а затем мы уже читаем файл из буфера. Так быстрее и это фактически без вариантов. Далее,
Нам нужна всего лишь n
-ая строка этого файла. Функция readLine()
объекта ins
читает файл с самого начала строку за строкой. Мы не знаем ни размера строк, ни сколько их вообще в файле. Но на всякий случай считываем в цикле подряд ровно n
строк. При этом мы не гарантированы от ошибки, которую сами не обрабатываем. Это конечно плохо, но мы можем делать проверки еще до обращения к нашей процедуре и здесь уже быть уверенными, что n
строк у нас есть. Но Java нам не верит и требует обрабатывать наш процесс на возможную ошибку. Это делается конструкцией типа try{...}catch(){...}
. Она необходима, потому что в данном случае мы не написали throws IOException
при объявлении класса. Значит мы обязаны написать указанную конструкцию в тексте, которая означает, что мы конкретно предлагаем свои действия в случае ошибки. В аргумент функции catch
поступит объект класса IOException
с названием ex
и далее мы можем воспользоваться его методами. Но мы как раз использовали стандартный метод, который срабатывает при добавлении текста throws IOException
в объявление класса.
Правда теперь у нас есть возможность в любой момент исправить обработку на более развернутую. Функция ex.printStackTrace();
просто указывает в окне нашего bat файла на место ошибки в коде программы. Это тоже очень полезная информация. Так как указывается конкретная строка файла, то нужен редактор, показывающий положение курсора (хотя бы строку). Ну и полезно закрывать объект ins
, отправляя его тем самым в мусор. А сборщик мусора его уберет. Далее, надо все таки проверить, считана строка или нет. Если она не считана, она будет null
, то есть не существует. Так мы ее определили с самого начала. А если считана, то пересылаем в arg
. Исходно arg
задана как имеющая один пробел. Вот и все.
Вторая функция split
расщепляет строку по заданному символу. Сначала метод класса String
с названием toCharArray()
преобразует эту строку в массив символов. Определяя длину этого массива, мы в цикле по элементам сначала определяем сколько раз символ, являющийся вторым аргументом функции, встречается в данном наборе символов. Число строк должно быть на 1 больше, поэтому отсчет идет от 1. Зная число будущих строк, мы определяет необходимый массив и затем конкретизируем каждую строку, используя конструктор класса String
, позволяющий преобразовывать массив символов в
строку new String(p,i1,i2).
Здесь число i1
- это первый элемент массива, попадающий в строку, i2
- полное число элементов. Остальное очевидно.
Но здесь появилась еще и третья функция parent
, которая нам понадобится позднее. Увы, я сам додумался до этой функции только через три года работы. Без нее тоже все работало, но немного странно. Эта функция как раз возвращает нам наше главное окно программы, к которому надо приклеивать диалоги, так как они не иконизируются. Если этого не делать, то есть задавать вместо окна null
, то диалоги гуляют сами по себе, а программное окно само по себе. И если не открывать других окон Windows, то никаких проблем не возникает. Но если открывать - то их надо тут же закрывать. Если открыть окно программы после открытия чужого окна, то мы не увидим в нем диалога - он не приклеен. Как это делается? Метод возвращает объект класса Frame
. Наше окно JFrame
. Но это не беда, так как JFrame
является прямым потомком Frame
. Статический метод getFrames()
класса Frame
возвращает все окна, открытые программой. Метод getTitle()
берет у каждого окна его заглавие и сравнивает с заглавием нашего окна mtit
. Приставку MyPro
уже не надо, так как мы и так в классе MyPro
. При совпадении названий данное окно возвращается как объект.
И еще два небольших замечания. У этого класса нет конструктора. Если мы его не пишем -- не беда, он автоматически подставляется в пустом виде. По этой причине мы могли не писать конструктор и во втором классе. Но там он все таки написан на предмет того, что возможно мы его все таки исправим. А здесь мы с самого начала договорились ставить только статические поля и статические методы. И второе, этот класс является фактически библиотекой стандартных функций, как было в старых языках. Его можно наращивать как угодно долго и добавлять другие классы такого же типа. Фактически это наш золотой фонд в чистом виде. Примеры функций можно списывать из учебников, статей и т. д., которых полно в интернете.