Статьи

Университет Центрального Вашингтона на платформе NetBeans

Андреас Стефик (на фото справа) — преподаватель, в настоящее время преподающий в Университете Центрального Вашингтона (CWU). В следующем году он начинает преподавать в качестве доцента в Университете Южного Иллинойса в Эдвардсвилле (SIUE). Его основная область интересов и исследований — разработка пользовательских языков программирования и компиляторов.

Несколько лет назад, когда он искал тему диссертации, он заинтересовался небольшим сообществом слепых талантливых программистов. Ему было любопытно, как они выполняли свои ежедневные обязанности по программированию.

Ниже следует интервью с ним на тему инструментов программирования для слепых программистов и решений, созданных на платформе NetBeans Андреасом и студентами CWU.

Андреас, как ты заинтересовался созданием лучших инструментов для слепых программистов?

Данные переписи населения США показывают, что люди с сенсорными нарушениями находятся в значительном неблагоприятном положении в американской рабочей силе. Например, для слепых людей использование существующих IDE часто невероятно сложно, что затрудняет поиск работы на и без того конкурентном рынке. В среднем слепые люди живут в большей бедности, имеют меньшую вероятность быть в составе рабочей силы и получать меньший средний доход.

Мне было любопытно, возможно ли компьютерное программирование для слепого человека, учитывая правильные инструменты, и решил попробовать создать лучшие инструменты, которые могли бы дать некоторым из этих пользователей потенциал для высокооплачиваемой карьеры. В течение нескольких лет я работаю над созданием и тестированием инструментов программирования для слепых, которые, надеюсь, сделают их более доступными. Эти инструменты очень сложны, поскольку в них используются настраиваемые компиляторы, отладчики и звуковые архитектуры, встроенные в стандартные IDE, такие как NetBeans или Visual Studio.

Этот интерес пересекается с платформой NetBeans. Вы даже обучали своих студентов использованию платформы NetBeans. Как все это произошло?

Разработка учебного плана и выбор преподавания информатики в университете — сложное дело. Как вы, вероятно, можете догадаться, это во многом потому, что количество технологий действительно устрашающе! Хуже того, нет волшебного гуру, который говорит профессорам, какие технологии важны, не говоря уже о том, на какие из них мы должны посвятить время занятий. Профессора часто спорят об этом бесконечно, что, вероятно, является вполне разумным способом решения проблемы. В CWU, и я представляю большинство мест, мы стараемся сосредоточиться на концепциях, а не на архитектуре конкретной платформы, такой как NetBeans, Visual Studio или Eclipse.

С учетом вышесказанного, несколько лет назад мы внесли изменения в учебную программу на основе Java (с C ++), и часть этого перехода сменилась на IDE на основе Java. Мы используем jGrasp для наших начальных классов и IDE NetBeans для еще нескольких. Однако для большинства из этих классов мы слишком заняты сосредоточением внимания на деталях алгоритмов или структур данных, чтобы сосредоточиться на деталях платформы NetBeans.

<br /> <meta name="GENERATOR" content="OpenOffice.org 3.0 (Linux)"/></p> <p style="margin-top: 0.19in; margin-bottom: 0.19in"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Но то, как я попал в платформу NetBeans, связано с моим проектом слепого программирования. Каждый год в CWU проходит курс по разработке программного обеспечения, который длится около 20 недель: 2 академических квартала. В этом курсе мы рассылаем сообщения членам местного сообщества с просьбами о проектных предложениях и выбираем те из них, которые, по нашему мнению, соответствуют нужным трудностям для конкретных студентов в этом году. Затем студенты подают резюме, подают заявки на различные предложения, и мы назначаем совместные команды.</font></font></p> <p style="margin-top: 0.19in; margin-bottom: 0.19in"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">В прошлом инструменты, над которыми я работал для слепых, были в основном доморощенными архитектурами компиляторов и отладчиков, которые я писал сам в свое свободное время. Это отлично работает для проведения экспериментов и исследования эффективности окружающей среды, но это не особенно практично. Таким образом, в этом году я решил сделать решающий шаг и переписать свою архитектуру в рамках нашего курса по разработке программного обеспечения на платформе NetBeans.</font></font></p> <p style="margin-top: 0.19in; margin-bottom: 0.19in"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Вот снимок экрана с окружающей средой в целом, снабженный деталями того, что мы добавили. Обратите внимание, что хотя снимок экрана выглядит как NetBeans, мы добавили новый язык программирования (Hop). Кроме того, наш отладчик «всезнающий», что означает, что вы можете выполнять код вперед и назад. Например, в большинстве отладчиков вы можете нажать </font></font><i><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">продолжить</font></font></i><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> (зеленая кнопка) и перейти к следующему пункту останова. В нашем случае вы также можете </font></font><i><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">перематывать</font></font></i><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> (синюю кнопку) на предыдущую точку останова. Точно так же большинство IDE позволяют вам<br /> </font></font><i><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">перешагнуть через</font></font></i><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> строку кода. Наш также позволяет вам </font></font><i><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">отступить</font></font></i><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> .</font></font></p> <p><a href="/sites/all/files/fig-2_29.png"/></p> <p><meta http-equiv="CONTENT-TYPE" content="text/html; charset=UTF-8"/> </p> <p/><title/><br /> <meta name="GENERATOR" content="OpenOffice.org 3.0 (Linux)"/></p> <p><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Этот проект был начат с командой из четырех студентов: Брок Дунда, Эндрю Хейвуд, Шазада Мансур и Даниэль Гарсиа, и вместе мы создали среду под названием « </font></font><a href="https://translate.google.com/translate?sl=en&tl=ru&hl=ru&u=http://sodbeans.sourceforge.net/&client=webapp"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Sodbeans</font></font></a><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> » или «Sonified Omniscient Debugger в NetBeans». </font><font style="vertical-align: inherit;">Учащиеся и я в первую очередь углубились в архитектуру NetBeans без какого-либо опыта. </font><font style="vertical-align: inherit;">Студенты проделали действительно фантастическую работу.  </font></font></p> <p><b><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Каким был ваш опыт использования платформы NetBeans?</font></font></b></p> <p> <meta http-equiv="CONTENT-TYPE" content="text/html; charset=UTF-8"/> </p> <p><title/><br /> <meta name="GENERATOR" content="OpenOffice.org 3.0 (Linux)"/></p> <p style="margin-top: 0.19in; margin-bottom: 0.19in"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Когда мы начинали эту часть проекта слепого программирования, все работающие над ним студенты использовали IDE NetBeans, но никто из нас не обладал более чем базовыми знаниями об архитектуре NetBeans. Я полагаю, я должен готовиться; Я знаю Java в течение очень долгого времени, более десяти лет, поэтому у меня есть достаточно хорошие знания языка и API. Однако знание API Java не обязательно полезно для изучения API-интерфейсов NetBeans. Поэтому, отвечая на ваш вопрос, я бы сказал, что начал изучать платформу NetBeans примерно в сентябре 2008 года. За последний год я многому научился, но вряд ли я эксперт.</font></font></p> <p style="margin-top: 0.19in; margin-bottom: 0.19in"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Изучение платформы NetBeans не так просто, как изучение Java или другого языка программирования. </font><font style="vertical-align: inherit;">Иногда </font></font><a href="https://translate.google.com/translate?sl=en&tl=ru&hl=ru&u=http://www.netbeans.org/kb/trails/platform.html&client=webapp"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">онлайн-уроки</font></font></a><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> дают нам подсказку о том, что нам нужно знать, чтобы завершить то, над чем мы работаем в данный момент, но чаще всего мы застреваем и попадаем в списки рассылки. </font><font style="vertical-align: inherit;">Как и все списки рассылки, они попали и пропустили, но намного лучше, чем ничего. </font><font style="vertical-align: inherit;">Я также думаю, что очень важно работать в команде над проектами при изучении такого сложного API, как NetBeans. </font><font style="vertical-align: inherit;">Таким образом, </font></font><b><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">когда</font></font></b><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> (не если) вы застряли, вы можете спросить друга.<br /> </font></font></p> <p> <b><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Каковы основные части, которые предоставляет ваш пользовательский инструмент для слепых программистов?</font></font></b></p> <p><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Наш пользовательский инструмент включает в себя инструменты для нашего 1) настраиваемого компилятора, 2) настраиваемых механизмов преобразования текста в речь, 3) настраиваемой архитектуры отладчика и ряда других второстепенных компонентов,</font></font></p> <p> <font style="vertical-align: inherit;">таких как интеграция в окно параметров и добавление настраиваемых окон и элементов меню. </font><font style="vertical-align: inherit;">Например, вот снимок экрана с опциями преобразования текста в речь, которые мы допускаем:<br /> </font><meta http-equiv="CONTENT-TYPE" content="text/html; charset=UTF-8"/> </p> <p/><title/><br /> <meta name="GENERATOR" content="OpenOffice.org 3.0 (Linux)"/></p> <p><font style="vertical-align: inherit;"/></p> <p><a href="/sites/all/files/fig-4_14.png"/></p> <p> </p> <p><b><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Давайте теперь поговорим об основных концептуальных камнях преткновения, которые у вас были, когда вы начинали работать с платформой NetBeans.</font></font></b></p> <p> <meta http-equiv="CONTENT-TYPE" content="text/html; charset=UTF-8"/> </p> <p/><title/><br /> <meta name="GENERATOR" content="OpenOffice.org 3.0 (Linux)"/></p> <p style="margin-top: 0.19in; margin-bottom: 0.19in"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Во-первых, я должен сказать, что </font></font><a href="https://translate.google.com/translate?sl=en&tl=ru&hl=ru&u=http://platform.netbeans.org/&client=webapp"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">платформа NetBeans,</font></font></a><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> вероятно, является лучшей из основных платформ IDE, которые я использовал. На данный момент я использовал Visual Studio, NetBeans и, в гораздо меньшей степени, платформы Eclipse для расширения соответствующих IDE. На мой взгляд, платформа NetBeans, вероятно, является самой чистой и лучше всего документированной из всех. С учетом вышесказанного любая IDE является сложной, и я думаю, что наиболее сложными для понимания платформой NetBeans являются: 1) поиск, 2) зависимости модулей и 3) особенности использования платформой NetBeans XML.</font></font></p> <p><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Поиски привели нашу команду в тупик, прежде чем мы поняли, как ее использовать. Чтобы было ясно, </font></font><i><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">идея</font></font></i><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> поиска очень проста: </font></font><i><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">вы «что-то ищите».</font></font></i><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> Это очевидно. К сожалению, из какой-либо существующей документации довольно не очевидно: 1) что вы ищете, 2) когда вам нужно искать вещи, и 3) как вы ищете что-то, и, наконец, 4) почему вам нужно что-то искать вверх.</font></font></p> <p/> <p><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Позвольте мне привести очень конкретный пример. Мы хотели написать свой собственный отладчик и интегрироваться в графический интерфейс NetBeans. В идеале мы хотим, чтобы он функционировал аналогично отладчикам для других языков, с некоторыми улучшениями доступности для слепых. Мы также хотели, чтобы наш отладчик не мешал отладчику для других языков. Другими словами, мы хотим, чтобы наш пользовательский язык легко интегрировался с остальными языками NetBeans, за исключением того, что при загрузке нашего языка он дает слуховую обратную связь пользователю в соответствии с указанным нами способом (который был тщательно протестирован в формальных статистических экспериментах).</font></font></p> <p><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Наша первая мысль о том, как решить эту проблему, заключалась в том, чтобы найти API, который подключается к отладчику в NetBeans, и либо обработать его информацией из нашего компилятора, либо манипулировать им иным способом. В обычных приложениях Java это обычно означает, что вы выполняете импорт, создаете экземпляр объекта или ссылаетесь на некоторый статический объект, а затем каким-то образом манипулируете объектами. Дело в том, что, пытаясь выяснить, «что искать» для управления отладчиком, нам было трудно понять, как нам найти то, что нам нужно для поиска, и контекст, в котором это сделать. В конце концов, мы не воспользовались этим подходом, так как наш собственный компилятор и отладчик в итоге создали свои собственные панели инструментов и окна (предложенные нам некоторыми людьми из списка рассылки), и этот подход хорошо работал, с несколькими ошибками.</font></font></p> <p><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Но с точки зрения поиска, моя точка зрения заключается в том, что учебники по поиску часто говорят, что вы передаете класс механизму поиска, и он будет возвращать экземпляр объекта, но не так просто найти, что искать для любого конкретного приложения (если только приложение просто упоминается </font></font><a href="https://translate.google.com/translate?sl=en&tl=ru&hl=ru&u=http://www.netbeans.org/kb/trails/platform.html&client=webapp"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">в одном из учебных пособий</font></font></a><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> ). </font><font style="vertical-align: inherit;">Было бы неплохо, если бы был ресурс, который перечислял бы основные возможности NetBeans и сообщал программисту, какие классы вы ищете, чтобы сделать что-то полезное (например, манипулирование встроенным отладчиком для данного языка, выполнение вызовов для других частей платформы). ).<br /> </font></font></p> <p><b><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">ОК, это был поиск. </font><font style="vertical-align: inherit;">А как насчет зависимостей?</font></font></b> </p> <p> <meta http-equiv="CONTENT-TYPE" content="text/html; charset=UTF-8"/> </p> <p><title/><br /> <meta name="GENERATOR" content="OpenOffice.org 3.0 (Linux)"/></p> <p style="margin-bottom: 0in"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Помимо поиска и прежде чем что-либо делать в платформе NetBeans, вам также необходимо понять зависимости объектов. Стратегия обычно выглядит следующим образом: 1) выяснить, от какого модуля вам нужно зависеть (если есть), и 2) выполнить поиск того, что вам нужно. По сравнению с типичной Java, модули в NetBeans должны устанавливать явные зависимости для доступа к функциональности этого модуля. С философской точки зрения это звучит как хорошая идея, потому что вам не нужно беспокоиться о внутренних изменениях модуля в следующей версии API.</font></font></p> <p style="margin-top: 0.19in; margin-bottom: 0.19in"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">К сожалению, буквально каждый студент, с которым я работал над этим и другими проектами в платформе NetBeans, был полностью сбит с толку правилами зависимости модулей. Я предполагаю, что это потому, что зависимости модулей не являются «визуально очевидными» в NetBeans. Эти зависимости находятся глубоко в свойствах модуля, над которым вы работаете. Они критически важны для работы модулей NetBeans, но вряд ли очевидны в IDE.</font></font></p> <p style="margin-top: 0.19in; margin-bottom: 0.19in"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Благодаря зависимостям мы также продолжали сталкиваться с тем, что NetBeans называет «Ошибки ошибок». </font><font style="vertical-align: inherit;">Большая часть информации, которую мы смогли найти по этим ошибкам, пришла от онлайн-форумов от разработчиков, которые казались такими же запутанными, как и мы, но суть в том, что они временно остановят компиляцию нашего проекта. </font><font style="vertical-align: inherit;">В нашем случае выгрузка и перегрузка наших зависимостей обычно, казалось, волшебным образом решали проблемы, хотя мы так и не выяснили, почему они вообще произошли, и, казалось, никогда не находили хороший ресурс или учебник по ним. </font><font style="vertical-align: inherit;">Это всего лишь одна из многих проблем, которые, похоже, возникали с зависимостями на протяжении всего проекта.<br /> </font></font></p> <p><b><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">И другие ваши проблемы, связанные с XML, используемым платформой NetBeans.</font></font></b> </p> <p style="margin-top: 0.19in; margin-bottom: 0.19in"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">В платформе NetBeans вы пишете файлы XML (иногда называемые файлами слоев). Изменяя XML, вы можете указать действия или другие способы взаимодействия со средой. Концептуально это расширяемо и имеет смысл. Однако документацию по XML найти сложно. Мы потратили много часов на поиск правильных «волшебных ключевых слов», которые говорят NetBeans, что делать. В Интернете есть много примеров того, как это сделать, но нам было трудно найти какую-либо общую документацию о том, какие слова использовались в XML и в каком контексте их использовать.</font></font></p> <p style="margin-top: 0.19in; margin-bottom: 0.19in"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Например, предположим, что вы хотите добавить действия для «желоба» в пользовательский редактор (например, рисунок для точки останова). Что вы меняете в XML? Должны ли вы даже использовать XML или поиск? Нужна ли вам зависимость от модуля перед изменением XML; прежде чем делать поиск? С точки зрения XML, мы помещаем то, что ниже, в так называемый файл слоя:</font></font></p> <pre class="xml"><filesystem><br/>    <folder name="Editors"><br/>        <folder name="text"><br/>            <folder name="x-hop"><br/>                <folder name="GlyphGutterActions"><br/>                    <file name="org-teambeans-sodbeans-actions-ToggleBreakpointAction.shadow"><br/>                        <attr name="originalFile" stringvalue="Actions/Debug/org-teambeans-sodbeans-actions-ToggleBreakpointAction.instance"/><br/>                        <attr name="position" intvalue="500"/><br/>                    </file><br/>                </folder><br/>            </folder><br/>        </folder><br/>    </folder><br/></filesystem> </pre> <p><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Если вы посмотрите на вышесказанное, вам нужно определить, к каким действиям в канавке обращаются, сначала указав тег файловой системы XML, а затем последовательность из четырех тегов, помеченных как папка (Editor, text, x-hop, GlyphGutterActions). Затем вы указываете ряд действий, которые будут предприняты для действия желоба. Использовать XML легко, но очень трудно понять, какие слова использует NetBeans для описания чего-либо, например, действий с желобами. Хуже того, слова меняются иногда в новых версиях IDE! Было бы неплохо, если бы при вводе символов «<folder =» NetBeans заполнял intellisense тем, какие варианты слов вы можете использовать, и объяснением того, что делает каждый из вариантов. На данный момент, тем не менее, он просто говорит «нет предложений».</font></font></p> <p><b><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Некоторые из ваших последних замечаний следует преодолеть с </font></font><a href="https://translate.google.com/translate?sl=en&tl=ru&hl=ru&u=http://platform.netbeans.org/whatsnew/67.html&client=webapp"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">помощью введения аннотаций в платформе NetBeans 6.7</font></font></a><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> . </font><font style="vertical-align: inherit;">Наконец, каково </font></font></b><b><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">текущее состояние инструментов для слепых программистов?</font></font></b></p> <p> <meta http-equiv="CONTENT-TYPE" content="text/html; charset=UTF-8"/> </p> <p><title/><br /> <meta name="GENERATOR" content="OpenOffice.org 3.0 (Linux)"/></p> <p style="margin-top: 0.19in; margin-bottom: 0.19in"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Я определенно рад играть больше с 6.7 и посмотреть, что вы, ребята, придумали! </font><font style="vertical-align: inherit;">Что касается инструмента, учащиеся завершили альфа-версию, готовую к демонстрации, версию инструмента весной. </font><font style="vertical-align: inherit;">С тех пор несколько студентов закончили обучение и ищут работу, но проект продолжается и недавно стал открытым. </font><font style="vertical-align: inherit;">У нас есть веб-сайт и страница sourceforge. </font><font style="vertical-align: inherit;">У нас также есть ряд чрезвычайно талантливых и опытных слепых программистов, которые так или иначе помогают нам в проекте. </font><font style="vertical-align: inherit;">Это был большой опыт, и я с нетерпением жду продолжения работы и изучения платформы NetBeans.</font></font></p> <p><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Вот ссылка на нашу страницу sourceforge:</font></font></p> <p><a href="https://translate.google.com/translate?sl=en&tl=ru&hl=ru&u=https://sourceforge.net/projects/sodbeans/&client=webapp"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">https://sourceforge.net/projects/sodbeans/</font></font></a></p> <p><a href="https://translate.google.com/translate?sl=en&tl=ru&hl=ru&u=https://sourceforge.net/projects/sodbeans/&client=webapp"/></p> <p><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">И вот ссылка на нашу веб-страницу: </font></font></p> <p> <a href="https://translate.google.com/translate?sl=en&tl=ru&hl=ru&u=http://sodbeans.sourceforge.net/&client=webapp"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">http://sodbeans.sourceforge.net/</font></font></a></p> <p/> <p><b><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Спасибо Андреасу и держите нас в курсе прогресса с этим полезным расширением IDE NetBeans!</font></font></b> </p> </div> <div class="content-html" dz-code-container="" ng-cloak=""> <a ng-href="{{articles[0].pdf}}"></p> <p> </a></p> <div class="pub-content content-html" ng-bind-html="article.shortDesc"/> </div> </div> <style class="advgb-styles-renderer"> &lt;!-- @page { size: 8.27in 11.69in; margin: 0.79in } P { margin-bottom: 0.08in } --&gt;</p> <p> &lt;!-- @page { size: 8.27in 11.69in; margin: 0.79in } P { margin-bottom: 0.08in } --&gt;</p> <p> &lt;!-- @page { size: 8.27in 11.69in; margin: 0.79in } P { margin-bottom: 0.08in } --&gt;</p> <p> &lt;!-- @page { size: 8.27in 11.69in; margin: 0.79in } P { margin-bottom: 0.08in } --&gt; &lt;!-- @page { size: 8.27in 11.69in; margin: 0.79in } P { margin-bottom: 0.08in } --&gt;</p> <p> &lt;!-- @page { size: 8.27in 11.69in; margin: 0.79in } P { margin-bottom: 0.08in } --&gt;</p> <p> &lt;!-- @page { size: 8.27in 11.69in; margin: 0.79in } P { margin-bottom: 0.08in } --&gt; </style> </div><!-- .entry-content --> <div class="saxon-social-share-fixed sidebar-position-right"> <div class="post-social-wrapper"> <div class="post-social-title">Share:</div> <div class="post-social"> <a title="Share with VKontakte" href="https://coderlessons.com/articles/java/universitet-tsentralnogo-vashingtona-na-platforme-netbeans" data-type="vk" data-title="Университет Центрального Вашингтона на платформе NetBeans" data-image="" class="vk-share"> <i class="fa fa-vk"></i></a><a title="Share to Telegram" href="tg://msg?text=%D0%A3%D0%BD%D0%B8%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D1%82%D0%B5%D1%82+%D0%A6%D0%B5%D0%BD%D1%82%D1%80%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE+%D0%92%D0%B0%D1%88%D0%B8%D0%BD%D0%B3%D1%82%D0%BE%D0%BD%D0%B0+%D0%BD%D0%B0+%D0%BF%D0%BB%D0%B0%D1%82%D1%84%D0%BE%D1%80%D0%BC%D0%B5+NetBeans: https://coderlessons.com/articles/java/universitet-tsentralnogo-vashingtona-na-platforme-netbeans" data-type="link" class="telegram-share"> <i class="fa fa-telegram"></i></a><a title="Share by Email" href="mailto:?subject=Университет⠀Центрального⠀Вашингтона⠀на⠀платформе⠀NetBeans&body=https://coderlessons.com/articles/java/universitet-tsentralnogo-vashingtona-na-platforme-netbeans" data-type="link" class="email-share"> <i class="fa fa-envelope-o"></i></a> </div> <div class="clear"></div> </div> </div> </div> </div> </article> <div class="saxon-post saxon-post-bottom"> <div class="post-details-bottom"> <div class="post-info-tags"> </div> <div class="post-info-wrapper"> <div class="post-info-views"><i class="fa fa-eye" aria-hidden="true"></i>34</div> </div> <div class="post-info-share"> <div class="post-social-wrapper"> <div class="post-social-title">Share:</div> <div class="post-social"> <a title="Share with VKontakte" href="https://coderlessons.com/articles/java/universitet-tsentralnogo-vashingtona-na-platforme-netbeans" data-type="vk" data-title="Университет Центрального Вашингтона на платформе NetBeans" data-image="" class="vk-share"> <i class="fa fa-vk"></i></a><a title="Share to Telegram" href="tg://msg?text=%D0%A3%D0%BD%D0%B8%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D1%82%D0%B5%D1%82+%D0%A6%D0%B5%D0%BD%D1%82%D1%80%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE+%D0%92%D0%B0%D1%88%D0%B8%D0%BD%D0%B3%D1%82%D0%BE%D0%BD%D0%B0+%D0%BD%D0%B0+%D0%BF%D0%BB%D0%B0%D1%82%D1%84%D0%BE%D1%80%D0%BC%D0%B5+NetBeans: https://coderlessons.com/articles/java/universitet-tsentralnogo-vashingtona-na-platforme-netbeans" data-type="link" class="telegram-share"> <i class="fa fa-telegram"></i></a><a title="Share by Email" href="mailto:?subject=Университет⠀Центрального⠀Вашингтона⠀на⠀платформе⠀NetBeans&body=https://coderlessons.com/articles/java/universitet-tsentralnogo-vashingtona-na-platforme-netbeans" data-type="link" class="email-share"> <i class="fa fa-envelope-o"></i></a> </div> <div class="clear"></div> </div> </div> </div> </div> </div> <nav id="nav-below" class="navigation-post"> <div class="container-fluid"> <div class="row"> <div class="col-md-6 nav-post-prev saxon-post no-image"> <a href="https://coderlessons.com/articles/java/bezopasnaia-zagruzka-razlichnykh-versii-sobstvennoi-biblioteki-v-jna-ili-jni" class="nav-post-title-link"><div class="nav-post-title">Назад</div><div class="nav-post-name">Безопасная загрузка различных версий собственной библиотеки в JNA (или JNI)</div></a> </div> <div class="col-md-6 nav-post-next saxon-post no-image"> <a href="https://coderlessons.com/articles/java/prostoe-aspektno-orientirovannoe-programmirovanie-aop-s-ispolzovaniem-cdi-v-javaee" class="nav-post-title-link"><div class="nav-post-title">Далее</div><div class="nav-post-name">Простое аспектно-ориентированное программирование (AOP) с использованием CDI в JavaEE</div></a> </div> </div> </div> </nav> </div> <div class="col-md-4 post-sidebar sidebar sidebar-right" role="complementary"> <ul id="post-sidebar"> <li id="saxon-categories-3" class="widget widget_saxon_categories"><h2 class="widgettitle">Категории</h2> <div class="post-categories"> <a href="https://coderlessons.com/articles/veb-razrabotka-articles" data-style="">Веб разработка<span class="post-categories-counter">11825</span></a><a href="https://coderlessons.com/articles/java" data-style="">Java<span class="post-categories-counter">7473</span></a><a href="https://coderlessons.com/articles/programmirovanie" data-style="">Программирование<span class="post-categories-counter">3465</span></a><a href="https://coderlessons.com/articles/mobilnaia-razrabotka-articles" data-style="">Мобильная разработка<span class="post-categories-counter">2983</span></a><a href="https://coderlessons.com/articles/predprinimatelstvo" data-style="">Предпринимательство<span class="post-categories-counter">2337</span></a><a href="https://coderlessons.com/articles/devops-articles" data-style="">DevOps<span class="post-categories-counter">1817</span></a><a href="https://coderlessons.com/articles/wordpress" data-style="">Wordpress<span class="post-categories-counter">1583</span></a><a href="https://coderlessons.com/articles/dizain" data-style="">Дизайн<span class="post-categories-counter">1256</span></a><a href="https://coderlessons.com/articles/php" data-style="">PHP<span class="post-categories-counter">1191</span></a><a href="https://coderlessons.com/articles/bazy-dannykh-articles" data-style="">Базы данных<span class="post-categories-counter">947</span></a><a href="https://coderlessons.com/articles/ruby" data-style="">Ruby<span class="post-categories-counter">692</span></a><a href="https://coderlessons.com/articles/upravlenie-proektami" data-style="">Управление проектами<span class="post-categories-counter">232</span></a><a href="https://coderlessons.com/articles/ai-ml" data-style="">AI/ML<span class="post-categories-counter">25</span></a><a href="https://coderlessons.com/articles/go" data-style="">Go<span class="post-categories-counter">10</span></a><a href="https://coderlessons.com/articles/node-js" data-style="">Node.js<span class="post-categories-counter">8</span></a><a href="https://coderlessons.com/articles/testirovanie" data-style="">Тестирование<span class="post-categories-counter">8</span></a><a href="https://coderlessons.com/articles/gamedev" data-style="">GameDev<span class="post-categories-counter">7</span></a> </div> </li> <li id="saxon-list-posts-14" class="widget widget_saxon_list_entries"> <h2 class="widgettitle">Последние статьи</h2> <ul> <li class="template-postsmasonry1-2"> <div class="saxon-postsmasonry1-post saxon-postsmasonry1_2-post saxon-post saxon-post-no-image format-"><div class="post-categories"><a href="https://coderlessons.com/articles" data-style="background-color: #81d742;">Статьи</a></div><div class="saxon-post-details"> <h3 class="post-title"><a href="https://coderlessons.com/articles/programmirovanie/refaktoring-hudson-god-class">Рефакторинг Hudson God Class</a></h3><div class="post-date">Июнь 3, 2019</div></div></div> </li> <li class="template-postsmasonry1-2"> <div class="saxon-postsmasonry1-post saxon-postsmasonry1_2-post saxon-post saxon-post-no-image format-"><div class="post-categories"><a href="https://coderlessons.com/articles" data-style="background-color: #81d742;">Статьи</a></div><div class="saxon-post-details"> <h3 class="post-title"><a href="https://coderlessons.com/articles/java/alternativy-sintaksisa-java-liambda">Альтернативы синтаксиса Java лямбда</a></h3><div class="post-date">Июнь 2, 2019</div></div></div> </li> <li class="template-postsmasonry1-2"> <div class="saxon-postsmasonry1-post saxon-postsmasonry1_2-post saxon-post saxon-post-no-image format-"><div class="post-categories"><a href="https://coderlessons.com/articles" data-style="background-color: #81d742;">Статьи</a></div><div class="saxon-post-details"> <h3 class="post-title"><a href="https://coderlessons.com/articles/java/morphia-i-mongodb-razvivaiushchiesia-struktury-dokumentov">Morphia и MongoDB: развивающиеся структуры документов</a></h3><div class="post-date">Май 29, 2019</div></div></div> </li> <li class="template-postsmasonry1-2"> <div class="saxon-postsmasonry1-post saxon-postsmasonry1_2-post saxon-post saxon-post-no-image format-"><div class="post-categories"><a href="https://coderlessons.com/articles" data-style="background-color: #81d742;">Статьи</a></div><div class="saxon-post-details"> <h3 class="post-title"><a href="https://coderlessons.com/articles/java/openshift-express-razvertyvanie-prilozheniia-java-ee-s-podderzhkoi-as7">OpenShift Express: развертывание приложения Java EE (с поддержкой AS7)</a></h3><div class="post-date">Май 29, 2019</div></div></div> </li> <li class="template-postsmasonry1-2"> <div class="saxon-postsmasonry1-post saxon-postsmasonry1_2-post saxon-post saxon-post-no-image format-"><div class="post-categories"><a href="https://coderlessons.com/articles" data-style="background-color: #81d742;">Статьи</a></div><div class="saxon-post-details"> <h3 class="post-title"><a href="https://coderlessons.com/articles/java/integratsiia-jqgrid-rest-ajax-i-spring-mvc">Интеграция jqGrid, REST, AJAX и Spring MVC</a></h3><div class="post-date">Май 29, 2019</div></div></div> </li> </ul> </li> <li id="custom_html-8" class="widget_text widget widget_custom_html"><div class="textwidget custom-html-widget"><div class="rl_cnt_bg" data-id="289286"></div></div></li> <li id="custom_html-9" class="widget_text widget widget_custom_html"><div class="textwidget custom-html-widget"><div class="rl_cnt_bg" data-id="289288"></div></div></li> <li id="custom_html-10" class="widget_text widget widget_custom_html"><div class="textwidget custom-html-widget"><div class="rl_cnt_bg" data-id="289289"></div></div></li> </ul> </div> </div> </div> </div> <a class="scroll-to-top btn alt" aria-label="Scroll to top" href="#top"></a> <div class="footer-wrapper"> <footer class="footer-black"> <div class="container"> <div class="row"> <div class="col-md-12 footer-menu" role="navigation"> </div> <div class="col-md-12 col-sm-12 footer-copyright"> <p>© Copyright 2024 <a href="https://coderlessons.com">CoderLessons.com</a></p> </div> </div> </div> </footer> </div> <script type='text/javascript'> "use strict";var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||!1,descriptor.configurable=!0,"value"in descriptor&&(descriptor.writable=!0),Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){return protoProps&&defineProperties(Constructor.prototype,protoProps),staticProps&&defineProperties(Constructor,staticProps),Constructor}}();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor))throw new TypeError("Cannot call a class as a function")}var RocketBrowserCompatibilityChecker=function(){function RocketBrowserCompatibilityChecker(options){_classCallCheck(this,RocketBrowserCompatibilityChecker),this.passiveSupported=!1,this._checkPassiveOption(this),this.options=!!this.passiveSupported&&options}return _createClass(RocketBrowserCompatibilityChecker,[{key:"_checkPassiveOption",value:function(self){try{var options={get passive(){return!(self.passiveSupported=!0)}};window.addEventListener("test",null,options),window.removeEventListener("test",null,options)}catch(err){self.passiveSupported=!1}}},{key:"initRequestIdleCallback",value:function(){!1 in window&&(window.requestIdleCallback=function(cb){var start=Date.now();return setTimeout(function(){cb({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-start))}})},1)}),!1 in window&&(window.cancelIdleCallback=function(id){return clearTimeout(id)})}},{key:"isDataSaverModeOn",value:function(){return"connection"in navigator&&!0===navigator.connection.saveData}},{key:"supportsLinkPrefetch",value:function(){var elem=document.createElement("link");return elem.relList&&elem.relList.supports&&elem.relList.supports("prefetch")&&window.IntersectionObserver&&"isIntersecting"in IntersectionObserverEntry.prototype}},{key:"isSlowConnection",value:function(){return"connection"in navigator&&"effectiveType"in navigator.connection&&("2g"===navigator.connection.effectiveType||"slow-2g"===navigator.connection.effectiveType)}}]),RocketBrowserCompatibilityChecker}(); </script> <script type='text/javascript'> class RocketLazyLoadScripts{constructor(t,e){this.attrName="data-rocketlazyloadscript",this.browser=e,this.options=this.browser.options,this.triggerEvents=t,this.userEventListener=this.triggerListener.bind(this),window.addEventListener("touchstart",function(){})}init(){this._addEventListener(this)}reset(){this._removeEventListener(this)}_addEventListener(t){this.triggerEvents.forEach(e=>window.addEventListener(e,t.userEventListener,t.options))}_removeEventListener(t){this.triggerEvents.forEach(e=>window.removeEventListener(e,t.userEventListener,t.options))}_loadScriptSrc(){const t=document.querySelectorAll(`script[${this.attrName}]`);0!==t.length?(Array.prototype.slice.call(t).forEach(t=>{const e=t.getAttribute(this.attrName);t.setAttribute("src",e),t.removeAttribute(this.attrName)}),this.reset()):this.reset()}triggerListener(t){if(t&&t.target){if("A"==t.target.tagName)return;if("I"==t.target.tagName&&"fa fa-bars"==t.target.className)return}this._loadScriptSrc(),this._removeEventListener(this)}static run(){if(!RocketBrowserCompatibilityChecker)return;const t=new RocketBrowserCompatibilityChecker({passive:!0});new RocketLazyLoadScripts(["keydown","mouseover","touchmove","touchstart"],t).init()}}RocketLazyLoadScripts.run(); </script> <script type='text/javascript'> /* <![CDATA[ */ var RocketPreloadLinksConfig = {"excludeUris":"\/(.+\/)?feed\/?.+\/?|\/(?:.+\/)?embed\/|\/(index\\.php\/)?wp\\-json(\/.*|$)|\/wp-admin|\/logout|\/wp-login.php","usesTrailingSlash":"","imageExt":"jpg|jpeg|gif|png|tiff|bmp|webp|avif","fileExt":"jpg|jpeg|gif|png|tiff|bmp|webp|avif|php|pdf|html|htm","siteUrl":"https:\/\/coderlessons.com","onHoverDelay":"100","rateThrottle":"3"}; /* ]]> */ </script> <script type='text/javascript'> (function() { "use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e=function(){function i(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(e,t,n){return t&&i(e.prototype,t),n&&i(e,n),e}}();function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var t=function(){function n(e,t){i(this,n),this.browser=e,this.config=t,this.options=this.browser.options,this.prefetched=new Set,this.eventTime=null,this.threshold=1111,this.numOnHover=0}return e(n,[{key:"init",value:function(){!this.browser.supportsLinkPrefetch()||this.browser.isDataSaverModeOn()||this.browser.isSlowConnection()||(this.regex={excludeUris:RegExp(this.config.excludeUris,"i"),images:RegExp(".("+this.config.imageExt+")$","i"),fileExt:RegExp(".("+this.config.fileExt+")$","i")},this._initListeners(this))}},{key:"_initListeners",value:function(e){-1<this.config.onHoverDelay&&document.addEventListener("mouseover",e.listener.bind(e),e.listenerOptions),document.addEventListener("mousedown",e.listener.bind(e),e.listenerOptions),document.addEventListener("touchstart",e.listener.bind(e),e.listenerOptions)}},{key:"listener",value:function(e){var t=e.target.closest("a"),n=this._prepareUrl(t);if(null!==n)switch(e.type){case"mousedown":case"touchstart":this._addPrefetchLink(n);break;case"mouseover":this._earlyPrefetch(t,n,"mouseout")}}},{key:"_earlyPrefetch",value:function(t,e,n){var i=this,r=setTimeout(function(){if(r=null,0===i.numOnHover)setTimeout(function(){return i.numOnHover=0},1e3);else if(i.numOnHover>i.config.rateThrottle)return;i.numOnHover++,i._addPrefetchLink(e)},this.config.onHoverDelay);t.addEventListener(n,function e(){t.removeEventListener(n,e,{passive:!0}),null!==r&&(clearTimeout(r),r=null)},{passive:!0})}},{key:"_addPrefetchLink",value:function(i){return this.prefetched.add(i.href),new Promise(function(e,t){var n=document.createElement("link");n.rel="prefetch",n.href=i.href,n.onload=e,n.onerror=t,document.head.appendChild(n)}).catch(function(){})}},{key:"_prepareUrl",value:function(e){if(null===e||"object"!==(void 0===e?"undefined":r(e))||!1 in e||-1===["http:","https:"].indexOf(e.protocol))return null;var t=e.href.substring(0,this.config.siteUrl.length),n=this._getPathname(e.href,t),i={original:e.href,protocol:e.protocol,origin:t,pathname:n,href:t+n};return this._isLinkOk(i)?i:null}},{key:"_getPathname",value:function(e,t){var n=t?e.substring(this.config.siteUrl.length):e;return n.startsWith("/")||(n="/"+n),this._shouldAddTrailingSlash(n)?n+"/":n}},{key:"_shouldAddTrailingSlash",value:function(e){return this.config.usesTrailingSlash&&!e.endsWith("/")&&!this.regex.fileExt.test(e)}},{key:"_isLinkOk",value:function(e){return null!==e&&"object"===(void 0===e?"undefined":r(e))&&(!this.prefetched.has(e.href)&&e.origin===this.config.siteUrl&&-1===e.href.indexOf("?")&&-1===e.href.indexOf("#")&&!this.regex.excludeUris.test(e.href)&&!this.regex.images.test(e.href))}}],[{key:"run",value:function(){"undefined"!=typeof RocketPreloadLinksConfig&&new n(new RocketBrowserCompatibilityChecker({capture:!0,passive:!0}),RocketPreloadLinksConfig).init()}}]),n}();t.run(); }()); </script> <script>window.lazyLoadOptions={elements_selector:"img[data-lazy-src],.rocket-lazyload",data_src:"lazy-src",data_srcset:"lazy-srcset",data_sizes:"lazy-sizes",class_loading:"lazyloading",class_loaded:"lazyloaded",threshold:300,callback_loaded:function(element){if(element.tagName==="IFRAME"&&element.dataset.rocketLazyload=="fitvidscompatible"){if(element.classList.contains("lazyloaded")){if(typeof window.jQuery!="undefined"){if(jQuery.fn.fitVids){jQuery(element).parent().fitVids()}}}}}};window.addEventListener('LazyLoad::Initialized',function(e){var lazyLoadInstance=e.detail.instance;if(window.MutationObserver){var observer=new MutationObserver(function(mutations){var image_count=0;var iframe_count=0;var rocketlazy_count=0;mutations.forEach(function(mutation){for(i=0;i<mutation.addedNodes.length;i++){if(typeof mutation.addedNodes[i].getElementsByTagName!=='function'){continue} if(typeof mutation.addedNodes[i].getElementsByClassName!=='function'){continue} images=mutation.addedNodes[i].getElementsByTagName('img');is_image=mutation.addedNodes[i].tagName=="IMG";iframes=mutation.addedNodes[i].getElementsByTagName('iframe');is_iframe=mutation.addedNodes[i].tagName=="IFRAME";rocket_lazy=mutation.addedNodes[i].getElementsByClassName('rocket-lazyload');image_count+=images.length;iframe_count+=iframes.length;rocketlazy_count+=rocket_lazy.length;if(is_image){image_count+=1} if(is_iframe){iframe_count+=1}}});if(image_count>0||iframe_count>0||rocketlazy_count>0){lazyLoadInstance.update()}});var b=document.getElementsByTagName("body")[0];var config={childList:!0,subtree:!0};observer.observe(b,config)}},!1)</script><script data-no-minify="1" async src="https://coderlessons.com/wp-content/plugins/wp-rocket/assets/js/lazyload/16.1/lazyload.min.js"></script><!-- Yandex.Metrika counter --> <noscript><div><img src="https://mc.yandex.ru/watch/54595627" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <!-- /Yandex.Metrika counter --> <script>"use strict";var wprRemoveCPCSS=function wprRemoveCPCSS(){var elem;document.querySelector('link[data-rocket-async="style"][rel="preload"]')?setTimeout(wprRemoveCPCSS,200):(elem=document.getElementById("rocket-critical-css"))&&"remove"in elem&&elem.remove()};window.addEventListener?window.addEventListener("load",wprRemoveCPCSS):window.attachEvent&&window.attachEvent("onload",wprRemoveCPCSS);</script><script src="https://coderlessons.com/wp-content/cache/min/1/769426e2f3c51b1c0a01c9f49230bab6.js" data-minify="1" defer></script><noscript><link rel="stylesheet" href="https://coderlessons.com/wp-content/cache/min/1/2dae0b0fbff1db926bd5fb7b1e3a08b3.css" media="all" data-minify="1" /></noscript></body> </html> <!-- This website is like a Rocket, isn't it? Performance optimized by WP Rocket. Learn more: https://wp-rocket.me - Debug: cached@1724813536 -->