@@ -21,12 +21,14 @@ import java.awt.Dimension
2121import java.awt.GridBagConstraints
2222import java.awt.GridBagLayout
2323import java.awt.Insets
24+ import java.text.DecimalFormat
2425import javax.swing.JLabel
2526import javax.swing.JPanel
2627import javax.swing.JProgressBar
2728import javax.swing.JScrollPane
2829import javax.swing.JTable
2930import javax.swing.plaf.basic.BasicProgressBarUI
31+ import javax.swing.table.DefaultTableCellRenderer
3032import org.utplsql.sqldev.model.LimitedLinkedHashMap
3133import org.utplsql.sqldev.model.runner.Run
3234import org.utplsql.sqldev.resources.UtplsqlResources
@@ -54,6 +56,7 @@ class RunnerPanel {
5456 def setModel (Run run ) {
5557 runs. put(run. reporterId, run)
5658 testOverviewTableModel. model = run. tests
59+ testOverviewTable. rowSorter. sortKeys = null
5760 }
5861
5962 def update (String reporterId ) {
@@ -62,7 +65,11 @@ class RunnerPanel {
6265 if (row < 0 ) {
6366 testOverviewTableModel. fireTableDataChanged
6467 } else {
65- testOverviewTableModel. fireTableRowsUpdated(row, row)
68+ if (testOverviewTableModel. rowCount > row) {
69+ testOverviewTableModel. fireTableRowsUpdated(row, row)
70+ val positionOfCurrentTest = testOverviewTable. getCellRect(row, 0 , true );
71+ testOverviewTable. scrollRectToVisible = positionOfCurrentTest
72+ }
6673 }
6774 statusLabel. text = run. status
6875 testCounterValueLabel. text = ' ' ' «run.totalNumberOfCompletedTests»/«run.totalNumberOfTests»' ' '
@@ -79,6 +86,25 @@ class RunnerPanel {
7986 progressBar. foreground = GREEN
8087 }
8188 }
89+
90+ static class TimeFormatRenderer extends DefaultTableCellRenderer {
91+ static val DecimalFormat formatter = new DecimalFormat (" #,##0.000" )
92+
93+ override getTableCellRendererComponent (JTable table , Object val ue , boolean isSelected ,
94+ boolean hasFocus , int row , int col ) {
95+ val renderedValue = if (value == = null ) {null } else {formatter. format(value as Number )}
96+ return super . getTableCellRendererComponent(table, renderedValue, isSelected, hasFocus, row, col) }
97+ }
98+
99+ static class TestTableHeaderRenderer extends DefaultTableCellRenderer {
100+ override getTableCellRendererComponent (JTable table , Object val ue , boolean isSelected , boolean hasFocus ,
101+ int row , int col ) {
102+ val renderer = table. getTableHeader(). getDefaultRenderer()
103+ val label = renderer. getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col) as JLabel
104+ label. horizontalAlignment = if (col == = 2 ) {JLabel . RIGHT } else {JLabel . LEFT }
105+ return label
106+ }
107+ }
82108
83109 private def initializeGUI () {
84110 // Base panel containing all components
@@ -196,14 +222,22 @@ class RunnerPanel {
196222 // Test overview - first part of the horizontal split pane
197223 testOverviewTableModel = new TestOverviewTableModel
198224 testOverviewTable = new JTable (testOverviewTableModel)
225+ testOverviewTable. tableHeader. reorderingAllowed = false
226+ testOverviewTable. autoCreateRowSorter = true
227+ val testTableHeaderRenderer = new TestTableHeaderRenderer
199228 val overviewTableIcon = testOverviewTable. columnModel. getColumn(0 )
200229 overviewTableIcon. minWidth = 20
201230 overviewTableIcon. preferredWidth = 20
202231 overviewTableIcon. maxWidth = 20
232+ val overviewTableId = testOverviewTable. columnModel. getColumn(1 )
233+ overviewTableId. headerRenderer = testTableHeaderRenderer
203234 val overviewTableTime = testOverviewTable. columnModel. getColumn(2 )
204235 overviewTableTime. preferredWidth = 60
205236 overviewTableTime. maxWidth = 100
206- testOverviewTable. tableHeader. reorderingAllowed = false
237+ overviewTableTime. headerRenderer = testTableHeaderRenderer
238+ val timeFormatRenderer = new TimeFormatRenderer
239+ timeFormatRenderer. horizontalAlignment = JLabel . RIGHT
240+ overviewTableTime. cellRenderer = timeFormatRenderer
207241 val testOverviewScrollPane = new JScrollPane (testOverviewTable)
208242 c. gridx = 0
209243 c. gridy = 3
0 commit comments