
毛利です。
C++Builder VCLでJSONファイルを読み込んでTTreeViewコンポーネントに表示するプログラムを試してみました。
プログラムソースは github.com/mojeldからダウンロード可能です。
[デザイン画面]
2つのTSpeedButton, TTreeView, TMemo, TActivityIndicator, TOpenDialog, TImageListを配置します。
ImageList1にはTreeView1に表示する為のアイコンを用意し、TreeView1->Images = ImageList1;
[ボタンイベント]
JSONファイルを読み込むイベントとクリップボードに入っている文字列を読むイベントを作ります。
//--------------------------------------------------------------------------- void __fastcall TForm1::SpeedButton1Click(TObject *Sender) { //ファイルオープンダイアログを表示しJSONを読込む 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) { //クリップボードのJSON文字列を読込む start_js_build(Clipboard()->AsText); }
[JSONを読込みTreeView1->Itemsに追加]
TJsonTextReaderを使いJSON文字列からTreeView1->Itemsに追加するコードです。
//--------------------------------------------------------------------------- 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(); }
Read More