Как написать свою ide

Некоторое время назад я опубликовал пост, в котором поднял тему низкого уровня качества моего любимого инструмента — PyCharm, и спросил: что делать? Данная проблема видится мне совершенно обескураживающей: 21-й век на дворе, а единственная доступная мне профессиональная IDE развивается по принципу «лучше — больше, но хуже». Имеется около десятка багов, исправление которых я лично жду годами, не говоря уже о тех проблемах, которые мне стало лень зарепортить. Количество багов растёт каждый год с постоянной скоростью, а в качестве оправдания я слышу рассказ о зависимости количества багов от количества пользователей. Альтернатив нет, а пилить свою IDE — почти нереально. Так что же делать?

Среди потока эмоциональных комментариев меня особо заинтересовал один — никем не замеченный, в котором пользователь VISTALL скромно сообщил, как он решил эту проблему для себя. Он сделал свой форк IDEA для .NET и C# — Consulo IDE. Для меня лично такое заявление стало полной неожиданностью. Извините, если кто-то не разделяет моего удивления, но для меня это совершенно непостижимо так же, как вездесущие вечные баги в PyCharm. Ведь IDE разрабатывают большие команды разработчков, а он решил сделать свой форк, пусть даже и

форк

, но

свой

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

— Валерий, давно ты знаком с IDEA?

— Честно говоря, уже забыл, когда познакомился с IDEA (вроде бы с IDEA 7, но не факт). Плагины я начал писать с IDEA 8. После появления IDEA Community Edition началась новая ветка в истории. Медленно я начал изучать платформу, что позднее вылилось в пулл-реквесты и в диалоги на трекере (и не только там). Но были и неприятные истории. Например плагин к Play 1: после какой то очередной правки со стороны платформы плагин стал вести себя нестабильно (toolwindow не закрывался, а превращался в светло-зеленый прямоугольник). Фикса не было, плагин сам был закрыт (его код). И вот вместо того, чтобы ждать фикс, я попросту написал плагин с нуля, т.к накипело. И с того времени я быстрее напишу свой плагин (или фикс), чем буду ждать исправлений.

— Сколько плагинов ты написал на текущий момент? Можешь перечислить самые интересные?

— К IDEA были написаны плагины Play, Lombok, и несколько безымянных плагинов. Также я пытался восстановить C++ плагин к IDEA, но был огорчен тем, что анализ был написан на С++ (и не был открыт авторами). Позднее почти все мои плагины переросли в плагины к моему форку IDEA. Также я написал более 10 новых плагинов. Самые интересные — это, конечно, поддержка .NET и C#.

— Как так получилось, что ты решил форкнуть IDEA?

— Первый мой публичный форк IDEA был для поддержки фреймворка Lombok. Первая проблема состояла в том что IDEA имеет свой анализ java файлов, и не было возможности расширить анализ без изменения самой Java реализации. Вторая проблема — это то, что Java прибита гвоздями в IDEA: нельзя просто заменить Java реализацию на пропатченую версию. Было много спорных вопросов в моем решении проблемы — в итоге дальше форка оно не ушло.

— А были еще и непубличные?

— Да. Я игрался с компилятором Java (javac) и поддержкой мною созданных фич в IDEA. С тех пор я практически всегда сидел на своих билдах IDEA.

— Я так понимаю, ты на этом не остановился?

— Да. Как автор плагинов я видел проблемы, и старался их исправить через патчи либо через пулл-реквесты. Часть была принята, а часть до сих пор находится в подвешенном состоянии.

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

— Большинство моих патчей были маленькие и не задевали глобальных вещей. Насчет больших изменений я поднимал несколько задач в трекере и на форуме. Из самых глобальных — я хотел выровнять Java реализацию с другими плагинами. Суть в том — что IntelliJ IDEA позиционируется в основном как среда для разработки на Java, в итоге часть интерфейса прибита гвоздями к Java-фичам.

Это можно увидеть, например, когда открываешь Project Structure в Node.js проекте, или в том же Node.js проекте видны пункты меню для Java.

— Чем тебе это мешало?

— Банальный вопрос — зачем пользователю скачивать весь Java стек разработки для того, чтобы работать с C#, например.

— А Rider для C# они на тот момент не предлагали?

— Нет. На данный момент Rider — это гибрид Resharper и IntelliJ. Назвать её полноценной IDE на базе IntelliJ я не могу, ибо весь анализ (и не только) лежит на плечах Resharper, который запускается параллельно с Rider. Он отвечает за все фичи, которые касаются .NET платформы.

— Что он из себя представляет твой форк?

— Главная задумка — это сделать универсальную IDE подобную IDEA, но Java будет плагином, а не частью платформы.

Также хотелось исправлять (по возможности) баги, которые находил. Закрытость почти всех плагинов создавала ощущение “раба” ситуации. Зарепортил баг — и ждешь. Даже если бага исправлена, нужно ждать либо EAP, либо релиз. В итоге было решено сделать полностью открытый проект.

— Над IntelliJ IDEA работает целая компания, а ты — один. Неужели реально одному пилить свою IDE, пусть даже и на готовой платформе?

— На деле я не сам. По технической части мне помогает знакомый, как и с тестами. А вот с разработкой плагинов тяжело. Приходится выбирать самое главное из того, что нужно сделать, и не распыляться. А желания сделать что-то новое — есть, например язык F#.
Также периодически переношу изменения из IDEA в Консулу, но не все. Очень много спорных фич, или мешает Kotlin, который сейчас они стараются принести в платформу.

— Чем тебе мешает Kotlin? Его зашивают так же жёстко, как и Java?

— Проблема в другом. Они начинаю писать часть кода на Котлине. С их точки зрения — это нормально. А как со стороны стороннего форка, иметь “новый” язык в платформе — это “тяжелый груз”. При этом нужно учесть, что Kotlin-а ещё нет в Консуле.

— Когда-нибудь они полностью переведут свои IDE на Kotlin — что тогда? Как ты считаешь вообще, всё идёт к этому?

— На деле — код конвертируем. Конечно, большие кучки чего либо на Котлине я не переделываю. Да — рано или поздно так и будет. Если учесть, что Rider написан на Котлине, и не только он. Когда это наступит — это будет новая эра Консулы. Эра возрождения или вымирания — покажет время :)

— В прошлом своём посте я поднимал тему забагованности IDEA. Вот и ты говоришь, что отчасти баги и скорость их исправления натолкнули на создание форка. С чем пришлось столкнуться по мере исправления багов? Много ли их там? Как тебе вообще код IDEA в целом?

— Я унаследовал почти все баги IDEA, также я имею немного своих. Код IDEA, славящийся своей “документацией” (сарказм), вполне понятен. Но встречаются внутренние вещи, которые не понять, если ты не работаешь в JetBrains.

— Я вот замечал, что в некоторых меню первый знак подчёркивания не отображается. А вместо этого местами подчёркнутым отображается символ, идущий за потерянным знаком подчёркивания. Такое есть в разных местах: “File -> Open Recent”, “Run -> Prifle”, “Run -> Concurrency Diagram”. Только в последней версии это починили в “Open Recent”, но проблема остаётся в “Run”.

— Судя по проблеме — это лишняя обработка Mnemonic в тексте меню. Просто нужно запретить обработку mnemonic. Видимо, кто-то забыл, когда в очередной раз правил этот код. Не понимаю почему такие баги должны висеть долго. Беглым поиском проблемы находится вот такой коммит.

— Честно говоря, такие ошибки смотрятся ужасно непрофессионально. Интересно, насколько стары эти баги. Ты их успел зацепить в Consulo?

— Беглым тестом — немного. В Recent Projects я не вижу проблемы. А вот в Run Configurations я вижу эту багу. Фикс на эту багу займет где то 10 минут.

— Когда я открываю эти меню, я долго всматриваюсь, чтобы найти нужный элемент. Я мучался с “Open Recent” очень долго — не знаю сколько. Найденный мною тикет висел полтора года. А ты показываешь коммит, в котором добавлен всего один параметр. И неизвестно, сколько еще провисит ошибка в “Run”. Какие тикеты, по твоим наблюдениям, в JetBrains закрывают быстрее? Добавление поддержки имодзи? :)

— Имодзи — часто запрашиваемая фича. И для ее реализации нужно править JRE. Я за то, что бы добавить, но не в ущерб другим.

— Поскольку ты переносишь изменения из IDEA, то, наверное, следишь за тем, какие фичи там добавляются. Есть ли такие фичи, которые ты не стал переносить из-за их принципиальной ненадобности в IDE?

— Editor Background Image. Я вовсе не понимаю смысл этой фичи. Из архитектурных соображений я не перенес реализацию External Compiler (jps внутри IDEA). Ибо спорная реализация, которая порождает дубликаты. Возможно, я верну эту подсистему, если решу архитектурные проблемы. К этому списку присоединяется прозрачный скролл. В редакторе это смотрится слишком ужасно. Со времен IDEA 8 я видел смены UI для скроллов в редакторе, пока что они ищут золотую середину. Но тестить на пользователях без возможности вернуться на старый UI — это плохо (у меня есть задача 2010 года где я жаловался на юзабилити скролла).

— А ты в своей Consulo как-то улучшаешь UI, помимо поддержки HiDPI?

— Да. Как известно, в IDEA нету возможности нормальной смены UI Theme (Laf), ибо много компонентов имеют “захардкоденную” отрисовку, а также цвета.

— А зачем это нужно? Вот я сижу, программирую, и вообще слабо понимаю, какая разница, какая тема у этой IDE. PyCharm со своей родной темой изначально смотрелся чужим на моём рабочем столе, но зато работу он делал лучше всех. А сейчас я уже привык? и не обращаю внимания на внешний вид.

— Когда-то “захаркоденная” отрисовка была одной из основных проблем на пути к появлению темной темы в IDEA. Но сделать хорошее решения у них не получилось, в итоге в IDEA есть два режима Light / Dark. И для каждого режима есть свой набор цветов которые никак не изменить (адекватно конечно). Хочется сделать нормальное решения чтобы дать юзерам возможность кастомизации интерфейса под себя. Есть несколько IDEA плагинов которые это делают. Но все же они встречают непреодолимые преграды для этого — очередной хардкод.

— Много там ещё такого неприятного хардкода встречается? В смысле, не в темах, а в чём-то ещё, что приходится переделывать.

— Да, приходится встречать призрак прошлого с тех времен, когда IDEA имела только Java реализацию. В платформе есть проверки на java language / java file например.

— На что ты делаешь упор при выборе новых фич? Каким фичам отдаешь предпочтение? Развитие какого функционала ты считаешь самым важным в Consulo, а какой приходится откладывать за недостатком ресурсов?

— В свое время я отложил все проблемы касаемые веб сервисов. И больше был занят поддержкой C# / Mono / Unity. Четыре месяца(сентябрь 2016) назад я решил переделать всю веб часть. Перешёл на Jenkins, написал сервис для пользователей и новый репозиторий для плагинов и платформы (в свою очередь это добавило возможность автоапдейта).

После закрытия беты второй Консулы я хочу сделать поддержку .NET Core.

— В чём ты видишь отличие своего подхода к разработке IDE от того, который используют в JetBrains? Кроме того, что ты ориентируешься на универсальную платформу.

— Первая разница — в том, что всё, что доступно для юзера, можно увидеть на гитхабе в виде исходников. Также можно влиять на саму разработку.

Второе — это более быстрые релизы. В текущий момент в канал “release” поступают билды каждый месяц (beta — каждую неделю, alpha — каждый день).

Я хочу добится более агрессивной смены API. Также активно поддерживать разработчиков сторонних плагинов. Сам помогаю разработчику Perl плагина к IDEA (и не только) — играю роль ходячей энциклопедии по платформе.

Это — из самых основных отличий.

— Ты говоришь “можно влиять на разработку”. И никто не скажет юзеру “это наш бизнес”, да? Один человек жаловался, что ему так и ответили, когда он предлагал что-то поменять в IDEA.

— Мне никто не платит, такое я не скажу. Да, могут быть спорные реквесты, но всё решаемо. Я не планирую продавать ни один из компонентов Консулы.

— Ты пробовал посчитать хотя бы примерно, сколько времени уже потратил на работу над Consulo? Есть ли в этом смысл? Может быть эффективнее было бы потратить это время на работу, за которую платят?

— Работаю над Консулой я с 2013 года. Смысл очень простой: Консула — моя основная среда для разработки. Если я встречаю баг — я исправляю его в течении дня, а не жду по несколько месяцев (очередной релиз IDEA например).

— Сколько сейчас человек пользуются Консулой на постоянной основе? Это возможно как-то достоверно подсчитать?

— Достоверно — нет. Увы сервис статистики у меня написан на коленке, и не даёт точной информации. А так — до 2 тысяч на первой версии, и более 400 человек на второй (которая с недавних пор доступна для скачивания, но имеет статус беты). С февраля 2017 года, первая версия больше не доступна для загрузки.

— Как часто пользователи присылают пулл-реквесты?

— Очень редко. Так как большинство пользователей у меня — это Unity (.NET платформа + C#), есть некие сложности в правке Java исходников. Также у меня хромает документация по всему проекту (более 100 репозиториев, и что в них — знаю только я), я очень медленно её дополняю. Но встречаются люди, которые делаю пулл-реквесты в несколько репозиториев одновременно (как общий фикс одной проблемы)

— А багрепорты и фича-реквесты? Как часто присылают, и как быстро ты на них реагируешь?

— Фичи — редко, баги — чаще. Сейчас я добился хорошей стабильности основного функционала, поэтому багов немного.

Реагирую я практически всегда в тот же день. Исправляю баги по мере приоритетности плагина, но если фикс простой — то исправляю в тот же день

— Как считаешь, по какой причине люди отдают предпочтения Consulo (те, кто отдают). Ты уже перечислил основные достоинства, но у меня ощущение, что это твоя точка зрения, то есть достоинства для тебя лично. А что нравится пользователям?

— Это просто. Консула была единственной нормальной средой C# для macOS. Хотя количество пользователей Windows + Linux догоняет macOS. Раньше была доступная только одна среда — это MonoDevelop (но это тихий ужас). Сейчас появились Visual Studio Code и Rider.

— Если пользователи продолжают прибывать, то, наверное, они находят в Consulo что-то такое, чего нет в других IDE? Что именно?

— Большая часть моей аудитории — это Unity разработчики, до сих пор нет хорошего аналога Консуле. Есть Rider который в статусе EAP, а в будущем будет платным.

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

— Не было, нет, и не будет. Это мое принципиальное решения по поводу закрытого функционала. Это одна из причин, почему я отошёл от IDEA. И возвращаться к этому я не собираюсь. Я хочу сделать открытый проект, а закрытый функционал будет мешать.

— А как на счёт пожертвований?

— Куда без них. У меня пока есть причины, которые мешают этому. В этом году постараюсь исправиться, и тогда наконец-то появится долгожданная кнопочка Donate.

— Каким бы ты хотел видеть будущее Консулы, и насколько, по-твоему, этого реально достичь?

— Вырасти в полноценную организацию/проект по разработке IDE (не только на Desktop). Реально ли? Да — но силами одного человека очень долго.

Большое спасибо, Валерий, что согласился рассказать о своём опыте и разрешил опубликовать этот диалог. Я надеюсь, этот пост поможет найти тебе новых пользователей и единомышленников, и желаю тебе удачи и много терпения.

Больше IDE — хороших и разных!

  • Download Java_IDE_CSharp.zip

Image 1

Image 2

Image 3

Introduction

I have created the named Silver-J project in Visual Studio and used TextEditor as ICSharpCode.TextEditor.dll. You can use any other text editor that you want. In this document we will focus only on creating a project file, reading a project file, and starting processes for compiling a Java source code file. I have defined all the functions in same project without creating other library(dll). There may be some extra, not needed, memory consuming code in it.

To understand this source code, read the Creating Advanced Notepad In C# article.

You can use following articles to create or customize your IDE.

  • Creating Custom Windows Forms In C# using Panels
  • Creating Code Completion In C#
  • Creating AutoComplete HTML Tags In C#
  • Creating DropDownControl In C#

I have used C# programming language to create this IDE but it is possible to create IDE in Java. The benefits of using Java is that you can access all features of it, it also supports many syntax highlighting libraries. C# and Java are syntactically same.

The following article may help you to how to create Tabbed Notepad editor in Java: Creating Advanced Tabbed Notepad In Java.

Requirements

  • Visual Studio 2013 Professional
  • .NET Framework 4.5
  • ICSharpCode.TextEditor.dll library
    • Which I have used in this project because it is free, but you can use any other library for syntax highlighting, I have also used some features of this library.

      You can download it from following sites :

      https://www.nuget.org/packages/ICSharpCode.TextEditor/

      To use this library see the following articles:

      Using ICSharpCode TextEditor

      Extending ICSharpCode TextEditor Syntax Highlighting

      Using-AvalonEdit WPF Text Editor

Files

For this application we need many files where we can store the data.

The following files are stored in the files folder at application location.

  1. appletcode.slvjappletfile

  2. config.slvjfile

  3. defaultprojloc.slvjfile

  4. files.slvjfile

  5. jkeywords.slvjfile

  6. jpackages.slvjfile

  7. mainhtmlsource.slvjmainhtmlfile

  8. themesfile.slvjthemefile

  9. <project_name>.slvjproj

Download the source code.

  1. appletcode.slvjappletfile: this file contains HTML source code with <applet></applet> tag.
  2. config.slvjfile: This file contains the data about everything of our application, like JDK path, and browser path. To show ToolStrip, StatusStrip or not, SplitContainer values. For example:
    ="1.0"="utf-8"
    
    <SilverJConfiguration>
      	
      	<JDKPath>C:Program FilesJavajdk1.8.0_25bin</JDKPath>
      	
      	<WebBrowser>C:Program Files (x86)GoogleChromeApplicationchrome.exe</WebBrowser>
     	 
      	<Font>Microsoft YaHei UI</Font>
      	<FontSize>10</FontSize>
      	
      	
     	 <Appearance>Default</Appearance>
      	
      	<ShowLineNumbers>true</ShowLineNumbers>
      	<ShowLineHighlighter>true</ShowLineHighlighter>
      	<ShowInvalidLines>false</ShowInvalidLines>
      	<ShowEndOfLineMarker>false</ShowEndOfLineMarker>
      	<ShowVisibleSpaces>false</ShowVisibleSpaces>
      	<BracesMatching>true</BracesMatching>
      	<AutoCompleteBraces>true</AutoCompleteBraces>
      	
      	<SplitContainer1>1132</SplitContainer1>
      	<SplitContainer2>559</SplitContainer2>
      	<SplitContainer3>280</SplitContainer3>
      	<SplitContainer4>315</SplitContainer4>
     	 
      	<TabsAlignment>Top</TabsAlignment>
      	<ShowStatusStrip>true</ShowStatusStrip>
     	 <ShowToolStrip>true</ShowToolStrip>
      	<ShowProjectExplorer>true</ShowProjectExplorer>
      	<ShowClassesView>true</ShowClassesView>
      	<ShowMethodsView>true</ShowMethodsView>
      	<ShowErrorList>true</ShowErrorList>
      	<ShowErrorDialog>false</ShowErrorDialog>
      	<ShowStartPageOnStartUp>true</ShowStartPageOnStartUp>
      	
      	<AutoCompileJava>false</AutoCompileJava>
      	
      	<AutoCompletion>true</AutoCompletion>
    </SilverJConfiguration>
  3. defaultprojloc.slvjfile: This file contains the current created or opened project name, project folder path, projectt folder file(.slvjproj) and project type.
        ="1.0"="utf-8"
    <SilverJ>
     	 <DefaultProjectLocation>C:My Java Projects</DefaultProjectLocation>
      	<CurrentProjectName>LookAndFeelDemo</CurrentProjectName>
     <CurrentProjectFileName>C:My Java ProjectsLookAndFeelDemoLookAndFeelDemo.slvjproj</CurrentProjectFileName>
     	 <CurrentProjectType>ApplicationType</CurrentProjectType>
    </SilverJ>
  4. files.slvjfile: This file contain the file names read from <VisualFile></VisualFile> tag from opened project file name.
  5. jkeywords.slvjfile: This file contains the java keywords which be used for code completion (see MyTabPage.cs file)
  6. jpackages.slvjfile: This file contains the java packages which be used to insert packages option Edit->Insert->Packages
  7. mainhtmlsource.slvjmainhtmlfile: Contains the HTML source code when New->HTML file is added or created.
  8. themesfile.slvjthemefile: This file contain the java code when Create Java Class with Java Themes.
  9. <project_name>.slvjproj: This file is stored in the users project folder. This file contain ProjectName, ProjectLocationFolder, ProjectType, MainClassFile, JavaClassFile, VisualFile, OtherFile. For an example of LookAndFeelDemo.slvjproj
        ="1.0"="utf-8"
    <SilverJProject>
      
      <ProjectName>LookAndFeelDemo</ProjectName>
      <ProjectLocationFolder>C:My Java ProjectsLookAndFeelDemo</ProjectLocationFolder>
      <ProjectLocationFile>C:My Java ProjectsLookAndFeelDemoLookAndFeelDemo.slvjproj</ProjectLocationFile>
      <ProjectType>ApplicationType</ProjectType>
      <MainClassFile>C:My Java ProjectsLookAndFeelDemosrcclassesLookAndFeelDemo.java</MainClassFile>
      <JavaClassFile>C:My Java ProjectsLookAndFeelDemosrcclassesJavaBlueTheme.java</JavaClassFile>
      <JavaClassFile>C:My Java ProjectsLookAndFeelDemosrcclassesJavaGreenTheme.java</JavaClassFile>
      <JavaClassFile>C:My Java ProjectsLookAndFeelDemosrcclassesJavaRedTheme.java</JavaClassFile>
      <JavaClassFile>C:My Java ProjectsLookAndFeelDemosrcclassesLookAndFeelDemo.java</JavaClassFile>
      <JavaClassFile>C:My Java ProjectsLookAndFeelDemosrcclassesTestFrame.java</JavaClassFile>
      <VisualFile>C:My Java ProjectsLookAndFeelDemosrcclassesLookAndFeelDemo.java</VisualFile>
      <VisualFile>C:My Java ProjectsLookAndFeelDemosrcclassesJavaGreenTheme.java</VisualFile>
      <VisualFile>C:My Java ProjectsLookAndFeelDemosrcclassesJavaRedTheme.java</VisualFile>
      <VisualFile>C:My Java ProjectsLookAndFeelDemosrcclassesTestFrame.java</VisualFile>
    </SilverJProject>

    VisualFile is the JavaClassFile which is only used to open this file in tab or not when project is opened.

Using the Code

Create Java Project

Add new Windows Form to your project. Here I used New_JavaApplicationProject_Form (New_JavaApplicationProject_Form.cs file) and design it with Project Name textbox, Project Location textbox, Create Java Class checkbox with Browse, Finish & Cancel buttons.

Image 4

In this file New_JavaApplicationProject_Form.cs we will just read a file \files\defaultprojloc.slvjfile.

We will also take input from above form as project name, project location etc.

I have used following variable to store it,

String projloc = ProjectLocationTextBox.Text;
String projfolder = projectfolderlabel.Text;
String projectname = ProjectNameTextBox.Text;
String projectfile;

Now we need to create a folder(directory) same as project name in the read project location folder(projfolder). Once directory is created we will create classes, src, srcclasses named directories in it.

Once project directory created, we need to create project file with file extension as .slvjproj (file name is same as created project name). In that file we will save our project data as defined in above File section. We will save data in XML format.

Following is the function that performs actions.

public void CreateJavaProject()
{
    String projloc = ProjectLocationTextBox.Text;
    String projfolder = projectfolderlabel.Text;
    String projectname = ProjectNameTextBox.Text;
    String projectfile;

    if (projloc != "" && projectname != "")
    {
        projectfile = projectname + ".slvjproj";
        if (checkBox1.Checked == false)
        {
            if (Directory.Exists(projloc + "\" + projfolder))
            {
                MessageBox.Show("Entered project name folder is already exists in current location","Error............");
            }
            else
            {
                
                Directory.CreateDirectory(projloc + "\" + projfolder);

                
                Directory.CreateDirectory(projloc + "\" + projfolder + "\classes");

                
                using (XmlWriter xmlwriter = XmlWriter.Create(projloc + "\" + projfolder + "\" + projectfile))
                {
                    xmlwriter.WriteStartDocument();
                    xmlwriter.WriteStartElement("SilverJProject");
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteComment("Silver-J (1.0) Java Application Project");
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectName", projectname);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectLocationFolder", projloc + "\" + projfolder);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectLocationFile", projloc + "\" + projfolder + "\" + projectfile);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectType", "ApplicationType");
                    xmlwriter.WriteEndElement();
                    xmlwriter.WriteEndDocument();
                    xmlwriter.Close();
                }

                String defaultprojfilepath = Application.StartupPath + "\files\defaultprojloc.slvjfile";

                projectfilename = projloc + "\" + projfolder + "\" + projectfile;

                XmlDocument doc = new XmlDocument();
                doc.Load(defaultprojfilepath);
                doc.SelectSingleNode("SilverJ/DefaultProjectLocation").InnerText = ProjectLocationTextBox.Text;
                doc.SelectSingleNode("SilverJ/CurrentProjectName").InnerText = ProjectNameTextBox.Text;
                doc.SelectSingleNode("SilverJ/CurrentProjectFileName").InnerText = projectfilename;
                doc.SelectSingleNode("SilverJ/CurrentProjectType").InnerText = "ApplicationType";
                doc.Save(defaultprojfilepath);

                a = 1;

                this.Close();
                isfinished = true;
            }
        }


        else if (checkBox1.Checked == true)
        {
            if (JavaClassTextBox.Text != "")
            {
                String classname = JavaClassTextBox.Text;
                if (classname.Contains(".java"))
                {
                }
                else
                {
                    classname = classname + ".java";
                }

                String javafilename = classname;

                if (Directory.Exists(projloc + "\" + projfolder))
                {
                    MessageBox.Show("Entered project name folder is already exists in current location", "Error............");
                }
                else
                {
                    
                    Directory.CreateDirectory(projloc + "\" + projfolder);
                    
                    Directory.CreateDirectory(projloc + "\" + projfolder + "\srcclasses");
                    
                    Directory.CreateDirectory(projloc + "\" + projfolder + "\classes");

                    String fname = projloc + "\" + projfolder + "\srcclasses\" + javafilename;
                    createdfilename = fname;
                    String filename = fname.Substring(fname.LastIndexOf("\") + 1);

                    
                    using (XmlWriter xmlwriter = XmlWriter.Create(projloc + "\" + projfolder + "\" + projectfile))
                    {
                        xmlwriter.WriteStartDocument();
                        xmlwriter.WriteStartElement("SilverJProject");
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteComment("Silver-J (1.0) Java Application Project");
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("ProjectName", projectname);
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("ProjectLocationFolder", projloc + "\" + projfolder);
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("ProjectLocationFile", projloc + "\" + projfolder + "\" + projectfile);
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("ProjectType", "ApplicationType");
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("MainClassFile", fname);
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("JavaClassFile", fname);
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("VisualFile", fname);
                        xmlwriter.WriteEndElement();
                        xmlwriter.WriteEndDocument();
                        xmlwriter.Close();
                    }

                    isSaved = true;

                    String defaultprojfilepath = Application.StartupPath + "\files\defaultprojloc.slvjfile";


                    projectfilename = projloc + "\" + projfolder + "\" + projectfile;

                    XmlDocument doc = new XmlDocument();
                    doc.Load(defaultprojfilepath);
                    doc.SelectSingleNode("SilverJ/DefaultProjectLocation").InnerText = ProjectLocationTextBox.Text;
                    doc.SelectSingleNode("SilverJ/CurrentProjectName").InnerText = ProjectNameTextBox.Text;
                    doc.SelectSingleNode("SilverJ/CurrentProjectFileName").InnerText = projectfilename;
                    doc.SelectSingleNode("SilverJ/CurrentProjectType").InnerText = "ApplicationType";
                    doc.Save(defaultprojfilepath);

                    a = 2;

                    this.Close();
                    isfinished = true;
                }
            }
        }
    }
}

First check if project location and project name are not empty strings. Then check whether Create Java Class check box is checked or not. If it is not checked then just create project without .java source file.

First create our java project file (projectfile = projectname + ".slvjproj";). Then we create this file and start to write that file by using the XmlWriter class.

We will write Project Name, Project Location Folder, Project type tags with its read values. Once we done this we need to change the contents of file defaultprojloc.slvjfile

In this file we will save current created/opened project name, location folder, project location file, project type.

If the Create Java Class check box is checked then we will perform all action as above just adding following tags and info to it where fname is entered Java class file name

xmlwriter.WriteElementString("MainClassFile", fname);
xmlwriter.WriteString("n");
xmlwriter.WriteElementString("JavaClassFile", fname);
xmlwriter.WriteString("n");
xmlwriter.WriteElementString("VisualFile", fname);

I am keeping track of created project, means if Project is created without creating a java class (means Create Java Class checkbox is unchecked) then CheckProjectType() function return 1 otherwise it returns 2 (variable a is used for this). This if for to create file, adding tabs to tabcontrol, adding projectname & filename to treeview etc. in MainForm.cs file.

Consider you have already designed you main IDE.

Now event for clicking on File->New->New Java Application Project

First show the New java application dialog form.

Download the source code.

ReadCurrentProjectFileName() function returns the string as project file name by reading file filesdefaultprojloc.slvjfile by reading tag CurrentProjectFileName.

If CheckProjectType() is 2 then we will create create a file by reading JavaClassFile tag text from current project, add tab to tabcontrol with control of texteditor, changing text of MainForm, adding projectname & file names to ProjectExplorerTreeView and then we will save that file.

private void File_New_JavaApplicationProjectMenuItem_Click(object sender, EventArgs e)
    {
        New_JavaApplicationProject_Form njap = new New_JavaApplicationProject_Form(this, ProjectExplorerTreeView, myTabControl);
        njap.ShowDialog();

        String projectname = "";
        String javaclassfilename = "";

            
            if (njap.CheckProjectType() == 2)
            {
                if (ReadCurrentProjectFileName() != "" && File.Exists(ReadCurrentProjectFileName()))
                {
                    
                    String projectfilename = ReadCurrentProjectFileName();
                    if (File.Exists(projectfilename))
                    {
                        using (XmlReader xmlreader = XmlReader.Create(projectfilename))
                        {
                            while (xmlreader.Read())
                            {
                                if (xmlreader.IsStartElement())
                                {
                                    switch (xmlreader.Name.ToString())
                                    {
                                        case "ProjectName": projectname = xmlreader.ReadString();
                                            break;

                                        case "JavaClassFile": javaclassfilename = xmlreader.ReadString();
                                            break;
                                    }
                                }
                            }
                        }

                        if (projectfilename != "" && javaclassfilename != "" && njap.getCreatedFileName() != "")
                        {
                            
                            
                            
                            ProjectExplorerTreeView.Nodes.Clear();
                            myTabControl.TabPages.Clear();

                            String prjname = projectfilename.Substring(projectfilename.LastIndexOf("\") + 1);
                            prjname = prjname.Remove(prjname.Length - 9);
                            this.Text = "Silver-J - [ " + prjname + " ]";

                            String jclassfilename = javaclassfilename.Substring(javaclassfilename.LastIndexOf("\") + 1);
                            String jclassnamewithoutjava = jclassfilename.Remove(jclassfilename.Length - 5);

                            MyTabPage mytabpage = new MyTabPage(this);
                            mytabpage.Text = jclassfilename;
                            mytabpage.textEditor.Text = "/*******************************n                    "+prjname+"     n*********************************/"
                                 + "npublic class " + jclassnamewithoutjava + "  {" + "n                                                                " + "n}";
                            mytabpage.textEditor.ContextMenuStrip = textEditorContextMenuStrip;

                            myTabControl.TabPages.Add(mytabpage);
                            myTabControl.SelectedTab = mytabpage;

                            TreeNode projecttreenode = new TreeNode();
                            projecttreenode.Text = prjname;
                            projecttreenode.ImageIndex = 6;
                            projecttreenode.SelectedImageIndex = 6;
                            ProjectExplorerTreeView.Nodes.Add(projecttreenode);
                            ProjectExplorerTreeView.SelectedNode = projecttreenode;

                            TreeNode trnode = ProjectExplorerTreeView.Nodes[0];
                            TreeNode jclassnode = new TreeNode();
                            jclassnode.Text = jclassfilename;
                            jclassnode.ImageIndex = 2;
                            jclassnode.SelectedImageIndex = 2;
                            trnode.Nodes.Add(jclassnode);
                            ProjectExplorerTreeView.ExpandAll();

                            if (njap.getCreatedFileName() != "")
                            {
                                try
                                {
                                    StreamWriter strw = new StreamWriter(njap.getCreatedFileName());
                                    strw.Write(mytabpage.textEditor.Text);
                                    strw.Close();
                                    strw.Dispose();
                                }
                                catch
                                { }
                            }
                        }
                    }
                }
            }

             
            else if (njap.CheckProjectType() == 1)
            {
                if (ReadCurrentProjectFileName() != "" && File.Exists(ReadCurrentProjectFileName()))
                {
                    String projectfilename2 = ReadCurrentProjectFileName();
                    if (File.Exists(projectfilename2))
                    {
                        using (XmlReader xmlreader = XmlReader.Create(projectfilename2))
                        {
                            while (xmlreader.Read())
                            {
                                if (xmlreader.IsStartElement())
                                {
                                    switch (xmlreader.Name.ToString())
                                    {
                                        case "ProjectName": projectname = xmlreader.ReadString();
                                            break;
                                    }
                                }
                            }
                        }

                        if (projectfilename2 != "")
                        {
                            ProjectExplorerTreeView.Nodes.Clear();
                            myTabControl.TabPages.Clear();

                            String prjname = projectfilename2.Substring(projectfilename2.LastIndexOf("\") + 1);
                            prjname = prjname.Remove(prjname.Length - 9);
                            this.Text = "Silver-J - [ " + prjname + " ]";


                            TreeNode projecttreenode = new TreeNode();
                            projecttreenode.Text = prjname;
                            projecttreenode.ImageIndex = 6;
                            projecttreenode.SelectedImageIndex = 6;
                            ProjectExplorerTreeView.Nodes.Add(projecttreenode);
                            ProjectExplorerTreeView.SelectedNode = projecttreenode;
                        }
                    }
                }
            }


        if (njap.IsFinished() == true)
        {
            FilenameToolStripLabel.Text = "Silver-J";
            AddFilesToProjectExplorerTreeView();
            WriteCurrentFileNames();
            CopyAllSourceFilesToSRCFolder();
            UpdateWindowsList_WindowMenu();
            SetVisibilityOfToolStripButtons();
            myTabControl_SelectedIndexChanged(sender, e);
        }
    }

If njap.isFinished()==true it will call all functions that we need to change or modify the IDE such as adding files to project explorer tree view, set visibility of toolstrip buttons, changing text of FilenameToolStripLabel to current opened file name.

  • WriteCurrentFileNames() this function reads all files from current opened project file name & write those file name to filesfiles.slvjfile for save operation.
  • CopyAllSourceFilesToSRCFolder() this function copies the all files from srcclasses to src folder without including .class file.
  • UpdateWindowsList_WindowMenu() this function checks tabs in tabcontrol and add those tab texts to Window menu by creating new menu items for selecting each tab by clicking on that menu item.

What we are doing here is that,

In New_JavaApplicationProject_Form.cs file,we are creating project file(<project_name>.slvjproj), writing project data to this file, creating directories (Project named directory in that classes,src, srcclasses directories).

In MainForm.cs file, we are reading created project file(<project_name>.slvjproj), adding tabs to tabcontrol with text of created filename, creating that file and writing that file, and also adding contents to ProjectExplorerTreeview. Where tab is MyTabPage which is going to add to tabcontrol. (see MyTabPage.cs)

See following article for better understanding to add tabs: Creating Advanced Notepad In C#

Same actions to create New Java Applet Project, only one extra content to create means index.html file.

New Java Class

Now we need a class form that create a java class. To create class a java project must created or opened in IDE. The following is the form that create or add java class to current opened project in the application.

Image 5

In file New_Class_Form.cs, we are reading Class Name, also reading Modifiers, Super Class etc. Once the Finish button is clicked, the tab is added to tabcontrol with same as class name by just adding .java to the end of it, and returning this filename with full path (getCreatedFileName() function).

In MainForm.cs file, in File_New_ClassMenuItem_Click() event, we will get this file name (getCreatedFileName()) , read contents from texteditor which is added to tabcontrol by New_Class_Form.cs file, creating this file and writing this contents to file using StreamWriter class.

Finally adding tag <JavaClassFile> and <VisualFile> with text as created filename. Also adding <MainClassFile> tag, this tag text is read when we want to compile a file.

Download the source code to view complete code of ide.

Follwing is the code when File->New->Class option selected

private void File_New_ClassMenuItem_Click(object sender, EventArgs e)
{
    MyTabPage tb = new MyTabPage(this);
    New_Class_Form ncf = new New_Class_Form(tb, myTabControl);
    ncf.ShowDialog();
    String filename = ncf.getCreatedFileName();
    int sel = myTabControl.SelectedIndex;

    if (sel != -1)
    {
        var mytexteditor = myTabControl.TabPages[sel].Controls[0];
        mytexteditor.ContextMenuStrip = textEditorContextMenuStrip;

        if (filename != "")
        {
            
            
            if (File.Exists(filename))
            {
                MessageBox.Show("The file name you entered is already exists in the folder or already added to your project", "Error......");
            }
            else
            {
                try
                {
                    StreamWriter strw = new StreamWriter(File.Create(filename));
                    strw.Write(mytexteditor.Text);
                    strw.Close();
                    strw.Dispose();
                }
                catch
                { }

                
                
                if (ReadCurrentProjectFileName() != "")
                {
                    String projectfilename = ReadCurrentProjectFileName();
                    XmlDocument xmldoc = new XmlDocument();
                    xmldoc.Load(projectfilename);
                    XmlNode node = xmldoc.CreateNode(XmlNodeType.Element, "JavaClassFile", null);
                    node.InnerText = filename;
                    xmldoc.DocumentElement.AppendChild(node);
                    xmldoc.Save(projectfilename);

                    XmlDocument xmldoc2 = new XmlDocument();
                    xmldoc2.Load(projectfilename);
                    XmlNode node2 = xmldoc2.CreateNode(XmlNodeType.Element, "VisualFile", null);
                    node2.InnerText = filename;
                    xmldoc2.DocumentElement.AppendChild(node2);
                    xmldoc2.Save(projectfilename);
                }
            }
        }
    }


    if (ncf.IsFinished() == true)
    {
        AddFilesToProjectExplorerTreeView();
        WriteCurrentFileNames();
        CopyAllSourceFilesToSRCFolder();
        UpdateWindowsList_WindowMenu();
        myTabControl_SelectedIndexChanged(sender, e);

        
        if (Directory.Exists(getCurrentProjectLocationFolder() + "\srcclasses"))
        {
            String mainclassfile = "";
            using (XmlReader reader = XmlReader.Create(ReadCurrentProjectFileName()))
            {
                while (reader.Read())
                {
                    if (reader.IsStartElement())
                    {
                        switch (reader.Name.ToString())
                        {
                            case "MainClassFile":
                                mainclassfile = reader.ReadString();
                                break;
                        }
                    }
                }
            }
            if (mainclassfile == "")
            {
                if (ReadCurrentProjectFileName() != "")
                {
                    String projectfilename = ReadCurrentProjectFileName();
                    XmlDocument xmldoc = new XmlDocument();
                    xmldoc.Load(projectfilename);
                    XmlNode node = xmldoc.CreateNode(XmlNodeType.Element, "MainClassFile", null);
                    node.InnerText = filename;
                    xmldoc.DocumentElement.AppendChild(node);
                    xmldoc.Save(projectfilename);
                }
            }
        }
    }
}

New Package Here we will create a folders in the project folder. When aaa.bbb.ccc package name is entered then we will replace . to ,(aaabbbccc) and will create these directories in current opened project location folder and also will create java class in aaabbbccc folder.

For other options like,

File->New->Interface, File->New->Enums

File->New->HTML File, File->New->CSS File

File->New->Text File, File->New->JavaScript File

File->New->SQL File, File->New->XML File

File->New->New File

Are same code as create New Java Class, just to create files with their own extensions.

Are same code as create New Java Class, just to create files with their own extensions.

Open Project: (File->Open Project) This is nothing but the read file(.slvjproj) from OpenFileDialog, read contents from it, and perform actions about it such as adding application form text to project name text, adds tabs to tabcontrol by getting files by tags

<JavaClassFile>,<HTMLFile> etc. Once project is opened adding Project Type, ProjectName, Project Location Folder to filesdefaultprojloc.slvjfile.

OpenFiles: (File->Open Files) This is same as above(Open Project) only to read files, adding their names to ProjectExplorerTreeView, opening those files on tabs and adding all file names with their full path to filesfiles.slvjfile.

Save: (File->Save) For saving a opened file on tab, I am using FilenameToolStripLabel to show/store current opened file name full path on tab.

I am checking FilenameToolStripLabel contains ‘’ or not, if it contains then read texteditor contents from current selected tab & write it to file from FilenameToolStripLabel.Text or here you can read filesfiles.slvjfile where contains all current opened project files with their full path.

Save All : (File->Save All) For this, iam reading a file filesfiles.slvjfile, comparing each tab with each file name read from files.slvjfile, if it matches then setting that tab to selected, save that file by reading current set tab texteditor with filename

Load Sample Project

As every IDE provides some sample projects, here we will provide following sample projects.

Image 6

First design your sample project form for selecting what kind of project want to create.

Create sample project is nothing but to create a Project file(.slvjproj), Project directory, creating sub directories in it (src, classes, srcclasses), creating project files (.java) in those directories, adding this created project information to filesdefaultprojloc.slvjfile & just call OpenProject function with created project file name.

These project files are located at Samples folder.

First lets define variables to store what files need to be read from Samples folder.

Here I defined notepad_files (notepad source file), notepad_2 (source file name we want to create in/as project)

String[] notepad_files = {
                           Application.StartupPath+"\Samples\Notepad\Notepad.slvjfile"
                         };

    String[] notepad_2 ={
                         "Notepad.java"
                        };

    String defaultprojfilepath = Application.StartupPath + "\files\defaultprojloc.slvjfile";


    public String ProjectLocaionFoder()
    {
        String projectfolder = "";
        using (XmlReader reader = XmlReader.Create(defaultprojfilepath))
        {
            while (reader.Read())
            {
                if (reader.IsStartElement())
                {
                    switch (reader.Name.ToString())
                    {
                        case "DefaultProjectLocation":
                            projectfolder = reader.ReadString();
                            break;
                    }
                }
            }
        }

        return projectfolder;
    }


            String selected_item = listBox1.SelectedItem.ToString();
            String projectfolder = ProjectLocaionFoder();

listBox1 is the control added to form (see above image). selected_item contains selected sample project name and projectfolder contains users project folder.

if (selected_item == "Notepad")
{
    project_name = "Notepad";

    String directory = projectfolder + "\Notepad";
    String projectfile = "Notepad.slvjproj";

    if (Directory.Exists(directory))
    {
        MessageBox.Show("The selected project is already exists in current location", "Error............");
    }

    else
    {

        Directory.CreateDirectory(directory);

        if (Directory.Exists(directory))
        {
            project_folder = directory;

            project_file = directory + "\" + projectfile;
        }

        if (File.Exists(notepad_files[0]))
        {
            String filename = notepad_files[0];
            String fname = filename.Substring(filename.LastIndexOf("\") + 1);
            fname = fname.Remove(fname.Length - 9);
            fname = fname + ".java";

            if (Directory.Exists(directory))
            {
                String src = directory + "\src";
                String srcclasses = directory + "\srcclasses";
                String classes = directory + "\classes";

                Directory.CreateDirectory(src);
                Directory.CreateDirectory(srcclasses);
                Directory.CreateDirectory(classes);

                String content = "";

                content = File.ReadAllText(notepad_files[0]);

                if (Directory.Exists(srcclasses))
                {
                    StreamWriter strw = new StreamWriter(File.Create(srcclasses + "\" + fname));
                    strw.Write(content);
                    strw.Close();
                    strw.Dispose();
                }

                
                using (XmlWriter xmlwriter = XmlWriter.Create(directory + "\" + projectfile))
                {
                    xmlwriter.WriteStartDocument();
                    xmlwriter.WriteStartElement("SilverJProject");
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteComment("Silver-J (1.0) Java Application Project");
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectName", "Notepad");
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectLocationFolder", directory);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectLocationFile", directory + "\" + projectfile);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectType", "ApplicationType");
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("MainClassFile", directory + "\srcclasses" + "\" + notepad_2[0]);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("JavaClassFile", directory + "\srcclasses" + "\" + notepad_2[0]);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("VisualFile", directory + "\srcclasses" + "\" + notepad_2[0]);
                    xmlwriter.WriteEndElement();
                    xmlwriter.WriteEndDocument();
                    xmlwriter.Close();
                }

            }
        }

        is_project_created = true;
    }
}

Here we are just performing actions same as creating new Java application project with Create Java Class checkbox is checked.

Compile & Run

Compiling using IDE means run commands through processes. But here to compile a java source file we dont need any window to show, we just need output of compilation such as errors and warnings. It is easy to create process. We need boolean value whether processes is started or not for compilation.

Consider you are compiling your java programs using cmd, same we are doing here.

e.g: cd C:MyJavaHello

javac.exe HelloWorld.java

Download the source code.

See following code:

Where EXE is application javac.exe with full path

WorkingDirectory is our source file directory (srcclasses)(above e.g C:MyJavaHello)

FileName is our main java source file which we want to compile (HelloWorld.java)

We need only one java source file to compile, you can provide more files.

The main source file is saved in the project file(.slvjproj) with tag <MainClassFile>. This file can be changed by going to Run->Main Class

public bool Compile(String EXE, String WorkingDirectory, String FileName)
    {
        bool processStarted = false;

        if (File.Exists(EXE))
        {
            process.StartInfo.FileName = EXE;
            process.StartInfo.Arguments = FileName;
            process.StartInfo.WorkingDirectory = WorkingDirectory;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.ErrorDialog = false;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            processStarted = process.Start();
        }
        else
        {
            MessageBox.Show("Unable to compile java file. Check your Java Path settings: Current Java Path : ");
        }
        return processStarted;
    }


   public void CompileJava(String file, String jdkpath)
    {
        String mystr = file;
        if (mystr.Contains(".java"))
        {
            mystr = mystr.Remove(mystr.Length - 5);
        }
        if (this.Compile(jdkpath + "\javac.exe", Path.GetDirectoryName(file), Path.GetFileName(file)))
        {
            ErrorReader = process.StandardError;
            string response = ErrorReader.ReadToEnd();

            if (response != "")
            {
                ErrorTextBox.Text = response;
                if (showErrorDialog == true)
                {
                    MessageBox.Show("" + response, "Errors");
                }
            }
            else if (response == "")
            {
                ErrorTextBox.Text = "Program Compiled Successfully.................!";
            }
            else if (response.Contains("uses or overrides a deprecated API."))
            {
                ErrorTextBox.Text = "Program Compiled Successfully.................!";
            }
            else
            {
                ErrorTextBox.Text = "Program Compiled Successfully.................!";
            }
        }
        else if (File.Exists("" + mystr + ".class"))
        {
            ErrorTextBox.Text = "Program Compiled Successfully.................!";
        }

        
        if(myTabControl.TabCount>0)
        {
            if(myTabControl.SelectedTab.Text.Contains(".java"))
            {
                String compilejavafilename = myTabControl.SelectedTab.Text;
                if (ErrorTextBox.Text.Contains(compilejavafilename))
                {
                    int select_index = myTabControl.SelectedIndex;
                    var texteditor = (TextEditorControl)myTabControl.TabPages[select_index].Controls[0];
                    RichTextBox rtb = new RichTextBox();
                    rtb.Text = texteditor.Text;

                    for(int i=0;i<rtb.Lines.Length;i++)
                    {
                        if(ErrorTextBox.Lines[0].Contains(i.ToString()))
                        {
                            texteditor.ActiveTextAreaControl.TextArea.Caret.Line = i-1;
                        }
                    }
                }
            }
        }
    }

showErrorDialog is to hold whether to show dialog after clicking on compile menu item. If an error is found then show it, and set caret to that error line number.

You know how to run Java programs on cmd.

First you compile Java source file, it will create .class file by going to the location folder. And then you run that class file using java.exe command.

e.g: cd C:MyJavaHello

java.exe HelloWorld.class

Instead of using only java.exe, I am using full path of java.exe file(jdk_pathbinjava.exe) as a string.

    String projectlocationfolder = getCurrentProjectLocationFolder();
if (Directory.Exists(projectlocationfolder + "\srcclasses"))
{
    if (filename.Contains(".java"))
    {
        String ffname = filename.Remove(filename.Length - 5);
        ffname = ffname + ".class";

        if (File.Exists(ffname))
        {
            ProcessStartInfo ProcessInfo;
            
            String javapath = """ + jdkpath + "\java.exe" + """;
            String getfilename = filename.Substring(filename.LastIndexOf("\") + 1);
            String fname = "";
            if (getfilename.Contains(".java"))
            {
                fname = getfilename.Remove(getfilename.Length - 5);
            }
            ProcessInfo = new ProcessStartInfo("cmd.exe", "/K" + "  cd/   &&  cd " + workingDirectory + "  &&  " + javapath + "  " + fname);
            ProcessInfo.CreateNoWindow = true;
            ProcessInfo.UseShellExecute = true;
            Process.Start(ProcessInfo);
        }
    }
}

ProcessInfo = new ProcessStartInfo("cmd.exe", "/K" + " cd/ && cd " + workingDirectory + " && " + javapath + " " + fname);

This line run the program. First it starts the cmd.exe with command cd/.

Then goes to project directory(workingDirectory(srcclasses)) by using cd.

Then call java.exe filename full path with .class filename.

Same for Run with Parameter option just adding those parameters after fname.

Same for Run Applet option only just to use appletviewer.exe with HTML source file.

Build Executable Jar

To create executable jar file we need a manifest file (manifest.mf). that file contain following contents.

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.4
Created-By: 1.8.0_25-b18 (Oracle Corporation)
Class-Path:
X-COMMENT: Main-Class will be added automatically by build
Main-Class:
Main-Class:

Where Main-Class: should contain mailclass filename(only filename without any file extension).

Created-By: is the JDK version.

To create jar file using cmd,

First go to working directory.

jar.exe cmf <manifest_file> <outputfile> <class_files>

e.g:

jar.exe cmf manifest.mf Hello.jar HelloWorld.class

In Run_BuildMenuItem_Click(), I have used a textbox to paste all .class files in it and use textbox. Text as class files. It will not add .java source files.

It also adds directories to jar file by adding directory names to textbox.

The process is same as running java programs, just changing in commands, inputs & arguments.

Once jar file is created, we will create a build folder in project location folder & copy created jar file there.

        private void Run_BuildMenuItem_Click(object sender, EventArgs e)
        {
            String projectfolderpath = getCurrentProjectLocationFolder();
            if (projectfolderpath != "")
            {
                if (Directory.Exists(projectfolderpath + "\srcclasses"))
                {
                    String mainclass = getMainClassFileName();
                    String mnclass = mainclass.Substring(mainclass.LastIndexOf("\") + 1);
                    mnclass = mnclass.Remove(mnclass.Length - 5);
                    
                    String maintexttomanifest = "Manifest-Version: 1.0"
                        + "nAnt-Version: Apache Ant 1.9.4"
                        + "nCreated-By: 1.8.0_25-b18 (Oracle Corporation)"
                        + "nClass-Path: "
                        + "nX-COMMENT: Main-Class will be added automatically by build"
                        + "nMain-Class: " + mnclass
                        + "nMain-Class: " + mnclass;

                    String manifestfile = projectfolderpath + "\srcclasses\mainclass.mf";
                    StreamWriter strw = new StreamWriter(manifestfile);
                    strw.Write(maintexttomanifest);
                    strw.Close();
                    strw.Dispose();

                    if (File.Exists(manifestfile))
                    {
                        String srcclassesfolderpath = projectfolderpath + "\srcclasses";
                        List<string> packagenameslist = getPackageNamesList();
                        TextBox textbox = new TextBox();
                        string[] files = Directory.GetFiles(srcclassesfolderpath);

                        foreach (string filePath in files)
                        {
                            if (Path.GetExtension(filePath) != ".java" && Path.GetExtension(filePath) != ".mf")
                            {
                                textbox.Paste(" " + Path.GetFileName(filePath));
                            }
                        }

                        
                        RichTextBox rtb = new RichTextBox();
                        String[] dirs = Directory.GetDirectories(srcclassesfolderpath);
                        foreach (String packagefolder in packagenameslist)
                        {
                            rtb.Text = rtb.Text.Insert(rtb.SelectionStart, "" + packagefolder + "  ");
                        }

                        
                        foreach (String dirsname in dirs)
                        {
                            String dirs2 = dirsname.Substring(dirsname.LastIndexOf("\") + 1);
                            if (rtb.Text.Contains(dirs2)) { }

                            else
                            {
                                textbox.Paste(" " + dirs2 + "* ");
                            }
                        }


                        
                        if (File.Exists(manifestfile))
                        {
                            String jarfilepath = """ + getJDKPath() + "\jar.exe" + """;
                            String prjfolder = getCurrentProjectLocationFolder() + "\srcclasses";
                            String manifestfilename = manifestfile.Substring(manifestfile.LastIndexOf("\") + 1);
                            String classes = textbox.Text;
                            String mainclassfile = mainclass.Substring(mainclass.LastIndexOf("\") + 1);
                            mainclassfile = mainclassfile.Remove(mainclassfile.Length - 5);
                            String jarfilename = mainclassfile + ".jar";

                            ProcessStartInfo ProcessInfo;
                            Process Process;
                            ProcessInfo = new ProcessStartInfo("cmd.exe", "/K " + "cd/  &&  cd  " + prjfolder + " &&  " + jarfilepath + "  cmf   " + manifestfilename + "  " + jarfilename + "   " + classes);
                            ProcessInfo.CreateNoWindow = true;
                            ProcessInfo.UseShellExecute = true;
                            ProcessInfo.WindowStyle = ProcessWindowStyle.Hidden;
                            Process = Process.Start(ProcessInfo);
                        }

                        
                        String createdjarfile = mainclass.Remove(mainclass.Length - 5) + ".jar";
                        if (File.Exists(createdjarfile))
                        {
                            String buildfolder = getCurrentProjectLocationFolder() + "\build";

                            if (Directory.Exists(buildfolder))
                            {
                                String createdjarfile2 = createdjarfile.Replace("srcclasses", "build");
                                File.Delete(createdjarfile2);
                                File.Copy(createdjarfile, createdjarfile2);

                                try
                                {
                                    File.Delete(createdjarfile);
                                }
                                catch { }

                                ShowAboutToolStripLabel.Text = "Build Completed";
                                Run_BuildMenuItem_Click(sender, e);
                            }
                            else
                            {
                                Directory.CreateDirectory(buildfolder);
                                String createdjarfile2 = createdjarfile.Replace("srcclasses", "build");
                                File.Copy(createdjarfile, createdjarfile2);

                                ShowAboutToolStripLabel.Text = "Build Completed";
                                Run_BuildMenuItem_Click(sender, e);
                            }
                        }
                    }
                }
            }
        }

</string>

Appearance

IDE also has different themes. Here I am providing Default, System, Light, Dark & Night appearances.

Appearance means just changing colors of the components.

For MenuStrip and ToolStrip we need to write code for rendering their appearance by drawing. These renderer classes are defined in MyRenderer.cs file.

I have created MyMenuStripZ, MyToolStripZ classes inheriting MenuStrip and ToolStrip and adding renderers to it from file MyRenderer.cs.

Here the code that set Night theme to IDE

 if(type=="Night")
{
    MyMenuStripZ.Renderer = new NightMenuRenderer();
    textEditorContextMenuStrip.Renderer = new NightMenuRenderer();
    ProjectExplorerTreeViewContextMenuStrip.Renderer = new NightMenuRenderer();
    myTabControlContextMenuStrip.Renderer = new NightMenuRenderer();
    ErrorsListContextMenuStrip.Renderer = new NightMenuRenderer();
    MyToolStripZ.Renderer = new NightToolStripRenderer();
    myTabControl.DrawMode = TabDrawMode.OwnerDrawFixed;

    myTabControl.Transparent1 = 255;
    myTabControl.Transparent2 = 255;
    toolstrippanel.Transparent1 = 255;
    toolstrippanel.Transparent2 = 255;
    projectexplorerpanel.Transparent1 = 255;
    projectexplorerpanel.Transparent2 = 255;
    classespanel.Transparent1 = 255;
    classespanel.Transparent2 = 255;
    methodspanel.Transparent1 = 255;
    methodspanel.Transparent2 = 255;
    errorslistpanel.Transparent1 = 255;
    errorslistpanel.Transparent2 = 255;

    MyMenuStripZ.BackColor = Color.FromArgb(255, 30, 30, 30);
    toolstrippanel.StartColor = Color.FromArgb(30, 30, 30);
    toolstrippanel.EndColor = Color.FromArgb(30, 30, 30);
    MyToolStripZ.BackColor = Color.FromArgb(250, 30, 30, 30);

    projectexplorerpanel.StartColor = Color.FromArgb(15, 15, 15);
    projectexplorerpanel.EndColor = Color.FromArgb(15, 15, 15);
    classespanel.StartColor = Color.FromArgb(15, 15, 15);
    classespanel.EndColor = Color.FromArgb(15, 15, 15);
    methodspanel.StartColor = Color.FromArgb(15, 15, 15);
    methodspanel.EndColor = Color.FromArgb(15, 15, 15);
    errorslistpanel.StartColor = Color.FromArgb(15, 15, 15);
    errorslistpanel.EndColor = Color.FromArgb(15, 15, 15);

    projectexplorerlabel.ForeColor = Color.White;
    classeslabel.ForeColor = Color.White;
    methodslabel.ForeColor = Color.White;
    errorslabel.ForeColor = Color.White;

    myTabControl.ActiveTabStartColor = Color.FromArgb(10, 10, 30);
    myTabControl.ActiveTabEndColor = Color.FromArgb(10, 10, 30);
    myTabControl.NonActiveTabStartColor = Color.FromArgb(60, 60, 60);
    myTabControl.NonActiveTabEndColor = Color.FromArgb(60, 60, 60);

    myTabControl.TextColor = Color.White;

    splitContainer1.BackColor = Color.FromArgb(255,10, 10, 10);

    ProjectExplorerTreeView.BackColor = Color.FromArgb(255, 25, 25, 25);
    ClassesTreeView.BackColor = Color.FromArgb(255, 25, 25, 25);
    MethodsTreeView.BackColor = Color.FromArgb(255, 25, 25, 25);
    ErrorTextBox.BackColor = Color.FromArgb(255, 25, 25, 25);

    ProjectExplorerTreeView.ForeColor = Color.White;
    ClassesTreeView.ForeColor = Color.White;
    MethodsTreeView.ForeColor = Color.White;
    ErrorTextBox.ForeColor = Color.FromArgb(255, 255, 220, 220);
}

  • Download Java_IDE_CSharp.zip

Image 1

Image 2

Image 3

Introduction

I have created the named Silver-J project in Visual Studio and used TextEditor as ICSharpCode.TextEditor.dll. You can use any other text editor that you want. In this document we will focus only on creating a project file, reading a project file, and starting processes for compiling a Java source code file. I have defined all the functions in same project without creating other library(dll). There may be some extra, not needed, memory consuming code in it.

To understand this source code, read the Creating Advanced Notepad In C# article.

You can use following articles to create or customize your IDE.

  • Creating Custom Windows Forms In C# using Panels
  • Creating Code Completion In C#
  • Creating AutoComplete HTML Tags In C#
  • Creating DropDownControl In C#

I have used C# programming language to create this IDE but it is possible to create IDE in Java. The benefits of using Java is that you can access all features of it, it also supports many syntax highlighting libraries. C# and Java are syntactically same.

The following article may help you to how to create Tabbed Notepad editor in Java: Creating Advanced Tabbed Notepad In Java.

Requirements

  • Visual Studio 2013 Professional
  • .NET Framework 4.5
  • ICSharpCode.TextEditor.dll library
    • Which I have used in this project because it is free, but you can use any other library for syntax highlighting, I have also used some features of this library.

      You can download it from following sites :

      https://www.nuget.org/packages/ICSharpCode.TextEditor/

      To use this library see the following articles:

      Using ICSharpCode TextEditor

      Extending ICSharpCode TextEditor Syntax Highlighting

      Using-AvalonEdit WPF Text Editor

Files

For this application we need many files where we can store the data.

The following files are stored in the files folder at application location.

  1. appletcode.slvjappletfile

  2. config.slvjfile

  3. defaultprojloc.slvjfile

  4. files.slvjfile

  5. jkeywords.slvjfile

  6. jpackages.slvjfile

  7. mainhtmlsource.slvjmainhtmlfile

  8. themesfile.slvjthemefile

  9. <project_name>.slvjproj

Download the source code.

  1. appletcode.slvjappletfile: this file contains HTML source code with <applet></applet> tag.
  2. config.slvjfile: This file contains the data about everything of our application, like JDK path, and browser path. To show ToolStrip, StatusStrip or not, SplitContainer values. For example:
    ="1.0"="utf-8"
    
    <SilverJConfiguration>
      	
      	<JDKPath>C:Program FilesJavajdk1.8.0_25bin</JDKPath>
      	
      	<WebBrowser>C:Program Files (x86)GoogleChromeApplicationchrome.exe</WebBrowser>
     	 
      	<Font>Microsoft YaHei UI</Font>
      	<FontSize>10</FontSize>
      	
      	
     	 <Appearance>Default</Appearance>
      	
      	<ShowLineNumbers>true</ShowLineNumbers>
      	<ShowLineHighlighter>true</ShowLineHighlighter>
      	<ShowInvalidLines>false</ShowInvalidLines>
      	<ShowEndOfLineMarker>false</ShowEndOfLineMarker>
      	<ShowVisibleSpaces>false</ShowVisibleSpaces>
      	<BracesMatching>true</BracesMatching>
      	<AutoCompleteBraces>true</AutoCompleteBraces>
      	
      	<SplitContainer1>1132</SplitContainer1>
      	<SplitContainer2>559</SplitContainer2>
      	<SplitContainer3>280</SplitContainer3>
      	<SplitContainer4>315</SplitContainer4>
     	 
      	<TabsAlignment>Top</TabsAlignment>
      	<ShowStatusStrip>true</ShowStatusStrip>
     	 <ShowToolStrip>true</ShowToolStrip>
      	<ShowProjectExplorer>true</ShowProjectExplorer>
      	<ShowClassesView>true</ShowClassesView>
      	<ShowMethodsView>true</ShowMethodsView>
      	<ShowErrorList>true</ShowErrorList>
      	<ShowErrorDialog>false</ShowErrorDialog>
      	<ShowStartPageOnStartUp>true</ShowStartPageOnStartUp>
      	
      	<AutoCompileJava>false</AutoCompileJava>
      	
      	<AutoCompletion>true</AutoCompletion>
    </SilverJConfiguration>
  3. defaultprojloc.slvjfile: This file contains the current created or opened project name, project folder path, projectt folder file(.slvjproj) and project type.
        ="1.0"="utf-8"
    <SilverJ>
     	 <DefaultProjectLocation>C:My Java Projects</DefaultProjectLocation>
      	<CurrentProjectName>LookAndFeelDemo</CurrentProjectName>
     <CurrentProjectFileName>C:My Java ProjectsLookAndFeelDemoLookAndFeelDemo.slvjproj</CurrentProjectFileName>
     	 <CurrentProjectType>ApplicationType</CurrentProjectType>
    </SilverJ>
  4. files.slvjfile: This file contain the file names read from <VisualFile></VisualFile> tag from opened project file name.
  5. jkeywords.slvjfile: This file contains the java keywords which be used for code completion (see MyTabPage.cs file)
  6. jpackages.slvjfile: This file contains the java packages which be used to insert packages option Edit->Insert->Packages
  7. mainhtmlsource.slvjmainhtmlfile: Contains the HTML source code when New->HTML file is added or created.
  8. themesfile.slvjthemefile: This file contain the java code when Create Java Class with Java Themes.
  9. <project_name>.slvjproj: This file is stored in the users project folder. This file contain ProjectName, ProjectLocationFolder, ProjectType, MainClassFile, JavaClassFile, VisualFile, OtherFile. For an example of LookAndFeelDemo.slvjproj
        ="1.0"="utf-8"
    <SilverJProject>
      
      <ProjectName>LookAndFeelDemo</ProjectName>
      <ProjectLocationFolder>C:My Java ProjectsLookAndFeelDemo</ProjectLocationFolder>
      <ProjectLocationFile>C:My Java ProjectsLookAndFeelDemoLookAndFeelDemo.slvjproj</ProjectLocationFile>
      <ProjectType>ApplicationType</ProjectType>
      <MainClassFile>C:My Java ProjectsLookAndFeelDemosrcclassesLookAndFeelDemo.java</MainClassFile>
      <JavaClassFile>C:My Java ProjectsLookAndFeelDemosrcclassesJavaBlueTheme.java</JavaClassFile>
      <JavaClassFile>C:My Java ProjectsLookAndFeelDemosrcclassesJavaGreenTheme.java</JavaClassFile>
      <JavaClassFile>C:My Java ProjectsLookAndFeelDemosrcclassesJavaRedTheme.java</JavaClassFile>
      <JavaClassFile>C:My Java ProjectsLookAndFeelDemosrcclassesLookAndFeelDemo.java</JavaClassFile>
      <JavaClassFile>C:My Java ProjectsLookAndFeelDemosrcclassesTestFrame.java</JavaClassFile>
      <VisualFile>C:My Java ProjectsLookAndFeelDemosrcclassesLookAndFeelDemo.java</VisualFile>
      <VisualFile>C:My Java ProjectsLookAndFeelDemosrcclassesJavaGreenTheme.java</VisualFile>
      <VisualFile>C:My Java ProjectsLookAndFeelDemosrcclassesJavaRedTheme.java</VisualFile>
      <VisualFile>C:My Java ProjectsLookAndFeelDemosrcclassesTestFrame.java</VisualFile>
    </SilverJProject>

    VisualFile is the JavaClassFile which is only used to open this file in tab or not when project is opened.

Using the Code

Create Java Project

Add new Windows Form to your project. Here I used New_JavaApplicationProject_Form (New_JavaApplicationProject_Form.cs file) and design it with Project Name textbox, Project Location textbox, Create Java Class checkbox with Browse, Finish & Cancel buttons.

Image 4

In this file New_JavaApplicationProject_Form.cs we will just read a file \files\defaultprojloc.slvjfile.

We will also take input from above form as project name, project location etc.

I have used following variable to store it,

String projloc = ProjectLocationTextBox.Text;
String projfolder = projectfolderlabel.Text;
String projectname = ProjectNameTextBox.Text;
String projectfile;

Now we need to create a folder(directory) same as project name in the read project location folder(projfolder). Once directory is created we will create classes, src, srcclasses named directories in it.

Once project directory created, we need to create project file with file extension as .slvjproj (file name is same as created project name). In that file we will save our project data as defined in above File section. We will save data in XML format.

Following is the function that performs actions.

public void CreateJavaProject()
{
    String projloc = ProjectLocationTextBox.Text;
    String projfolder = projectfolderlabel.Text;
    String projectname = ProjectNameTextBox.Text;
    String projectfile;

    if (projloc != "" && projectname != "")
    {
        projectfile = projectname + ".slvjproj";
        if (checkBox1.Checked == false)
        {
            if (Directory.Exists(projloc + "\" + projfolder))
            {
                MessageBox.Show("Entered project name folder is already exists in current location","Error............");
            }
            else
            {
                
                Directory.CreateDirectory(projloc + "\" + projfolder);

                
                Directory.CreateDirectory(projloc + "\" + projfolder + "\classes");

                
                using (XmlWriter xmlwriter = XmlWriter.Create(projloc + "\" + projfolder + "\" + projectfile))
                {
                    xmlwriter.WriteStartDocument();
                    xmlwriter.WriteStartElement("SilverJProject");
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteComment("Silver-J (1.0) Java Application Project");
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectName", projectname);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectLocationFolder", projloc + "\" + projfolder);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectLocationFile", projloc + "\" + projfolder + "\" + projectfile);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectType", "ApplicationType");
                    xmlwriter.WriteEndElement();
                    xmlwriter.WriteEndDocument();
                    xmlwriter.Close();
                }

                String defaultprojfilepath = Application.StartupPath + "\files\defaultprojloc.slvjfile";

                projectfilename = projloc + "\" + projfolder + "\" + projectfile;

                XmlDocument doc = new XmlDocument();
                doc.Load(defaultprojfilepath);
                doc.SelectSingleNode("SilverJ/DefaultProjectLocation").InnerText = ProjectLocationTextBox.Text;
                doc.SelectSingleNode("SilverJ/CurrentProjectName").InnerText = ProjectNameTextBox.Text;
                doc.SelectSingleNode("SilverJ/CurrentProjectFileName").InnerText = projectfilename;
                doc.SelectSingleNode("SilverJ/CurrentProjectType").InnerText = "ApplicationType";
                doc.Save(defaultprojfilepath);

                a = 1;

                this.Close();
                isfinished = true;
            }
        }


        else if (checkBox1.Checked == true)
        {
            if (JavaClassTextBox.Text != "")
            {
                String classname = JavaClassTextBox.Text;
                if (classname.Contains(".java"))
                {
                }
                else
                {
                    classname = classname + ".java";
                }

                String javafilename = classname;

                if (Directory.Exists(projloc + "\" + projfolder))
                {
                    MessageBox.Show("Entered project name folder is already exists in current location", "Error............");
                }
                else
                {
                    
                    Directory.CreateDirectory(projloc + "\" + projfolder);
                    
                    Directory.CreateDirectory(projloc + "\" + projfolder + "\srcclasses");
                    
                    Directory.CreateDirectory(projloc + "\" + projfolder + "\classes");

                    String fname = projloc + "\" + projfolder + "\srcclasses\" + javafilename;
                    createdfilename = fname;
                    String filename = fname.Substring(fname.LastIndexOf("\") + 1);

                    
                    using (XmlWriter xmlwriter = XmlWriter.Create(projloc + "\" + projfolder + "\" + projectfile))
                    {
                        xmlwriter.WriteStartDocument();
                        xmlwriter.WriteStartElement("SilverJProject");
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteComment("Silver-J (1.0) Java Application Project");
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("ProjectName", projectname);
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("ProjectLocationFolder", projloc + "\" + projfolder);
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("ProjectLocationFile", projloc + "\" + projfolder + "\" + projectfile);
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("ProjectType", "ApplicationType");
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("MainClassFile", fname);
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("JavaClassFile", fname);
                        xmlwriter.WriteString("n");
                        xmlwriter.WriteElementString("VisualFile", fname);
                        xmlwriter.WriteEndElement();
                        xmlwriter.WriteEndDocument();
                        xmlwriter.Close();
                    }

                    isSaved = true;

                    String defaultprojfilepath = Application.StartupPath + "\files\defaultprojloc.slvjfile";


                    projectfilename = projloc + "\" + projfolder + "\" + projectfile;

                    XmlDocument doc = new XmlDocument();
                    doc.Load(defaultprojfilepath);
                    doc.SelectSingleNode("SilverJ/DefaultProjectLocation").InnerText = ProjectLocationTextBox.Text;
                    doc.SelectSingleNode("SilverJ/CurrentProjectName").InnerText = ProjectNameTextBox.Text;
                    doc.SelectSingleNode("SilverJ/CurrentProjectFileName").InnerText = projectfilename;
                    doc.SelectSingleNode("SilverJ/CurrentProjectType").InnerText = "ApplicationType";
                    doc.Save(defaultprojfilepath);

                    a = 2;

                    this.Close();
                    isfinished = true;
                }
            }
        }
    }
}

First check if project location and project name are not empty strings. Then check whether Create Java Class check box is checked or not. If it is not checked then just create project without .java source file.

First create our java project file (projectfile = projectname + ".slvjproj";). Then we create this file and start to write that file by using the XmlWriter class.

We will write Project Name, Project Location Folder, Project type tags with its read values. Once we done this we need to change the contents of file defaultprojloc.slvjfile

In this file we will save current created/opened project name, location folder, project location file, project type.

If the Create Java Class check box is checked then we will perform all action as above just adding following tags and info to it where fname is entered Java class file name

xmlwriter.WriteElementString("MainClassFile", fname);
xmlwriter.WriteString("n");
xmlwriter.WriteElementString("JavaClassFile", fname);
xmlwriter.WriteString("n");
xmlwriter.WriteElementString("VisualFile", fname);

I am keeping track of created project, means if Project is created without creating a java class (means Create Java Class checkbox is unchecked) then CheckProjectType() function return 1 otherwise it returns 2 (variable a is used for this). This if for to create file, adding tabs to tabcontrol, adding projectname & filename to treeview etc. in MainForm.cs file.

Consider you have already designed you main IDE.

Now event for clicking on File->New->New Java Application Project

First show the New java application dialog form.

Download the source code.

ReadCurrentProjectFileName() function returns the string as project file name by reading file filesdefaultprojloc.slvjfile by reading tag CurrentProjectFileName.

If CheckProjectType() is 2 then we will create create a file by reading JavaClassFile tag text from current project, add tab to tabcontrol with control of texteditor, changing text of MainForm, adding projectname & file names to ProjectExplorerTreeView and then we will save that file.

private void File_New_JavaApplicationProjectMenuItem_Click(object sender, EventArgs e)
    {
        New_JavaApplicationProject_Form njap = new New_JavaApplicationProject_Form(this, ProjectExplorerTreeView, myTabControl);
        njap.ShowDialog();

        String projectname = "";
        String javaclassfilename = "";

            
            if (njap.CheckProjectType() == 2)
            {
                if (ReadCurrentProjectFileName() != "" && File.Exists(ReadCurrentProjectFileName()))
                {
                    
                    String projectfilename = ReadCurrentProjectFileName();
                    if (File.Exists(projectfilename))
                    {
                        using (XmlReader xmlreader = XmlReader.Create(projectfilename))
                        {
                            while (xmlreader.Read())
                            {
                                if (xmlreader.IsStartElement())
                                {
                                    switch (xmlreader.Name.ToString())
                                    {
                                        case "ProjectName": projectname = xmlreader.ReadString();
                                            break;

                                        case "JavaClassFile": javaclassfilename = xmlreader.ReadString();
                                            break;
                                    }
                                }
                            }
                        }

                        if (projectfilename != "" && javaclassfilename != "" && njap.getCreatedFileName() != "")
                        {
                            
                            
                            
                            ProjectExplorerTreeView.Nodes.Clear();
                            myTabControl.TabPages.Clear();

                            String prjname = projectfilename.Substring(projectfilename.LastIndexOf("\") + 1);
                            prjname = prjname.Remove(prjname.Length - 9);
                            this.Text = "Silver-J - [ " + prjname + " ]";

                            String jclassfilename = javaclassfilename.Substring(javaclassfilename.LastIndexOf("\") + 1);
                            String jclassnamewithoutjava = jclassfilename.Remove(jclassfilename.Length - 5);

                            MyTabPage mytabpage = new MyTabPage(this);
                            mytabpage.Text = jclassfilename;
                            mytabpage.textEditor.Text = "/*******************************n                    "+prjname+"     n*********************************/"
                                 + "npublic class " + jclassnamewithoutjava + "  {" + "n                                                                " + "n}";
                            mytabpage.textEditor.ContextMenuStrip = textEditorContextMenuStrip;

                            myTabControl.TabPages.Add(mytabpage);
                            myTabControl.SelectedTab = mytabpage;

                            TreeNode projecttreenode = new TreeNode();
                            projecttreenode.Text = prjname;
                            projecttreenode.ImageIndex = 6;
                            projecttreenode.SelectedImageIndex = 6;
                            ProjectExplorerTreeView.Nodes.Add(projecttreenode);
                            ProjectExplorerTreeView.SelectedNode = projecttreenode;

                            TreeNode trnode = ProjectExplorerTreeView.Nodes[0];
                            TreeNode jclassnode = new TreeNode();
                            jclassnode.Text = jclassfilename;
                            jclassnode.ImageIndex = 2;
                            jclassnode.SelectedImageIndex = 2;
                            trnode.Nodes.Add(jclassnode);
                            ProjectExplorerTreeView.ExpandAll();

                            if (njap.getCreatedFileName() != "")
                            {
                                try
                                {
                                    StreamWriter strw = new StreamWriter(njap.getCreatedFileName());
                                    strw.Write(mytabpage.textEditor.Text);
                                    strw.Close();
                                    strw.Dispose();
                                }
                                catch
                                { }
                            }
                        }
                    }
                }
            }

             
            else if (njap.CheckProjectType() == 1)
            {
                if (ReadCurrentProjectFileName() != "" && File.Exists(ReadCurrentProjectFileName()))
                {
                    String projectfilename2 = ReadCurrentProjectFileName();
                    if (File.Exists(projectfilename2))
                    {
                        using (XmlReader xmlreader = XmlReader.Create(projectfilename2))
                        {
                            while (xmlreader.Read())
                            {
                                if (xmlreader.IsStartElement())
                                {
                                    switch (xmlreader.Name.ToString())
                                    {
                                        case "ProjectName": projectname = xmlreader.ReadString();
                                            break;
                                    }
                                }
                            }
                        }

                        if (projectfilename2 != "")
                        {
                            ProjectExplorerTreeView.Nodes.Clear();
                            myTabControl.TabPages.Clear();

                            String prjname = projectfilename2.Substring(projectfilename2.LastIndexOf("\") + 1);
                            prjname = prjname.Remove(prjname.Length - 9);
                            this.Text = "Silver-J - [ " + prjname + " ]";


                            TreeNode projecttreenode = new TreeNode();
                            projecttreenode.Text = prjname;
                            projecttreenode.ImageIndex = 6;
                            projecttreenode.SelectedImageIndex = 6;
                            ProjectExplorerTreeView.Nodes.Add(projecttreenode);
                            ProjectExplorerTreeView.SelectedNode = projecttreenode;
                        }
                    }
                }
            }


        if (njap.IsFinished() == true)
        {
            FilenameToolStripLabel.Text = "Silver-J";
            AddFilesToProjectExplorerTreeView();
            WriteCurrentFileNames();
            CopyAllSourceFilesToSRCFolder();
            UpdateWindowsList_WindowMenu();
            SetVisibilityOfToolStripButtons();
            myTabControl_SelectedIndexChanged(sender, e);
        }
    }

If njap.isFinished()==true it will call all functions that we need to change or modify the IDE such as adding files to project explorer tree view, set visibility of toolstrip buttons, changing text of FilenameToolStripLabel to current opened file name.

  • WriteCurrentFileNames() this function reads all files from current opened project file name & write those file name to filesfiles.slvjfile for save operation.
  • CopyAllSourceFilesToSRCFolder() this function copies the all files from srcclasses to src folder without including .class file.
  • UpdateWindowsList_WindowMenu() this function checks tabs in tabcontrol and add those tab texts to Window menu by creating new menu items for selecting each tab by clicking on that menu item.

What we are doing here is that,

In New_JavaApplicationProject_Form.cs file,we are creating project file(<project_name>.slvjproj), writing project data to this file, creating directories (Project named directory in that classes,src, srcclasses directories).

In MainForm.cs file, we are reading created project file(<project_name>.slvjproj), adding tabs to tabcontrol with text of created filename, creating that file and writing that file, and also adding contents to ProjectExplorerTreeview. Where tab is MyTabPage which is going to add to tabcontrol. (see MyTabPage.cs)

See following article for better understanding to add tabs: Creating Advanced Notepad In C#

Same actions to create New Java Applet Project, only one extra content to create means index.html file.

New Java Class

Now we need a class form that create a java class. To create class a java project must created or opened in IDE. The following is the form that create or add java class to current opened project in the application.

Image 5

In file New_Class_Form.cs, we are reading Class Name, also reading Modifiers, Super Class etc. Once the Finish button is clicked, the tab is added to tabcontrol with same as class name by just adding .java to the end of it, and returning this filename with full path (getCreatedFileName() function).

In MainForm.cs file, in File_New_ClassMenuItem_Click() event, we will get this file name (getCreatedFileName()) , read contents from texteditor which is added to tabcontrol by New_Class_Form.cs file, creating this file and writing this contents to file using StreamWriter class.

Finally adding tag <JavaClassFile> and <VisualFile> with text as created filename. Also adding <MainClassFile> tag, this tag text is read when we want to compile a file.

Download the source code to view complete code of ide.

Follwing is the code when File->New->Class option selected

private void File_New_ClassMenuItem_Click(object sender, EventArgs e)
{
    MyTabPage tb = new MyTabPage(this);
    New_Class_Form ncf = new New_Class_Form(tb, myTabControl);
    ncf.ShowDialog();
    String filename = ncf.getCreatedFileName();
    int sel = myTabControl.SelectedIndex;

    if (sel != -1)
    {
        var mytexteditor = myTabControl.TabPages[sel].Controls[0];
        mytexteditor.ContextMenuStrip = textEditorContextMenuStrip;

        if (filename != "")
        {
            
            
            if (File.Exists(filename))
            {
                MessageBox.Show("The file name you entered is already exists in the folder or already added to your project", "Error......");
            }
            else
            {
                try
                {
                    StreamWriter strw = new StreamWriter(File.Create(filename));
                    strw.Write(mytexteditor.Text);
                    strw.Close();
                    strw.Dispose();
                }
                catch
                { }

                
                
                if (ReadCurrentProjectFileName() != "")
                {
                    String projectfilename = ReadCurrentProjectFileName();
                    XmlDocument xmldoc = new XmlDocument();
                    xmldoc.Load(projectfilename);
                    XmlNode node = xmldoc.CreateNode(XmlNodeType.Element, "JavaClassFile", null);
                    node.InnerText = filename;
                    xmldoc.DocumentElement.AppendChild(node);
                    xmldoc.Save(projectfilename);

                    XmlDocument xmldoc2 = new XmlDocument();
                    xmldoc2.Load(projectfilename);
                    XmlNode node2 = xmldoc2.CreateNode(XmlNodeType.Element, "VisualFile", null);
                    node2.InnerText = filename;
                    xmldoc2.DocumentElement.AppendChild(node2);
                    xmldoc2.Save(projectfilename);
                }
            }
        }
    }


    if (ncf.IsFinished() == true)
    {
        AddFilesToProjectExplorerTreeView();
        WriteCurrentFileNames();
        CopyAllSourceFilesToSRCFolder();
        UpdateWindowsList_WindowMenu();
        myTabControl_SelectedIndexChanged(sender, e);

        
        if (Directory.Exists(getCurrentProjectLocationFolder() + "\srcclasses"))
        {
            String mainclassfile = "";
            using (XmlReader reader = XmlReader.Create(ReadCurrentProjectFileName()))
            {
                while (reader.Read())
                {
                    if (reader.IsStartElement())
                    {
                        switch (reader.Name.ToString())
                        {
                            case "MainClassFile":
                                mainclassfile = reader.ReadString();
                                break;
                        }
                    }
                }
            }
            if (mainclassfile == "")
            {
                if (ReadCurrentProjectFileName() != "")
                {
                    String projectfilename = ReadCurrentProjectFileName();
                    XmlDocument xmldoc = new XmlDocument();
                    xmldoc.Load(projectfilename);
                    XmlNode node = xmldoc.CreateNode(XmlNodeType.Element, "MainClassFile", null);
                    node.InnerText = filename;
                    xmldoc.DocumentElement.AppendChild(node);
                    xmldoc.Save(projectfilename);
                }
            }
        }
    }
}

New Package Here we will create a folders in the project folder. When aaa.bbb.ccc package name is entered then we will replace . to ,(aaabbbccc) and will create these directories in current opened project location folder and also will create java class in aaabbbccc folder.

For other options like,

File->New->Interface, File->New->Enums

File->New->HTML File, File->New->CSS File

File->New->Text File, File->New->JavaScript File

File->New->SQL File, File->New->XML File

File->New->New File

Are same code as create New Java Class, just to create files with their own extensions.

Are same code as create New Java Class, just to create files with their own extensions.

Open Project: (File->Open Project) This is nothing but the read file(.slvjproj) from OpenFileDialog, read contents from it, and perform actions about it such as adding application form text to project name text, adds tabs to tabcontrol by getting files by tags

<JavaClassFile>,<HTMLFile> etc. Once project is opened adding Project Type, ProjectName, Project Location Folder to filesdefaultprojloc.slvjfile.

OpenFiles: (File->Open Files) This is same as above(Open Project) only to read files, adding their names to ProjectExplorerTreeView, opening those files on tabs and adding all file names with their full path to filesfiles.slvjfile.

Save: (File->Save) For saving a opened file on tab, I am using FilenameToolStripLabel to show/store current opened file name full path on tab.

I am checking FilenameToolStripLabel contains ‘’ or not, if it contains then read texteditor contents from current selected tab & write it to file from FilenameToolStripLabel.Text or here you can read filesfiles.slvjfile where contains all current opened project files with their full path.

Save All : (File->Save All) For this, iam reading a file filesfiles.slvjfile, comparing each tab with each file name read from files.slvjfile, if it matches then setting that tab to selected, save that file by reading current set tab texteditor with filename

Load Sample Project

As every IDE provides some sample projects, here we will provide following sample projects.

Image 6

First design your sample project form for selecting what kind of project want to create.

Create sample project is nothing but to create a Project file(.slvjproj), Project directory, creating sub directories in it (src, classes, srcclasses), creating project files (.java) in those directories, adding this created project information to filesdefaultprojloc.slvjfile & just call OpenProject function with created project file name.

These project files are located at Samples folder.

First lets define variables to store what files need to be read from Samples folder.

Here I defined notepad_files (notepad source file), notepad_2 (source file name we want to create in/as project)

String[] notepad_files = {
                           Application.StartupPath+"\Samples\Notepad\Notepad.slvjfile"
                         };

    String[] notepad_2 ={
                         "Notepad.java"
                        };

    String defaultprojfilepath = Application.StartupPath + "\files\defaultprojloc.slvjfile";


    public String ProjectLocaionFoder()
    {
        String projectfolder = "";
        using (XmlReader reader = XmlReader.Create(defaultprojfilepath))
        {
            while (reader.Read())
            {
                if (reader.IsStartElement())
                {
                    switch (reader.Name.ToString())
                    {
                        case "DefaultProjectLocation":
                            projectfolder = reader.ReadString();
                            break;
                    }
                }
            }
        }

        return projectfolder;
    }


            String selected_item = listBox1.SelectedItem.ToString();
            String projectfolder = ProjectLocaionFoder();

listBox1 is the control added to form (see above image). selected_item contains selected sample project name and projectfolder contains users project folder.

if (selected_item == "Notepad")
{
    project_name = "Notepad";

    String directory = projectfolder + "\Notepad";
    String projectfile = "Notepad.slvjproj";

    if (Directory.Exists(directory))
    {
        MessageBox.Show("The selected project is already exists in current location", "Error............");
    }

    else
    {

        Directory.CreateDirectory(directory);

        if (Directory.Exists(directory))
        {
            project_folder = directory;

            project_file = directory + "\" + projectfile;
        }

        if (File.Exists(notepad_files[0]))
        {
            String filename = notepad_files[0];
            String fname = filename.Substring(filename.LastIndexOf("\") + 1);
            fname = fname.Remove(fname.Length - 9);
            fname = fname + ".java";

            if (Directory.Exists(directory))
            {
                String src = directory + "\src";
                String srcclasses = directory + "\srcclasses";
                String classes = directory + "\classes";

                Directory.CreateDirectory(src);
                Directory.CreateDirectory(srcclasses);
                Directory.CreateDirectory(classes);

                String content = "";

                content = File.ReadAllText(notepad_files[0]);

                if (Directory.Exists(srcclasses))
                {
                    StreamWriter strw = new StreamWriter(File.Create(srcclasses + "\" + fname));
                    strw.Write(content);
                    strw.Close();
                    strw.Dispose();
                }

                
                using (XmlWriter xmlwriter = XmlWriter.Create(directory + "\" + projectfile))
                {
                    xmlwriter.WriteStartDocument();
                    xmlwriter.WriteStartElement("SilverJProject");
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteComment("Silver-J (1.0) Java Application Project");
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectName", "Notepad");
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectLocationFolder", directory);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectLocationFile", directory + "\" + projectfile);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("ProjectType", "ApplicationType");
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("MainClassFile", directory + "\srcclasses" + "\" + notepad_2[0]);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("JavaClassFile", directory + "\srcclasses" + "\" + notepad_2[0]);
                    xmlwriter.WriteString("n");
                    xmlwriter.WriteElementString("VisualFile", directory + "\srcclasses" + "\" + notepad_2[0]);
                    xmlwriter.WriteEndElement();
                    xmlwriter.WriteEndDocument();
                    xmlwriter.Close();
                }

            }
        }

        is_project_created = true;
    }
}

Here we are just performing actions same as creating new Java application project with Create Java Class checkbox is checked.

Compile & Run

Compiling using IDE means run commands through processes. But here to compile a java source file we dont need any window to show, we just need output of compilation such as errors and warnings. It is easy to create process. We need boolean value whether processes is started or not for compilation.

Consider you are compiling your java programs using cmd, same we are doing here.

e.g: cd C:MyJavaHello

javac.exe HelloWorld.java

Download the source code.

See following code:

Where EXE is application javac.exe with full path

WorkingDirectory is our source file directory (srcclasses)(above e.g C:MyJavaHello)

FileName is our main java source file which we want to compile (HelloWorld.java)

We need only one java source file to compile, you can provide more files.

The main source file is saved in the project file(.slvjproj) with tag <MainClassFile>. This file can be changed by going to Run->Main Class

public bool Compile(String EXE, String WorkingDirectory, String FileName)
    {
        bool processStarted = false;

        if (File.Exists(EXE))
        {
            process.StartInfo.FileName = EXE;
            process.StartInfo.Arguments = FileName;
            process.StartInfo.WorkingDirectory = WorkingDirectory;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.ErrorDialog = false;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            processStarted = process.Start();
        }
        else
        {
            MessageBox.Show("Unable to compile java file. Check your Java Path settings: Current Java Path : ");
        }
        return processStarted;
    }


   public void CompileJava(String file, String jdkpath)
    {
        String mystr = file;
        if (mystr.Contains(".java"))
        {
            mystr = mystr.Remove(mystr.Length - 5);
        }
        if (this.Compile(jdkpath + "\javac.exe", Path.GetDirectoryName(file), Path.GetFileName(file)))
        {
            ErrorReader = process.StandardError;
            string response = ErrorReader.ReadToEnd();

            if (response != "")
            {
                ErrorTextBox.Text = response;
                if (showErrorDialog == true)
                {
                    MessageBox.Show("" + response, "Errors");
                }
            }
            else if (response == "")
            {
                ErrorTextBox.Text = "Program Compiled Successfully.................!";
            }
            else if (response.Contains("uses or overrides a deprecated API."))
            {
                ErrorTextBox.Text = "Program Compiled Successfully.................!";
            }
            else
            {
                ErrorTextBox.Text = "Program Compiled Successfully.................!";
            }
        }
        else if (File.Exists("" + mystr + ".class"))
        {
            ErrorTextBox.Text = "Program Compiled Successfully.................!";
        }

        
        if(myTabControl.TabCount>0)
        {
            if(myTabControl.SelectedTab.Text.Contains(".java"))
            {
                String compilejavafilename = myTabControl.SelectedTab.Text;
                if (ErrorTextBox.Text.Contains(compilejavafilename))
                {
                    int select_index = myTabControl.SelectedIndex;
                    var texteditor = (TextEditorControl)myTabControl.TabPages[select_index].Controls[0];
                    RichTextBox rtb = new RichTextBox();
                    rtb.Text = texteditor.Text;

                    for(int i=0;i<rtb.Lines.Length;i++)
                    {
                        if(ErrorTextBox.Lines[0].Contains(i.ToString()))
                        {
                            texteditor.ActiveTextAreaControl.TextArea.Caret.Line = i-1;
                        }
                    }
                }
            }
        }
    }

showErrorDialog is to hold whether to show dialog after clicking on compile menu item. If an error is found then show it, and set caret to that error line number.

You know how to run Java programs on cmd.

First you compile Java source file, it will create .class file by going to the location folder. And then you run that class file using java.exe command.

e.g: cd C:MyJavaHello

java.exe HelloWorld.class

Instead of using only java.exe, I am using full path of java.exe file(jdk_pathbinjava.exe) as a string.

    String projectlocationfolder = getCurrentProjectLocationFolder();
if (Directory.Exists(projectlocationfolder + "\srcclasses"))
{
    if (filename.Contains(".java"))
    {
        String ffname = filename.Remove(filename.Length - 5);
        ffname = ffname + ".class";

        if (File.Exists(ffname))
        {
            ProcessStartInfo ProcessInfo;
            
            String javapath = """ + jdkpath + "\java.exe" + """;
            String getfilename = filename.Substring(filename.LastIndexOf("\") + 1);
            String fname = "";
            if (getfilename.Contains(".java"))
            {
                fname = getfilename.Remove(getfilename.Length - 5);
            }
            ProcessInfo = new ProcessStartInfo("cmd.exe", "/K" + "  cd/   &&  cd " + workingDirectory + "  &&  " + javapath + "  " + fname);
            ProcessInfo.CreateNoWindow = true;
            ProcessInfo.UseShellExecute = true;
            Process.Start(ProcessInfo);
        }
    }
}

ProcessInfo = new ProcessStartInfo("cmd.exe", "/K" + " cd/ && cd " + workingDirectory + " && " + javapath + " " + fname);

This line run the program. First it starts the cmd.exe with command cd/.

Then goes to project directory(workingDirectory(srcclasses)) by using cd.

Then call java.exe filename full path with .class filename.

Same for Run with Parameter option just adding those parameters after fname.

Same for Run Applet option only just to use appletviewer.exe with HTML source file.

Build Executable Jar

To create executable jar file we need a manifest file (manifest.mf). that file contain following contents.

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.4
Created-By: 1.8.0_25-b18 (Oracle Corporation)
Class-Path:
X-COMMENT: Main-Class will be added automatically by build
Main-Class:
Main-Class:

Where Main-Class: should contain mailclass filename(only filename without any file extension).

Created-By: is the JDK version.

To create jar file using cmd,

First go to working directory.

jar.exe cmf <manifest_file> <outputfile> <class_files>

e.g:

jar.exe cmf manifest.mf Hello.jar HelloWorld.class

In Run_BuildMenuItem_Click(), I have used a textbox to paste all .class files in it and use textbox. Text as class files. It will not add .java source files.

It also adds directories to jar file by adding directory names to textbox.

The process is same as running java programs, just changing in commands, inputs & arguments.

Once jar file is created, we will create a build folder in project location folder & copy created jar file there.

        private void Run_BuildMenuItem_Click(object sender, EventArgs e)
        {
            String projectfolderpath = getCurrentProjectLocationFolder();
            if (projectfolderpath != "")
            {
                if (Directory.Exists(projectfolderpath + "\srcclasses"))
                {
                    String mainclass = getMainClassFileName();
                    String mnclass = mainclass.Substring(mainclass.LastIndexOf("\") + 1);
                    mnclass = mnclass.Remove(mnclass.Length - 5);
                    
                    String maintexttomanifest = "Manifest-Version: 1.0"
                        + "nAnt-Version: Apache Ant 1.9.4"
                        + "nCreated-By: 1.8.0_25-b18 (Oracle Corporation)"
                        + "nClass-Path: "
                        + "nX-COMMENT: Main-Class will be added automatically by build"
                        + "nMain-Class: " + mnclass
                        + "nMain-Class: " + mnclass;

                    String manifestfile = projectfolderpath + "\srcclasses\mainclass.mf";
                    StreamWriter strw = new StreamWriter(manifestfile);
                    strw.Write(maintexttomanifest);
                    strw.Close();
                    strw.Dispose();

                    if (File.Exists(manifestfile))
                    {
                        String srcclassesfolderpath = projectfolderpath + "\srcclasses";
                        List<string> packagenameslist = getPackageNamesList();
                        TextBox textbox = new TextBox();
                        string[] files = Directory.GetFiles(srcclassesfolderpath);

                        foreach (string filePath in files)
                        {
                            if (Path.GetExtension(filePath) != ".java" && Path.GetExtension(filePath) != ".mf")
                            {
                                textbox.Paste(" " + Path.GetFileName(filePath));
                            }
                        }

                        
                        RichTextBox rtb = new RichTextBox();
                        String[] dirs = Directory.GetDirectories(srcclassesfolderpath);
                        foreach (String packagefolder in packagenameslist)
                        {
                            rtb.Text = rtb.Text.Insert(rtb.SelectionStart, "" + packagefolder + "  ");
                        }

                        
                        foreach (String dirsname in dirs)
                        {
                            String dirs2 = dirsname.Substring(dirsname.LastIndexOf("\") + 1);
                            if (rtb.Text.Contains(dirs2)) { }

                            else
                            {
                                textbox.Paste(" " + dirs2 + "* ");
                            }
                        }


                        
                        if (File.Exists(manifestfile))
                        {
                            String jarfilepath = """ + getJDKPath() + "\jar.exe" + """;
                            String prjfolder = getCurrentProjectLocationFolder() + "\srcclasses";
                            String manifestfilename = manifestfile.Substring(manifestfile.LastIndexOf("\") + 1);
                            String classes = textbox.Text;
                            String mainclassfile = mainclass.Substring(mainclass.LastIndexOf("\") + 1);
                            mainclassfile = mainclassfile.Remove(mainclassfile.Length - 5);
                            String jarfilename = mainclassfile + ".jar";

                            ProcessStartInfo ProcessInfo;
                            Process Process;
                            ProcessInfo = new ProcessStartInfo("cmd.exe", "/K " + "cd/  &&  cd  " + prjfolder + " &&  " + jarfilepath + "  cmf   " + manifestfilename + "  " + jarfilename + "   " + classes);
                            ProcessInfo.CreateNoWindow = true;
                            ProcessInfo.UseShellExecute = true;
                            ProcessInfo.WindowStyle = ProcessWindowStyle.Hidden;
                            Process = Process.Start(ProcessInfo);
                        }

                        
                        String createdjarfile = mainclass.Remove(mainclass.Length - 5) + ".jar";
                        if (File.Exists(createdjarfile))
                        {
                            String buildfolder = getCurrentProjectLocationFolder() + "\build";

                            if (Directory.Exists(buildfolder))
                            {
                                String createdjarfile2 = createdjarfile.Replace("srcclasses", "build");
                                File.Delete(createdjarfile2);
                                File.Copy(createdjarfile, createdjarfile2);

                                try
                                {
                                    File.Delete(createdjarfile);
                                }
                                catch { }

                                ShowAboutToolStripLabel.Text = "Build Completed";
                                Run_BuildMenuItem_Click(sender, e);
                            }
                            else
                            {
                                Directory.CreateDirectory(buildfolder);
                                String createdjarfile2 = createdjarfile.Replace("srcclasses", "build");
                                File.Copy(createdjarfile, createdjarfile2);

                                ShowAboutToolStripLabel.Text = "Build Completed";
                                Run_BuildMenuItem_Click(sender, e);
                            }
                        }
                    }
                }
            }
        }

</string>

Appearance

IDE also has different themes. Here I am providing Default, System, Light, Dark & Night appearances.

Appearance means just changing colors of the components.

For MenuStrip and ToolStrip we need to write code for rendering their appearance by drawing. These renderer classes are defined in MyRenderer.cs file.

I have created MyMenuStripZ, MyToolStripZ classes inheriting MenuStrip and ToolStrip and adding renderers to it from file MyRenderer.cs.

Here the code that set Night theme to IDE

 if(type=="Night")
{
    MyMenuStripZ.Renderer = new NightMenuRenderer();
    textEditorContextMenuStrip.Renderer = new NightMenuRenderer();
    ProjectExplorerTreeViewContextMenuStrip.Renderer = new NightMenuRenderer();
    myTabControlContextMenuStrip.Renderer = new NightMenuRenderer();
    ErrorsListContextMenuStrip.Renderer = new NightMenuRenderer();
    MyToolStripZ.Renderer = new NightToolStripRenderer();
    myTabControl.DrawMode = TabDrawMode.OwnerDrawFixed;

    myTabControl.Transparent1 = 255;
    myTabControl.Transparent2 = 255;
    toolstrippanel.Transparent1 = 255;
    toolstrippanel.Transparent2 = 255;
    projectexplorerpanel.Transparent1 = 255;
    projectexplorerpanel.Transparent2 = 255;
    classespanel.Transparent1 = 255;
    classespanel.Transparent2 = 255;
    methodspanel.Transparent1 = 255;
    methodspanel.Transparent2 = 255;
    errorslistpanel.Transparent1 = 255;
    errorslistpanel.Transparent2 = 255;

    MyMenuStripZ.BackColor = Color.FromArgb(255, 30, 30, 30);
    toolstrippanel.StartColor = Color.FromArgb(30, 30, 30);
    toolstrippanel.EndColor = Color.FromArgb(30, 30, 30);
    MyToolStripZ.BackColor = Color.FromArgb(250, 30, 30, 30);

    projectexplorerpanel.StartColor = Color.FromArgb(15, 15, 15);
    projectexplorerpanel.EndColor = Color.FromArgb(15, 15, 15);
    classespanel.StartColor = Color.FromArgb(15, 15, 15);
    classespanel.EndColor = Color.FromArgb(15, 15, 15);
    methodspanel.StartColor = Color.FromArgb(15, 15, 15);
    methodspanel.EndColor = Color.FromArgb(15, 15, 15);
    errorslistpanel.StartColor = Color.FromArgb(15, 15, 15);
    errorslistpanel.EndColor = Color.FromArgb(15, 15, 15);

    projectexplorerlabel.ForeColor = Color.White;
    classeslabel.ForeColor = Color.White;
    methodslabel.ForeColor = Color.White;
    errorslabel.ForeColor = Color.White;

    myTabControl.ActiveTabStartColor = Color.FromArgb(10, 10, 30);
    myTabControl.ActiveTabEndColor = Color.FromArgb(10, 10, 30);
    myTabControl.NonActiveTabStartColor = Color.FromArgb(60, 60, 60);
    myTabControl.NonActiveTabEndColor = Color.FromArgb(60, 60, 60);

    myTabControl.TextColor = Color.White;

    splitContainer1.BackColor = Color.FromArgb(255,10, 10, 10);

    ProjectExplorerTreeView.BackColor = Color.FromArgb(255, 25, 25, 25);
    ClassesTreeView.BackColor = Color.FromArgb(255, 25, 25, 25);
    MethodsTreeView.BackColor = Color.FromArgb(255, 25, 25, 25);
    ErrorTextBox.BackColor = Color.FromArgb(255, 25, 25, 25);

    ProjectExplorerTreeView.ForeColor = Color.White;
    ClassesTreeView.ForeColor = Color.White;
    MethodsTreeView.ForeColor = Color.White;
    ErrorTextBox.ForeColor = Color.FromArgb(255, 255, 220, 220);
}

1 / 1 / 0

Регистрация: 10.11.2010

Сообщений: 7

1

17.04.2011, 19:54. Показов 4908. Ответов 17


Ув. программисты, скажите (или покажите на примере(ах)) пожалуйста как написать свою IDE на vb.net (Проще говоря — этакий мини-vb.net в vb.net)

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



_

2363 / 1238 / 78

Регистрация: 28.10.2009

Сообщений: 4,331

17.04.2011, 20:38

3

aolko, посмотри тему про про динамическую компиляцию, по большому счету, чтобы написать свою IDE нужно два инструмента — текстовый редактор и компилятор. Компилятор у тебя от NET, а простой редактор тож не сложное дело.
Другое дело уже обвешивать его всякими рюшечками -типа панель инструментов, кодогенерация, подсветка синтаксиса.



1



1 / 1 / 0

Регистрация: 10.11.2010

Сообщений: 7

17.04.2011, 20:51

 [ТС]

4

Цитата
Сообщение от Eugene22
Посмотреть сообщение

всякими рюшечками -типа панель инструментов

это даже не рюшечки,а обязательный компонент)



0



386 / 375 / 22

Регистрация: 08.02.2011

Сообщений: 1,078

17.04.2011, 21:57

5

Есть такая свободная среда разработки Sharpdevelop, по функционалу это почти студия 2008, а в некотором и лучше. Это открытая среда, ее можно дорабатывать под себя и т.д. Скачать ее можно тут вместе с исходником http://www.icsharpcode.net/OpenSource/SD/Download/ . Написана она на C#, но перевод не составит труда. А вообще зачем изобретать велосипед?



1



557 / 434 / 21

Регистрация: 16.12.2010

Сообщений: 953

18.04.2011, 16:30

6

Не по теме:

_Лёша_, Net Framework тоже когда то был велосипедом (была java), но теперь это популярный велосипед

Добавлено через 18 часов 24 минуты
покапался немного на msdn и вот нашел такой способ компиляции проекта:

создаем BAT — file прописываем туды:

Код

C:WINDOWSMicrosoft.NETFrameworkv3.5MSBuild.exe WinApp1.vbproj /property:Configuration=Debug
pause

и наслаждаемся красивой сборкой
и небольшой коммент

Код

C:WINDOWSMicrosoft.NETFrameworkv3.5MSBuild.exe - путь к билдеру
WinApp1.vbproj - путь к проекту 
/property:Configuration=Debug - режим откладки

p.s. батник помещаем в папку с проектом



1



386 / 375 / 22

Регистрация: 08.02.2011

Сообщений: 1,078

18.04.2011, 16:38

7

Да батник то это совсем уж примитив. Можно вызывать просто компиляцию методом shell из VB, просто название проекта в строке подставлять соответствующее.



0



557 / 434 / 21

Регистрация: 16.12.2010

Сообщений: 953

18.04.2011, 21:01

8

Батник примитив — наглядно показывающий работу, но потом можно и через shell

Добавлено через 4 часа 15 минут
http://www.codeproject.com/KB/cs/ConscriptIDE.aspx
вот что-то уже делали подобное правда на шарпе, но думаю разберетесь



0



1 / 1 / 0

Регистрация: 10.11.2010

Сообщений: 7

08.05.2011, 00:16

 [ТС]

9

Цитата
Сообщение от Ciberst
Посмотреть сообщение

но думаю разберетесь

Увы, не разобрался
Мне бы пока что надо сам код для редактора найти

Ну должно получится что-то вроде этого

Как написать свою IDE

…Или этого

Как написать свою IDE



0



Просто прогер

1291 / 1078 / 13

Регистрация: 13.03.2009

Сообщений: 2,502

08.05.2011, 00:58

10

Нужен текстовый движок, к примеру Scintilla.



0



1 / 1 / 0

Регистрация: 10.11.2010

Сообщений: 7

08.05.2011, 01:22

 [ТС]

11

Цитата
Сообщение от PB
Посмотреть сообщение

Нужен текстовый движок, к примеру Scintilla.

Редактируем ли он? Он вставляется в проект через библиотеку?



1



Просто прогер

1291 / 1078 / 13

Регистрация: 13.03.2009

Сообщений: 2,502

08.05.2011, 12:30

12

Цитата
Сообщение от aolko
Посмотреть сообщение

Он вставляется в проект через библиотеку?

Да, Scintilla.dll
Это текстовый редактор с возможностью подсветки синтаксиса, свертки строк, работы со списками автозавершения, маркировки строк ключевых слов и многого другого.



1



1 / 1 / 0

Регистрация: 10.11.2010

Сообщений: 7

08.05.2011, 15:02

 [ТС]

13

Отлично. Это есть. Теперь где форм-дизайнер достать?



0



_

2363 / 1238 / 78

Регистрация: 28.10.2009

Сообщений: 4,331

08.05.2011, 19:35

14

Цитата
Сообщение от aolko
Посмотреть сообщение

Теперь где форм-дизайнер достать?

попробуй сам написать, примитивный редактор с минимумом контролов в панели инструментов, как мне кажется, не так уж и сложно будет написать



0



1 / 1 / 0

Регистрация: 10.11.2010

Сообщений: 7

09.05.2011, 17:02

 [ТС]

15

Цитата
Сообщение от Eugene22
Посмотреть сообщение

попробуй сам написать, примитивный редактор с минимумом контролов в панели инструментов, как мне кажется, не так уж и сложно будет написать

Спроектировать-то ладно,а где я код для этого возьму?



0



_

2363 / 1238 / 78

Регистрация: 28.10.2009

Сообщений: 4,331

09.05.2011, 17:12

16

Цитата
Сообщение от aolko
Посмотреть сообщение

а где я код для этого возьму?

ну сам попробуй написать.
У формы сделай панельку — там будет несколько кнопок. Напиши код, по которому к указателю мыши цеплялась выбранная кнопка — точнее не кнопка, а инструмент, который она представляет и так перетаскиваешь инструмент на форму. Создай панельки для вывода и изменения свойств инструментов. А при сохранении записываешь все свойства контролов в файл кода. Ну это я так вобщем., примерно представил.

Если самому в ломы писать — возьми готовое решение как уже выше предлагали — Sharpdevelop. Код конверторами переделай в vb.



0



Почетный модератор

Эксперт .NET

8713 / 3665 / 404

Регистрация: 14.06.2010

Сообщений: 4,513

Записей в блоге: 9

09.05.2011, 18:22

17

aolko, загляните сюда. При небольшом допиливании можно получить то что требуется.



2



13 / 13 / 1

Регистрация: 24.06.2011

Сообщений: 135

18.08.2011, 09:56

18

Предлагаю такую статью. С примером.



1



    Microsoft User Group Community

  • Главная
  • Публикации
  • Компании
  • События
  • User Groups
  • Поиск

Звучит красиво и интригующе [:)]

Вот то что у нас должно получится:

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

AvalonEdit

AvalonEdit — основаный на WPF редактор используемый в SharpDevelop 4.x. В использовании AvalonEdit  очень похож на обычный TextBox!

Для загрузки документа ….

И на конец, подсветка синтаксиса:

AvalonEdit поддерживает ASP.NET, Boo, Coco/R grammars, C++, C#, HTML, Java, JavaScript, Patch files, PHP, TeX, VB, XML.

Если вам интерестно узнать подробнее об этом елементе управлеения то нужно почитать статью Daniel Grunwald’s на CodeProject. (Так же будет полезно почитать Document и Rendering которые были удалены из оригинальной статьи.)

AvalonDock

AvalonDock — библиотека WPF елементов управления которую можно задействовать для создания макета расположения дочерних окон как это сделано в Visual Studio. Это поддержка всплывающих окон, мэнеджер множественного стыкования дочерних окон, стили и темы и поддержка элементов управления WinForms.

DockingManager

DockingManager ответственен за расстановку своего контента (панели и т.д.) и для выполнения их правильного стыкования.

ResizingPanel

ResizingPanel это унаследованый от Panel классс который призван организовать свой контент (панели и т.д.) по направлению (как Orientation в StackPanel классе). Между двумя последовательными ResizingPanel елементами автоматически вставляется ResizingPanelSplitter. Потянув за сплиттер можно изменять размер ResizingPanel елемента.

DockablePane & DocumentPane

DockablePane может содержать только DockableContents и может быть перетянут и перестыкован к границе контейнера DockingManager. В добавок DockablePane может быть автоспрятан («отстыкован»)  или всплывающим если разположен в сплыващем окне. DocumentPane может содержать как DocumentContents так и DockableContents, но он не может быть перемещен.

Детальнее в отличном AvalonDock Tutorial.

ОК, правда это еще далеко не IDE, но описаные контролы были использованы при написании OpenSource продукта SharpDevelop.

Enjoy [:)]

З.Ы.

оригинал статьи Create your own IDE in 10 minutes.

Первоначальные соображения : что нам вообще надо по минимуму

1. на отладчик на самом деле можно наплевать первоначально (баловство это)
2. трассировка(логгирование) нам нужна (обязательно — SWO JLink )
3. знание языка С (хотя бы начальное)

Остается всего ничего : скомпилировать кучку *.с файлов и зашить в мк.

Трассировку смотреть в J-Link SWO viewer (а он бесплатный).

Откуда мы берем кучки файлов *.c (*.h,*.s) ?

Ну самый популярный вариант я думаю STM32CubeMX под STM32 контроллер.

Там есть сборки под разные среды MDK (Keil), CubeIDE,AtollicStudio,SW4STM32, EWARM (IAR Embedded Workbench) и даже makefile.

Keil, IAR платные .
В Keil при использовании Ethernet и lwip (бесплатная) упираемся сразу при линковке в : The code size of this image (37052 bytes) exceeds the maximum allowed for this version of the linker (смысл покупай лицензию 2000-4000E).
CubeIDE, AtollicStudio, SW4STM32 — это Эклипс

А что же такое makefile?

А это историческая основа программирования, когда работали только в текстовом редакторе, компили из командной строки.
Makefile — это настройщик сборки файлов  языка С и не только..

Кстати программисты драйверов Windows и саму ОС Windows до сих пор создают именно этим способом. Забавно не правда ли?

Для запуска makefile надо выполнить программу make.exe. А где же она хранится ?

Для Windows прогу make надо скачать отдельно, мне попалась тут

http://www.equation.com/servlet/equation.cmd?fa=make

А где компилятор наш находится ?

Возвращаемся к makefile:
В нем и указывается компилятор

CC = $(GCC_PATH)/$(PREFIX)gcc

. То есть с префиксом это получится файл arm-none-eabi-gcc (и этот компилятор наверняка бесплатный). А где его взять?

Поиски приводят к GNU ARM Embedded Toolchain (это бесплатно). А что это такое?

Это ответ на вопрос — где лежит халява! Точнее ребята с https://developer.arm.com делают этот toolchain бесплатно для вас и для меня.

Устанавливаем на Windows 10.

фотка 1

launch gccvar.bat — запустится окно с командной строкой с предустановленными путями к компилятору и т.д. Это важно!
Так в дальнейшем и надо сначала запускать этот батник.

А что это такое toolchain?

А это набор компилятор,сборщик и еще что-то для создания программ под разные железки и разные ОС. По сути это основа программирования (База инструментов).

И наконец чтобы все собралось кинем make к нашему проекту и там из командной строки запустим.

Как ни удивительно все прошло довольно быстро и в результате получили файл с прошивкой!

Примечание : Keil например использует свой toolchain , набор инструметов можно посмотреть здесь :

*** Using Compiler 'V5.06 update 6 (build 750)', folder: 'C:Keil_v5ARMARMCCBin'

Выводы :

Ура мир не без добрых людей! Можно программировать совершенно бесплатно и пользоваться разными бесплатными библиотеками типа lwip, freertos,..

Главное понимать поглубже , что надо для компиляции, сборки и т.д.

Кстати приятная новость — опять порадовали шведы: Atollic True Studio взлетела и отладка для STM32 пошла через JLink за пять секунд. Ну что ж теперь поработаем?

А то готовьте несколько тысяч баксов — да где у обычного чела в России такие лишние деньги?

Я для прикола жене предложил мне подарить на 50 лет IDE Keil, посмотрел в ее глаза — и все понял…

Понравилась статья? Поделить с друзьями:
  • Как написать свою cms
  • Как написать свою cad программу
  • Как написать свойства параболы
  • Как написать свой язык программирования на ассемблере
  • Как написать свой язык программирования на python