jsonを取得、表示するアプリケーション　その９

レスポンスで返ってきたjsonデータをツリーで表示する
ツリー関連の処理はクラスにまとめておいた

ステップ数もだいぶ増えてきたのでそろそろリファクタリングしたほうがいいかな

```groovy:json_client.groovy
import groovy.swing.SwingBuilder
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import groovy.beans.Bindable
import javax.swing.*
import javax.swing.tree.DefaultMutableTreeNode as TreeNode
import java.awt.*
import java.net.*

def manager = new CookieManager()
manager.cookiePolicy = CookiePolicy.ACCEPT_ALL
CookieHandler.default = manager

@Bindable
class Model {
	String method = 'GET'
	String url = ''
	String params = ''
	String json = ''
}
def model = new Model()

def tabPane
def jsonTree

class TreeUtil {
	def clearTree = { jsonTree ->
		jsonTree.model.root.removeAllChildren()
		jsonTree.model.reload(jsonTree.model.root)
	}
	
	def reloadTree = { jsonTree, json ->
		clearTree(jsonTree)
		createNode(jsonTree.model.root, json)
		jsonTree.model.reload(jsonTree.model.root)
	}
	
	def createNode = { node, json ->
		if (json instanceof HashMap) {
			json.each { key, value ->
				def childNode = new TreeNode(key)
				node.add(childNode)
				createNode(childNode, value)
			}
 		} else if (json instanceof ArrayList) {
			json.eachWithIndex { child, index ->
				def childNode = new TreeNode(index + 1)
				node.add(childNode)
				createNode(childNode, child)
			}
		} else {
			node.add(new TreeNode(json))
		}
	}
}
def treeUtil = new TreeUtil()

def prettyPrint = { text ->
	def result = JsonOutput.prettyPrint(text)
	(result =~ /\\u[0-9a-zA-Z]{4}/).each { match ->
		def code = match[2..5]
		def encTxt = new String([Integer.parseInt(code, 16)] as int[], 0, 1)
		result = result.replaceAll(/\\u${code}/, encTxt)
	}
	result
}

def sendRequest = {
	model.json = ''
	
	def method = model.method
	def url = model.url
	def params = URLEncoder.encode(model.params, 'utf-8').replaceAll('%3D', '=').replaceAll('%26', '&')
	if (method == 'GET') {
		url = "${url}?${params}"
	}
	
	def conn = url.toURL().openConnection()
	conn.requestMethod = method
	if (method == 'POST') {
		conn.doOutput = true
		conn.outputStream << params
	}
	
	model.json = prettyPrint(conn.inputStream.getText('utf-8'))
	
	def json = new JsonSlurper().parseText(model.json)
	treeUtil.reloadTree(jsonTree, json)
	
	tabPane.selectedIndex = 1
}

new SwingBuilder().frame(title:'jsonを取得、表示するアプリケーション', defaultCloseOperation:JFrame.EXIT_ON_CLOSE,
						size: [800, 600], show:true) {
	lookAndFeel('nimbus')
	borderLayout()
	hbox(constraints: BorderLayout.NORTH) {
		comboBox(items:['GET', 'POST'], selectedItem:bind(source: model, sourceProperty: 'method', mutual: true))
		textField(text:bind(source: model, sourceProperty: 'url', mutual: true))
		button(text:'送信', actionPerformed:sendRequest)
	}
	tabPane = tabbedPane(constraints: BorderLayout.CENTER) {
		scrollPane(name:'パラメータ') {
			textArea(text:bind(source: model, sourceProperty: 'params', mutual: true))
		}
		scrollPane(name:'レスポンス（テキスト）') {
			textArea(editable:false, text:bind {model.json})
		}
		scrollPane(name:'レスポンス（ツリー）') {
			jsonTree = tree(rootVisible: false)
			treeUtil.clearTree(jsonTree)
		}
	}
}
```

![qiita-009a.png](https://qiita-image-store.s3.amazonaws.com/0/17179/b27ae4d9-9fb9-5951-a0b0-24b6d141e1b4.png)
![qiita-009b.png](https://qiita-image-store.s3.amazonaws.com/0/17179/6a706909-5da0-bc4a-44f3-f77ced4f0a29.png)