--- /dev/null
+package jp.ymir.taskReporter.ui
+import com.toedter.calendar._
+import java.beans.PropertyChangeEvent
+import java.beans.PropertyChangeListener
+import java.util.Calendar
+import java.util.Date
+import scala.swing._
+import scala.swing.event._
+
+class DateChooser extends Component {
+ override lazy val peer = new JDateChooser()
+
+ case class DateChanged(from: Option[Date], to: Option[Date]) extends Event
+
+ peer.addPropertyChangeListener("date", new PropertyChangeListener {
+ def propertyChange(e: PropertyChangeEvent) {
+ if (e.getPropertyName == "date") {
+ publish(
+ DateChanged(
+ from = Option(e.getOldValue.asInstanceOf[Date]),
+ to = Option(e.getNewValue.asInstanceOf[Date])))
+ }
+ }
+ })
+
+ def calendar: Option[Calendar] = peer.getCalendar match {
+ case null => None
+ case cal => Some(cal)
+ }
+ def calendar_=(cal: Option[Calendar])
+ = peer.setCalendar(cal.getOrElse(null))
+
+ def calendarChooser: CalendarChooser = new CalendarChooser(peer.getJCalendar)
+
+ def dateFormatString: String = peer.getDateFormatString
+ def dateFormatString_=(fmt: String) = peer.setDateFormatString(fmt)
+}
package jp.ymir.taskReporter.ui
-import com.toedter.calendar._
import java.awt.Insets
+import java.util.Calendar
import jp.ymir.taskReporter.core._
+import scala.collection.immutable._
import scala.swing._
+import scala.swing.event._
class TaskEditor extends GridBagPanel {
- import GridBagPanel.Anchor._
- import GridBagPanel.Fill._
+ import GridBagPanel._
+
+ case class TaskUpdated(t: Task) extends Event
+
+ def task: (Calendar => Task) = d => Task(
+ date = d,
+ ticketID = noneIfEmpty(ticketID.text).map(_.toInt),
+ title = title.text,
+ expectedCompletionDate = expectedCompletionDate.calendar.getOrElse(Task.endOfCurrentHalf),
+ deadline = deadline.calendar,
+ status = status.selection.item,
+ description = noneIfEmpty(description.text)
+ )
+
+ def task_=(t: Task) = {
+ ticketID.text = t.ticketID.fold("")(_.toString)
+ title.text = t.title
+ expectedCompletionDate.calendar = Some(t.expectedCompletionDate)
+ deadline.calendar = t.deadline
+ status.selection.item = t.status
+ description.text = t.description.getOrElse("")
+ }
private val commonInsets = new Insets(2, 3, 2, 3)
- val date = Component.wrap(new JDateChooser() {
- setDateFormatString("yyyy-MM-dd")
- getJCalendar().setTodayButtonVisible(true)
- getJCalendar().setWeekOfYearVisible(false)
- })
- add(
- new Label("報告日"),
- new Constraints { gridx = 0; gridy = 0 })
- add(
- date,
- new Constraints() {
- gridx = 1; gridy = 0; anchor = West
- ipadx = 3; ipady = 3; insets = commonInsets
- })
- date.minimumSize = date.preferredSize
+ private def noneIfEmpty[T <% StringLike[_]](str: T): Option[T] = str match {
+ case "" => None
+ case _ => Some(str)
+ }
- val ticketID = new TextField(6) {
- val isDigit = (c : Char) => c >= '0' && c <= '9'
- inputVerifier = _ => wrapString(text).forall(isDigit)
+ private val ticketID = new TextField(6) {
+ def isDigit(c : Char) = c >= '0' && c <= '9'
+ inputVerifier = _ => wrapString(text).forall(isDigit)
+ horizontalAlignment = Alignment.Right
peer.setMargin(commonInsets)
}
add(
new Label("チケットID"),
- new Constraints { gridx = 0; gridy = 1 })
+ new Constraints { gridx = 0; gridy = 0 })
add(
ticketID,
new Constraints() {
- gridx = 1; gridy = 1; anchor = West; insets = commonInsets
+ gridx = 1; gridy = 0; anchor = Anchor.West; insets = commonInsets
})
ticketID.minimumSize = ticketID.preferredSize
- val title = new TextField() {
+ private val title = new TextField() {
peer.setMargin(commonInsets)
}
add(
new Label("作業名"),
- new Constraints { gridx = 0; gridy = 2 })
+ new Constraints { gridx = 0; gridy = 1 })
add(
title,
new Constraints() {
- gridx = 1; gridy = 2; fill = Horizontal; weightx = 1.0
+ gridx = 1; gridy = 1; fill = Fill.Horizontal; weightx = 1.0
insets = commonInsets
})
- val expectedCompletionDate = Component.wrap(new JDateChooser() {
- setDateFormatString("yyyy-MM-dd")
- getJCalendar().setTodayButtonVisible(true)
- getJCalendar().setWeekOfYearVisible(false)
- })
+ private val expectedCompletionDate = new DateChooser {
+ dateFormatString = "yyyy-MM-dd"
+ calendarChooser.todayButtonVisible = true
+ calendarChooser.weekOfYearVisible = false
+ }
add(
new Label("作業完了予定年月日"),
- new Constraints { gridx = 0; gridy = 3 })
+ new Constraints { gridx = 0; gridy = 2 })
add(
expectedCompletionDate,
new Constraints() {
- gridx = 1; gridy = 3; anchor = West
- ipadx = 3; ipady = 3; insets = commonInsets
+ gridx = 1; gridy = 2; anchor = Anchor.West
+ ipadx = 3; ipady = 2; insets = commonInsets
})
expectedCompletionDate.minimumSize = expectedCompletionDate.preferredSize
- val deadline = Component.wrap(new JDateChooser() {
- setDateFormatString("yyyy-MM-dd")
- getJCalendar().setTodayButtonVisible(true)
- getJCalendar().setNullDateButtonVisible(true)
- getJCalendar().setWeekOfYearVisible(false)
- })
+ private val deadline = new DateChooser {
+ dateFormatString = "yyyy-MM-dd"
+ calendarChooser.nullDateButtonVisible = true
+ calendarChooser.todayButtonVisible = true
+ calendarChooser.weekOfYearVisible = false
+ }
add(
new Label("タスク期限"),
- new Constraints { gridx = 0; gridy = 4 })
+ new Constraints { gridx = 0; gridy = 3 })
add(
deadline,
new Constraints() {
- gridx = 1; gridy = 4; anchor = West
+ gridx = 1; gridy = 3; anchor = Anchor.West
ipadx = 3; ipady = 3; insets = commonInsets
})
deadline.minimumSize = deadline.preferredSize
- val status = new ComboBox[Task.Status](Task.Status.all)
+ private val status = new ComboBox[Task.Status](Task.Status.all)
add(
new Label("状態"),
- new Constraints { gridx = 0; gridy = 5 })
+ new Constraints { gridx = 0; gridy = 4 })
add(
status,
new Constraints {
- gridx = 1; gridy = 5; anchor = West
+ gridx = 1; gridy = 4; anchor = Anchor.West
ipadx = 3; ipady = 3; insets = commonInsets
})
- val description = new ScrollPane(new TextArea() {
+ private val description = new TextArea() {
rows = 5
peer.setMargin(commonInsets)
- })
+ }
+ private val scrollingDescription = new ScrollPane(description)
add(
new Label("説明"),
- new Constraints { gridx = 0; gridy = 6 })
+ new Constraints { gridx = 0; gridy = 5 })
add(
- description,
+ scrollingDescription,
new Constraints() {
- gridx = 1; gridy = 6; fill = Horizontal; weightx = 1.0
+ gridx = 1; gridy = 5; fill = Fill.Horizontal; weightx = 1.0
insets = commonInsets
})
- description.minimumSize = description.preferredSize
+ scrollingDescription.minimumSize = scrollingDescription.preferredSize
}