Small enhancements to libpit to facilitate pit-swing.
Added delete() and createNewProject(String) to Project class. Added nicer toString() method to Category enum.
This commit is contained in:
@ -1,11 +1,15 @@
|
||||
package com.jdbernard.pit.swing
|
||||
|
||||
import com.jdbernard.pit.Category
|
||||
import com.jdbernard.pit.Filter
|
||||
import com.jdbernard.pit.Issue
|
||||
import com.jdbernard.pit.Project
|
||||
import com.jdbernard.pit.FileProject
|
||||
import groovy.beans.Bindable
|
||||
import java.awt.event.MouseEvent
|
||||
import javax.swing.DefaultListModel
|
||||
import javax.swing.JFileChooser
|
||||
import javax.swing.JOptionPane
|
||||
import javax.swing.JSplitPane
|
||||
import javax.swing.ListSelectionModel
|
||||
import javax.swing.tree.DefaultMutableTreeNode
|
||||
@ -14,34 +18,78 @@ import javax.swing.tree.DefaultTreeModel
|
||||
import javax.swing.tree.TreeSelectionModel
|
||||
import net.miginfocom.swing.MigLayout
|
||||
|
||||
// VIEW-Specific data
|
||||
/* ********************
|
||||
* VIEW-Specific data
|
||||
* ********************/
|
||||
|
||||
// cache the ListModels
|
||||
projectListModels = [:]
|
||||
|
||||
categoryIcons = [(Category.BUG): imageIcon('/bug.png'),
|
||||
(Category.CLOSED): imageIcon('/closed.png'),
|
||||
(Category.FEATURE): imageIcon('/feature.png'),
|
||||
(Category.TASK): imageIcon('/task.png')]
|
||||
// map of category -> list icon
|
||||
categoryIcons = [:]
|
||||
|
||||
openDialog = fileChooser(fileSelectionMode: JFileChooser.DIRECTORIES_ONLY)
|
||||
// filter for projects and issues
|
||||
filter = new Filter(categories: [])
|
||||
|
||||
// event methods
|
||||
displayProject = { evt = null ->
|
||||
def project= evt?.newLeadSelectionPath?.lastPathComponent?.userObject
|
||||
@Bindable def popupProject = null
|
||||
|
||||
// initialize category-related view data
|
||||
Category.values().each {
|
||||
categoryIcons[(it)] = imageIcon("/${it.name().toLowerCase()}.png")
|
||||
filter.categories.add(it)
|
||||
}
|
||||
|
||||
/* ***************
|
||||
* event methods
|
||||
* ***************/
|
||||
|
||||
/**
|
||||
* displayProject
|
||||
* @param project Project to display.
|
||||
*
|
||||
*/
|
||||
displayProject = { project = null ->
|
||||
issueTextArea.text = ""
|
||||
if (!project) return
|
||||
|
||||
if (!projectListModels[(project.name)]) {
|
||||
def model = new DefaultListModel()
|
||||
project.eachIssue { model.addElement(it) }
|
||||
project.eachIssue(filter) { model.addElement(it) }
|
||||
projectListModels[(project.name)] = model
|
||||
}
|
||||
|
||||
issueList.setModel(projectListModels[(project.name)])
|
||||
}
|
||||
|
||||
displayIssue = { evt = null ->
|
||||
if (issueList.selectedValue)
|
||||
issueTextArea.text = issueList.selectedValue.text
|
||||
displayIssue = { issue = null ->
|
||||
if (issue) issueTextArea.text = issue.text
|
||||
}
|
||||
|
||||
showProjectPopup = { project, x, y ->
|
||||
popupProject = project
|
||||
projectPopupMenu[1].enabled = project != null
|
||||
projectPopupMenu.show(projectTree, x, y)
|
||||
}
|
||||
|
||||
/* ****************
|
||||
* GUI components
|
||||
* ****************/
|
||||
openDialog = fileChooser(fileSelectionMode: JFileChooser.DIRECTORIES_ONLY)
|
||||
|
||||
projectPopupMenu = popupMenu() {
|
||||
menuItem('New Project...',
|
||||
actionPerformed: {
|
||||
def name = JOptionPane.showInputDialog(frame, 'Project name:',
|
||||
'New Project...', JOptionPane.QUESTION_MESSAGE)
|
||||
|
||||
if (!popupProject) popupProject = model.rootProject
|
||||
def newProject = popupProject.createNewProject(name)
|
||||
|
||||
projectTree.model = new DefaultTreeModel(
|
||||
makeNodes(model.rootProject))
|
||||
})
|
||||
menuItem('Delete Project',
|
||||
actionPerformed: { popupProject.delete() })
|
||||
}
|
||||
|
||||
frame = application(title:'Personal Issue Tracker',
|
||||
@ -69,6 +117,29 @@ frame = application(title:'Personal Issue Tracker',
|
||||
projectDir = openDialog.selectedFile
|
||||
model.rootProject = new FileProject(projectDir)
|
||||
})
|
||||
|
||||
menuItem('Exit', actionPerformed: { app.shutdown() })
|
||||
}
|
||||
|
||||
menu('View') {
|
||||
Category.values().each {
|
||||
checkBoxMenuItem(it.toString(),
|
||||
selected: filter.categories.contains(it),
|
||||
actionPerformed: { evt ->
|
||||
def cat = Category.toCategory(evt.source.text)
|
||||
if (filter.categories.contains(cat)) {
|
||||
filter.categories.remove(cat)
|
||||
evt.source.selected = false
|
||||
} else {
|
||||
filter.categories.add(cat)
|
||||
evt.source.selected = true
|
||||
}
|
||||
projectListModels.clear()
|
||||
displayProject(projectTree.leadSelectionPath
|
||||
?.lastPathComponent?.userObject)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +160,19 @@ frame = application(title:'Personal Issue Tracker',
|
||||
new DefaultTreeModel(makeNodes(model.rootProject))
|
||||
} else new DefaultTreeModel()
|
||||
}),
|
||||
valueChanged: displayProject)
|
||||
valueChanged: { evt ->
|
||||
displayProject(evt?.newLeadSelectionPath
|
||||
?.lastPathComponent?.userObject)
|
||||
},
|
||||
mouseClicked: { evt ->
|
||||
if (evt.button == MouseEvent.BUTTON3) {
|
||||
showProjectPopup(
|
||||
projectTree.getPathForLocation(evt.x, evt.y)
|
||||
?.lastPathComponent?.userObject,
|
||||
evt.x, evt.y)
|
||||
}
|
||||
})
|
||||
|
||||
projectTree.selectionModel.selectionMode =
|
||||
TreeSelectionModel.SINGLE_TREE_SELECTION
|
||||
}
|
||||
@ -103,7 +186,7 @@ frame = application(title:'Personal Issue Tracker',
|
||||
cellRenderer: new IssueListCellRenderer(
|
||||
issueIcons: categoryIcons),
|
||||
selectionMode: ListSelectionModel.SINGLE_SELECTION,
|
||||
valueChanged: displayIssue)
|
||||
valueChanged: { displayIssue(issueList.selectedValue) })
|
||||
}
|
||||
scrollPane(constraints: "bottom") {
|
||||
issueTextArea = textArea()
|
||||
@ -112,8 +195,11 @@ frame = application(title:'Personal Issue Tracker',
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************
|
||||
* Auxilary methods
|
||||
* ******************/
|
||||
def makeNodes(Project project) {
|
||||
def rootNode = new DefaultMutableTreeNode(project)
|
||||
project.eachProject { rootNode.add(makeNodes(it)) }
|
||||
project.eachProject(filter) { rootNode.add(makeNodes(it)) }
|
||||
return rootNode
|
||||
}
|
||||
|
Reference in New Issue
Block a user