リクエストパラメータの入力をテーブルに変更する
ついでにメニューもつけておく
このアプリケーションについてはとりあえずここまで。
ここから先を作りこむならgriffonに移植するほうがいいかな
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 header = ''
String json = ''
Boolean enabled = true
}
def model = new Model()
def tabPane
def paramTable
def dataModel
def jsonTree
class TreeUtil {
def clearTree = { jsonTree ->
jsonTree.model.root.removeAllChildren()
jsonTree.model.reload(jsonTree.model.root)
}
def createTree = { jsonTree, json ->
clearTree(jsonTree)
createNode(jsonTree.model.root, json)
}
def reloadTree = { jsonTree ->
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 swing = new SwingBuilder()
def sendRequest = {
model.header = ''
model.json = ''
model.enabled = false
treeUtil.clearTree(jsonTree)
swing.doOutside {
def method = model.method
def url = model.url
def params = new StringBuilder()
dataModel.rows.each { row ->
if (row.name.size() == 0) return
if (params.size() > 0) params << '&'
params << "${row.name}=${URLEncoder.encode(row.value, 'utf-8')}"
}
println params
if (method == 'GET') {
url = "${url}?${params}"
}
println url
def conn = url.toURL().openConnection()
conn.requestMethod = method
if (method == 'POST') {
conn.doOutput = true
conn.outputStream << params
}
def header = new StringBuilder()
conn.headerFields.each { key, fields ->
fields.each { field ->
header << "${key ? key + ':' : ''}${field}\n"
}
}
model.header = header.toString()
model.json = prettyPrint(conn.inputStream.getText('utf-8'))
def json = new JsonSlurper().parseText(model.json)
treeUtil.createTree(jsonTree, json)
conn.disconnect()
doLater {
treeUtil.reloadTree(jsonTree)
tabPane.selectedIndex = 2
model.enabled = true
}
}
}
swing.edt {
frame(title:'jsonを取得、表示するアプリケーション', defaultCloseOperation:JFrame.EXIT_ON_CLOSE,
size: [800, 600], show:true) {
lookAndFeel('nimbus')
borderLayout()
menuBar() {
menu(text:'ファイル', mnemonic:'F') {
menuItem(text:'終了', mnemonic:'X', actionPerformed:{dispose()})
}
}
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, enabled:bind {model.enabled})
}
tabPane = tabbedPane(constraints: BorderLayout.CENTER) {
panel(name:'パラメータ') {
borderLayout()
hbox(constraints: BorderLayout.NORTH) {
button(text:'追加', actionPerformed:{
dataModel.rows.add([name:'', value:''])
dataModel.fireTableDataChanged()
})
button(text:'削除', actionPerformed:{
if (paramTable.selectedRow == -1) return
dataModel.rows.remove(paramTable.selectedRow)
dataModel.fireTableDataChanged()
})
}
scrollPane() {
paramTable = table(constraints: BorderLayout.CENTER, autoResizeMode:JTable.AUTO_RESIZE_OFF) {
dataModel = tableModel {
propertyColumn(header:'名前', propertyName:'name')
propertyColumn(header:'値', propertyName:'value')
}
}
paramTable.putClientProperty('terminateEditOnFocusLost', true)
}
}
scrollPane(name:'ヘッダ') {
textArea(editable:false, text:bind {model.header})
}
scrollPane(name:'レスポンス(テキスト)') {
textArea(editable:false, text:bind {model.json})
}
scrollPane(name:'レスポンス(ツリー)') {
jsonTree = tree(rootVisible: false)
treeUtil.clearTree(jsonTree)
}
}
progressBar(constraints: BorderLayout.SOUTH, indeterminate:bind{!model.enabled})
}
}