Visualize JSON using TTreeView

Posted by on in Blogs

I tried a program that reads a JSON file in C++Builder VCL and displays it in TTreeView component.

This project file is open to public from github.

github.com/mojeld 

https://www.microsoft.com/store/productid/9PLPHK05PJF7

 


 

Place two TSpeedButton, TTreeView, TMemo, TActivityIndicator, TOpenDialog, TImageList.

ImageList1 has an icon for displaying in TreeView1

 

 

 

[code]


Create an event to read a JSON file and an event to read a character string contained in the clipboard.

//---------------------------------------------------------------------------
void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
	//Read JSON file.
	if (OpenDialog1->Execute(this->Handle) )
	{
		if (FileExists(OpenDialog1->FileName) )
		{
			UnicodeString s_ = file_towstring(OpenDialog1->FileName);
			if (s_.Length() > 0)
			{
				start_js_build(s_);
			}
		}
	}
}

void __fastcall TForm1::SpeedButton2Click(TObject *Sender)
{
	//Read the character string contained in the clipboard.
	start_js_build(Clipboard()->AsText);
}

 

 

 

[Read JSON and add it to TreeView 1->Items]


Code to add from JSON string to ”TreeView 1->Items” using TJsonTextReader.

//---------------------------------------------------------------------------
void __fastcall TForm1::addChild_(TJsonTextReader* jsr, std::stack<TTreeNode* >& st_, UnicodeString value_, const int imagenum)
{
	UnicodeString path_ = StringReplace(jsr->Path, st_.top()->Text, "", TReplaceFlags() << System::Sysutils::rfReplaceAll);
	if (Pos(".", path_) == 1) path_.Delete(1, 1);
	TThread::Synchronize(TThread::CurrentThread, [this, &st_, jsr, &path_, &value_, &imagenum](){
		TTreeNode* node_ = TreeView1->Items->AddChild(st_.top(),path_ + ":" + value_);
		Memo1->Lines->Append(path_ + " = " + value_);
		node_->ImageIndex 		= imagenum;
		node_->SelectedIndex 	= imagenum;
	});
}

void __fastcall TForm1::json_totree_(TJsonTextReader* jsr)
{
	TThread::CreateAnonymousThread([this, jsr](){
		std::stack<TTreeNode* > st_;
		try
		{
			while (jsr->Read() )
			{
				switch (jsr->TokenType)
				{
				case TJsonToken::StartObject:
					TThread::Synchronize(TThread::CurrentThread, [this, &st_, jsr](){
						(st_.empty())? st_.push(TreeView1->Items->Add(nullptr, "JSON")):
							st_.push(TreeView1->Items->AddChild(st_.top(), jsr->Path));
						if (st_.top() != nullptr) {
							st_.top()->ImageIndex 		= 0;
							st_.top()->SelectedIndex 	= 0;
							if (jsr->Path.Length() > 0) {
								Memo1->Lines->Append("[" + jsr->Path + "]");
							}
						}
					});
					break;
				case TJsonToken::StartArray:
				case TJsonToken::PropertyName:
					break;
				case TJsonToken::String:
					addChild_(jsr, st_, jsr->Value.AsString() + " (string)",1 );
					break;
				case TJsonToken::Integer:
					addChild_(jsr, st_, IntToStr(jsr->Value.AsInteger()) + " (integer)" , 2);
					break;
				case TJsonToken::Float:
					addChild_(jsr, st_, CurrToStr(jsr->Value.AsCurrency()) + " (float)" ,2);
					break;
				case TJsonToken::Boolean:
					addChild_(jsr, st_, BoolToStr(jsr->Value.AsBoolean()) + " (bool)" ,2);
					break;
				case TJsonToken::Null:
					addChild_(jsr, st_, "null" ,3);
					break;
				case TJsonToken::EndArray:
					break;
				case TJsonToken::EndObject:
					st_.pop();
					break;
				}
			}
		}
		__finally
		{
			TThread::Synchronize(TThread::CurrentThread, [this](){
				SpeedButton1->Enabled = true;
				SpeedButton2->Enabled = true;
				Panel4->Visible 	  = false;
			});
		}
	})->Start();
}

 

 

 



About
Gold User, No rank,
Delphi / C++Builder blogger

Comments

Check out more tips and tricks in this development video: