Skip to content

Commit bec82af

Browse files
dialog for code coverage reporter with cancel capabilities
1 parent 2cc7e0d commit bec82af

File tree

1 file changed

+217
-0
lines changed

1 file changed

+217
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
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

Comments
 (0)