@@ -82,7 +82,8 @@ class RunnerPanel implements FocusListener, ActionListener {
8282 JTextArea testDescriptionTextArea
8383 JTextField testStartTextField
8484 JTextField testEndTextField
85- JTextArea testFailureDescriptionTextArea
85+ FailuresTableModel failuresTableModel
86+ JTable failuresTable
8687 JTextArea testFailureMessageTextArea
8788 JTextArea testFailureCallerTextArea
8889 JTextArea testErrorStackTextArea
@@ -106,7 +107,8 @@ class RunnerPanel implements FocusListener, ActionListener {
106107 testDescriptionTextArea. text = null
107108 testStartTextField. text = null
108109 testEndTextField. text = null
109- testFailureDescriptionTextArea. text = null
110+ failuresTableModel. model = null
111+ failuresTableModel. fireTableDataChanged
110112 testFailureMessageTextArea. text = null
111113 testFailureCallerTextArea. text = null
112114 testErrorStackTextArea. text = null
@@ -185,8 +187,6 @@ class RunnerPanel implements FocusListener, ActionListener {
185187 testIdTextArea. caret. visible = true
186188 } else if (e. source == testDescriptionTextArea) {
187189 testDescriptionTextArea. caret. visible = true
188- } else if (e. source == testFailureDescriptionTextArea) {
189- testFailureDescriptionTextArea. caret. visible = true
190190 } else if (e. source == testFailureMessageTextArea) {
191191 testFailureMessageTextArea. caret. visible = true
192192 } else if (e. source == testFailureCallerTextArea) {
@@ -203,8 +203,6 @@ class RunnerPanel implements FocusListener, ActionListener {
203203 testIdTextArea. caret. visible = false
204204 } else if (e. source == testDescriptionTextArea) {
205205 testDescriptionTextArea. caret. visible = false
206- } else if (e. source == testFailureDescriptionTextArea) {
207- testFailureDescriptionTextArea. caret. visible = false
208206 } else if (e. source == testFailureMessageTextArea) {
209207 testFailureMessageTextArea. caret. visible = false
210208 } else if (e. source == testFailureCallerTextArea) {
@@ -275,15 +273,12 @@ class RunnerPanel implements FocusListener, ActionListener {
275273 p. testDescriptionTextArea. text = test. description
276274 p. testStartTextField. text = formatDateTime(test. startTime)
277275 p. testEndTextField. text = formatDateTime(test. endTime)
278- if (test. failedExpectations !== null && test. failedExpectations. size > 0 ) {
279- val expectation = test. failedExpectations. get(0 )
280- p. testFailureDescriptionTextArea. text = expectation. description
281- p. testFailureMessageTextArea. text = expectation. message
282- p. testFailureCallerTextArea. text = expectation. caller
283- } else {
284- p. testFailureDescriptionTextArea. text = null
285- p. testFailureMessageTextArea. text = null
286- p. testFailureCallerTextArea. text = null
276+ p. failuresTableModel. model = test. failedExpectations
277+ p. testFailureMessageTextArea. text = null
278+ p. testFailureCallerTextArea. text = null
279+ if (test. failedExpectations. size > 0 ) {
280+ p. failuresTableModel. fireTableDataChanged
281+ p. failuresTable. setRowSelectionInterval(0 , 0 )
287282 }
288283 p. testErrorStackTextArea. text = test. errorStack
289284 p. testWarningsTextArea. text = test. warnings
@@ -305,6 +300,24 @@ class RunnerPanel implements FocusListener, ActionListener {
305300 }
306301 }
307302
303+ static class FailuresRowListener implements ListSelectionListener {
304+ RunnerPanel p
305+
306+ new (RunnerPanel p) {
307+ this . p = p
308+ }
309+
310+ override void valueChanged (ListSelectionEvent event ) {
311+ val rowIndex = p. failuresTable. selectedRow
312+ if (rowIndex != - 1 ) {
313+ val row = p. failuresTable. convertRowIndexToModel(rowIndex)
314+ val expectation = p. failuresTableModel. getExpectation(row)
315+ p. testFailureMessageTextArea. text = expectation. message
316+ p. testFailureCallerTextArea. text = expectation. caller
317+ }
318+ }
319+ }
320+
308321 static class TimeFormatRenderer extends DefaultTableCellRenderer {
309322 static val DecimalFormat formatter = new DecimalFormat (" #,##0.000" )
310323
@@ -318,7 +331,7 @@ class RunnerPanel implements FocusListener, ActionListener {
318331 static class TestTableHeaderRenderer extends DefaultTableCellRenderer {
319332 override getTableCellRendererComponent (JTable table , Object val ue , boolean isSelected , boolean hasFocus ,
320333 int row , int col ) {
321- val renderer = table. getTableHeader() . getDefaultRenderer()
334+ val renderer = table. tableHeader . defaultRenderer
322335 val label = renderer. getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col) as JLabel
323336 if (col == = 0 ) {
324337 label. icon = UtplsqlResources . getIcon(" UTPLSQL_ICON" )
@@ -339,6 +352,18 @@ class RunnerPanel implements FocusListener, ActionListener {
339352 return label
340353 }
341354 }
355+
356+ static class FailuresTableHeaderRenderer extends DefaultTableCellRenderer {
357+ override getTableCellRendererComponent (JTable table , Object val ue , boolean isSelected , boolean hasFocus ,
358+ int row , int col ) {
359+ val renderer = table. tableHeader. defaultRenderer
360+ val label = renderer. getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col) as JLabel
361+ if (col == = 0 ) {
362+ label. horizontalAlignment = JLabel . RIGHT
363+ }
364+ return label
365+ }
366+ }
342367
343368 private def makeLabelledCounterComponent (JLabel label , JComponent comp ) {
344369 val groupPanel = new JPanel
@@ -721,45 +746,27 @@ class RunnerPanel implements FocusListener, ActionListener {
721746 val testPropertiesScrollPane = new JScrollPane (testInfoPanel)
722747
723748 // Failures tabbed pane (failed expectations)
724- // TODO support unbound number of failed expectations
725- // - description
749+ // - failures table (number and description)
750+ failuresTableModel = new FailuresTableModel
751+ failuresTable = new JTable (failuresTableModel)
752+ failuresTable. tableHeader. reorderingAllowed = false
753+ failuresTable. selectionModel. addListSelectionListener(new FailuresRowListener (this ))
754+ val failuresTableHeaderRenderer = new FailuresTableHeaderRenderer
755+ val failuresTableNumber = failuresTable. columnModel. getColumn(0 )
756+ failuresTableNumber. headerRenderer = failuresTableHeaderRenderer
757+ failuresTableNumber. preferredWidth = 60
758+ failuresTableNumber. maxWidth = 60
759+ val failuresTableScrollPane = new JScrollPane (failuresTable)
760+ // - failures details
726761 val testFailuresPanel = new JPanel
727762 testFailuresPanel. setLayout(new GridBagLayout ())
728- val testFailureDescriptionLabel = new JLabel (" Description" )
729- c. gridx = 0
730- c. gridy = 0
731- c. gridwidth = 1
732- c. gridheight = 1
733- c. insets = new Insets (10 , 10 , 0 , 0 ) // top, left, bottom, right
734- c. anchor = GridBagConstraints :: WEST
735- c. fill = GridBagConstraints :: NONE
736- c. weightx = 0
737- c. weighty = 0
738- testFailuresPanel. add(testFailureDescriptionLabel, c)
739- testFailureDescriptionTextArea = new JTextArea
740- testFailureDescriptionTextArea. editable = false
741- testFailureDescriptionTextArea. enabled = true
742- testFailureDescriptionTextArea. lineWrap = true
743- testFailureDescriptionTextArea. wrapStyleWord = true
744- testFailureDescriptionTextArea. addFocusListener(this )
745- val testFailureDescriptionScrollPane = new JScrollPane (testFailureDescriptionTextArea)
746- c. gridx = 1
747- c. gridy = 0
748- c. gridwidth = 1
749- c. gridheight = 1
750- c. insets = new Insets (5 , 5 , 0 , 10 ) // top, left, bottom, right
751- c. anchor = GridBagConstraints :: WEST
752- c. fill = GridBagConstraints :: HORIZONTAL
753- c. weightx = 1
754- c. weighty = 0
755- testFailuresPanel. add(testFailureDescriptionScrollPane, c)
756763 // - message
757764 val testFailureMessageLabel = new JLabel (" Message" )
758765 c. gridx = 0
759- c. gridy = 1
766+ c. gridy = 0
760767 c. gridwidth = 1
761768 c. gridheight = 1
762- c. insets = new Insets (5 , 10 , 0 , 0 ) // top, left, bottom, right
769+ c. insets = new Insets (10 , 10 , 0 , 0 ) // top, left, bottom, right
763770 c. anchor = GridBagConstraints :: NORTHWEST
764771 c. fill = GridBagConstraints :: NONE
765772 c. weightx = 0
@@ -773,10 +780,10 @@ class RunnerPanel implements FocusListener, ActionListener {
773780 testFailureMessageTextArea. addFocusListener(this )
774781 val testFailureMessageScrollPane = new JScrollPane (testFailureMessageTextArea)
775782 c. gridx = 1
776- c. gridy = 1
783+ c. gridy = 0
777784 c. gridwidth = 1
778785 c. gridheight = 1
779- c. insets = new Insets (5 , 5 , 0 , 10 ) // top, left, bottom, right
786+ c. insets = new Insets (10 , 5 , 0 , 10 ) // top, left, bottom, right
780787 c. anchor = GridBagConstraints :: WEST
781788 c. fill = GridBagConstraints :: BOTH
782789 c. weightx = 1
@@ -785,10 +792,10 @@ class RunnerPanel implements FocusListener, ActionListener {
785792 // - caller
786793 val testFailureCallerLabel = new JLabel (" Caller" )
787794 c. gridx = 0
788- c. gridy = 2
795+ c. gridy = 1
789796 c. gridwidth = 1
790797 c. gridheight = 1
791- c. insets = new Insets (5 , 10 , 0 , 0 ) // top, left, bottom, right
798+ c. insets = new Insets (5 , 10 , 10 , 0 ) // top, left, bottom, right
792799 c. anchor = GridBagConstraints :: NORTHWEST
793800 c. fill = GridBagConstraints :: NONE
794801 c. weightx = 0
@@ -802,7 +809,7 @@ class RunnerPanel implements FocusListener, ActionListener {
802809 testFailureCallerTextArea. addFocusListener(this )
803810 val testFailureCallerScrollPane = new JScrollPane (testFailureCallerTextArea)
804811 c. gridx = 1
805- c. gridy = 2
812+ c. gridy = 1
806813 c. gridwidth = 1
807814 c. gridheight = 1
808815 c. insets = new Insets (5 , 5 , 10 , 10 ) // top, left, bottom, right
@@ -811,6 +818,9 @@ class RunnerPanel implements FocusListener, ActionListener {
811818 c. weightx = 1
812819 c. weighty = 2
813820 testFailuresPanel. add(testFailureCallerScrollPane, c)
821+ // - split pane
822+ val failuresSplitPane = new JSplitPane (SwingConstants . HORIZONTAL , failuresTableScrollPane, testFailuresPanel)
823+ failuresSplitPane. resizeWeight = 0.2
814824
815825 // Errors tabbed pane (Error Stack)
816826 val testErrorStackPanel = new JPanel
@@ -878,7 +888,7 @@ class RunnerPanel implements FocusListener, ActionListener {
878888 // split pane with all tabs
879889 testDetailTabbedPane = new JTabbedPane ()
880890 testDetailTabbedPane. add(" Test" , testPropertiesScrollPane)
881- testDetailTabbedPane. add(" Failures" , testFailuresPanel )
891+ testDetailTabbedPane. add(" Failures" , failuresSplitPane )
882892 testDetailTabbedPane. add(" Errors" , testErrorStackPanel)
883893 testDetailTabbedPane. add(" Warnings" , testWarningsPanel)
884894 testDetailTabbedPane. add(" Info" , testServerOutputPanel)
0 commit comments