1
+ /*
2
+ * Copyright 2018 Philipp Salvisberg <[email protected] >
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ package org.utplsql.sqldev
17
+
18
+ import java.awt.Component
19
+ import java.awt.Dimension
20
+ import java.awt.GridBagConstraints
21
+ import java.awt.GridBagLayout
22
+ import java.awt.Insets
23
+ import java.awt.Rectangle
24
+ import java.awt.Toolkit
25
+ import java.awt.event.ActionEvent
26
+ import java.awt.event.ActionListener
27
+ import java.awt.event.FocusEvent
28
+ import java.awt.event.FocusListener
29
+ import java.awt.event.WindowEvent
30
+ import javax.swing.BorderFactory
31
+ import javax.swing.JButton
32
+ import javax.swing.JFrame
33
+ import javax.swing.JLabel
34
+ import javax.swing.JPanel
35
+ import javax.swing.JScrollPane
36
+ import javax.swing.JTextArea
37
+ import javax.swing.JTextField
38
+ import javax.swing.ScrollPaneConstants
39
+ import javax.swing.SwingUtilities
40
+ import org.springframework.core.task.SimpleAsyncTaskExecutor
41
+ import org.utplsql.sqldev.resources.UtplsqlResources
42
+
43
+ class CodeCoverageReporterWindow extends JFrame implements ActionListener , FocusListener {
44
+
45
+ var CodeCoverageReporter reporter
46
+ var JButton runButton
47
+ var JButton cancelButton
48
+ var JPanel paneParams;
49
+ var int paramPos = - 1 ;
50
+ val pathsTextArea = new JTextArea ()
51
+ val schemasTextField = new JTextField ()
52
+ val includeObjectsTextArea = new JTextArea ()
53
+ val excludeObjectsTextArea = new JTextArea ()
54
+
55
+ def static createAndShow (CodeCoverageReporter reporter ) {
56
+ SwingUtilities . invokeLater(new Runnable () {
57
+ override run() {
58
+ CodeCoverageReporterWindow . createAndShowWithinEventThread(reporter);
59
+ }
60
+ });
61
+ }
62
+
63
+ def private static createAndShowWithinEventThread (CodeCoverageReporter reporter ) {
64
+ // create and layout the dialog
65
+ val frame = new CodeCoverageReporterWindow (reporter)
66
+ reporter. frame = frame
67
+ frame. pack
68
+ // center dialog
69
+ val dim = Toolkit . getDefaultToolkit(). getScreenSize();
70
+ frame. setLocation(dim. width / 2 - frame. getSize(). width / 2 , dim. height / 2 - frame. getSize(). height / 2 );
71
+ frame. alwaysOnTop = true
72
+ frame. visible = true
73
+ }
74
+
75
+ new (CodeCoverageReporter reporter) {
76
+ super (UtplsqlResources . getString(" WINDOW_CODE_COVERAGE_REPORT_LABEL" ))
77
+ this . reporter = reporter
78
+ val pane = this . getContentPane();
79
+ pane. setLayout(new GridBagLayout ());
80
+ val c = new GridBagConstraints ();
81
+
82
+ // parameters pane
83
+ paneParams = new JPanel (new GridBagLayout ())
84
+ pathsTextArea. editable = false
85
+ pathsTextArea. enabled = false
86
+ addParam(UtplsqlResources . getString(" WINDOW_PATHS_LABEL" ), ' ' ' «FOR path : reporter.pathList SEPARATOR ", "»«path»«ENDFOR»' ' ' , pathsTextArea)
87
+ addParam(UtplsqlResources . getString(" WINDOW_SCHEMAS_LABEL" ), " " , schemasTextField);
88
+ addParam(UtplsqlResources . getString(" WINDOW_INCLUDE_OBJECS_LABEL" ), ' ' ' «FOR i : reporter.includeObjectList SEPARATOR ", "»«i»«ENDFOR»' ' ' , includeObjectsTextArea);
89
+ addParam(UtplsqlResources . getString(" WINDOW_EXCLUDE_OBJECS_LABEL" ), " " , excludeObjectsTextArea);
90
+ val scrollPane = new JScrollPane (paneParams)
91
+ scrollPane. verticalScrollBarPolicy = ScrollPaneConstants . VERTICAL_SCROLLBAR_AS_NEEDED
92
+ scrollPane. horizontalScrollBarPolicy = ScrollPaneConstants . HORIZONTAL_SCROLLBAR_NEVER
93
+ scrollPane. border = BorderFactory . createEmptyBorder;
94
+ c. gridx = 0 ;
95
+ c. gridy = 0 ;
96
+ c. gridwidth = 2 ;
97
+ c. insets = new Insets (10 , 10 , 0 , 10 ); // top, left, bottom, right
98
+ c. anchor = GridBagConstraints . NORTH ;
99
+ c. fill = GridBagConstraints . BOTH ;
100
+ c. weightx = 1 ;
101
+ c. weighty = 1 ;
102
+ pane. add(scrollPane, c)
103
+
104
+ // Buttons pane
105
+ val panelButtons = new JPanel (new GridBagLayout ())
106
+ runButton = new JButton (UtplsqlResources . getString(" WINDOW_RUN_BUTTON" ))
107
+ runButton. addActionListener(this );
108
+ c. gridx = 0 ;
109
+ c. gridy = 0 ;
110
+ c. gridwidth = 1 ;
111
+ c. insets = new Insets (0 , 0 , 0 , 0 ); // top, left, bottom, right
112
+ c. fill = GridBagConstraints . NONE ;
113
+ c. weightx = 0 ;
114
+ c. weighty = 0 ;
115
+ panelButtons. add(runButton, c);
116
+ cancelButton = new JButton (UtplsqlResources . getString(" WINDOW_CANCEL_BUTTON" ));
117
+ cancelButton. addActionListener(this );
118
+ c. gridx = 1 ;
119
+ c. insets = new Insets (0 , 10 , 0 , 0 ); // top, left, bottom, right
120
+ c. fill = GridBagConstraints . NONE ;
121
+ c. weightx = 0 ;
122
+ c. weighty = 0 ;
123
+ panelButtons. add(cancelButton, c);
124
+ c. gridx = 1 ;
125
+ c. gridy = 1 ;
126
+ c. gridwidth = 1 ;
127
+ c. insets = new Insets (30 , 10 , 10 , 10 ); // top, left, bottom, right
128
+ c. anchor = GridBagConstraints . EAST
129
+ c. fill = GridBagConstraints . NONE
130
+ c. weightx = 0 ;
131
+ c. weighty = 0 ;
132
+ pane. add(panelButtons, c);
133
+ pane. setPreferredSize(new Dimension (600 , 320 ));
134
+ SwingUtilities . getRootPane(runButton). defaultButton = runButton
135
+ }
136
+
137
+ private def addParam (String label , String text , Component component ) {
138
+ paramPos++
139
+ val c = new GridBagConstraints ();
140
+ val paramLabel = new JLabel (label)
141
+ c. gridx = 0
142
+ c. gridy = paramPos
143
+ c. gridwidth = 1
144
+ c. insets = new Insets (10 , 10 , 0 , 0 ) // top, left, bottom, right
145
+ c. anchor = GridBagConstraints . NORTHWEST
146
+ c. fill = GridBagConstraints . HORIZONTAL
147
+ c. weightx = 0
148
+ c. weighty = 0
149
+ paneParams. add(paramLabel, c);
150
+ c. gridx = 1
151
+ c. gridwidth = GridBagConstraints . REMAINDER
152
+ c. anchor = GridBagConstraints . WEST
153
+ c. fill = GridBagConstraints . BOTH
154
+ c. insets = new Insets (10 , 10 , 0 , 10 ); // top, left, bottom, right
155
+ c. weightx = 1
156
+ if (component instanceof JTextField ) {
157
+ component. text = text
158
+ c. weighty = 0
159
+ paneParams. add(component, c)
160
+ } else if (component instanceof JTextArea ) {
161
+ component. text = text
162
+ component. lineWrap = true
163
+ component. wrapStyleWord = true
164
+ var scrollPane = new JScrollPane (component);
165
+ scrollPane. viewport. preferredSize = new Dimension (200 , 50 )
166
+ c. weighty = 1
167
+ paneParams. add(scrollPane, c)
168
+ }
169
+ component. addFocusListener(this )
170
+ }
171
+
172
+ def exit () {
173
+ this . dispatchEvent(new WindowEvent (this , WindowEvent . WINDOW_CLOSING ));
174
+ }
175
+
176
+ override actionPerformed (ActionEvent e ) {
177
+ if (e. getSource == runButton) {
178
+ reporter. schemas = schemasTextField. text
179
+ reporter. includeObjects = includeObjectsTextArea. text
180
+ reporter. excludeObjects = excludeObjectsTextArea. text
181
+ schemasTextField. setEnabled(false )
182
+ includeObjectsTextArea. setEnabled(false )
183
+ excludeObjectsTextArea. setEnabled(false )
184
+ runButton. setEnabled(false )
185
+ reporter. runAsync
186
+ } else if (e. getSource == cancelButton) {
187
+ if (runButton. enabled) {
188
+ // report is not yet started, just close the window
189
+ exit
190
+ } else {
191
+ // report is being created...
192
+ // frame will close as soon as the connection is technically aborted
193
+ // database session is not cancelled. This is not a bug.
194
+ // to cancel the session you have to kill it via "ALTER SYSTEM KILL SESSION".
195
+ // However, the abort frees all resources on the client side.
196
+ reporter. connection. abort(new SimpleAsyncTaskExecutor )
197
+ }
198
+ }
199
+ }
200
+
201
+ override focusGained (FocusEvent e ) {
202
+ if (paneParams. isAncestorOf(e. component)) {
203
+ // make component at cursor position is visible
204
+ val x = e. component. getLocationOnScreen. x - paneParams. getLocationOnScreen. x
205
+ val y = e. component. getLocationOnScreen. y - paneParams. getLocationOnScreen. y
206
+ val width = e. component. getBounds. width
207
+ val height = e. component. getBounds. height
208
+ val rect = new Rectangle (x, y, width, height)
209
+ paneParams. scrollRectToVisible(rect)
210
+ }
211
+ }
212
+
213
+ override focusLost (FocusEvent e ) {
214
+ // ignore
215
+ }
216
+
217
+ }
0 commit comments