JSONファイルをTreeViewで可視化

  • 2
    いいね
  • 0
    コメント

C++Builder VCLでJSONファイルを読み込んでTTreeViewコンポーネントに表示するプログラムを試してみました。
プログラムソースは github.com/mojeldからダウンロード可能です。

画面デザイン

2つのTSpeedButton, TTreeView, TMemo, TActivityIndicator, TOpenDialog, TImageListを配置します。
png1
ImageList1にはTreeView1に表示する為のアイコンを用意し、TreeView1->Images = ImageList1;
png2

ボタンイベント追加

JSONファイルを読み込むイベントとクリップボードに入っている文字列を読むイベントを作ります。

Unit1.cpp
void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
    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)
{
    start_js_build(Clipboard()->AsText);
}

JSONを読込みTreeView1->Itemsに追加

TJsonTextReaderを使いJSON文字列からTreeView1->Itemsに追加するコードです。

Unit1.cpp
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();
}

実行

TJsonTextReaderを使えば簡単に実現できます。
2017-05-271844.png

参考URL

https://github.com/mojeld/jsree
https://community.embarcadero.com/blogs/entry/json-ttreeview-japan
jsree