Isn't this SwingWorker using Threads in a ThreadPoolExecutor?
As part of the Final Year project, I developed a desktop application that fits the "graphical development environment" category, if such a thing exists. I've followed a small subset of Jessy James Garrett's Visual Vocabulary for information architecture and interaction design , so a user can draw a diagram (directional graph, in other words) representing the user experience in a webapp, assigning HTML templates to pages and writing some code into the connector / transition. which will be executed as soon as the application is compiled and the user clicks on the corresponding hyperlink.
(I can't post more than one hyperlink, but I mean pages and connectors like the User Experience Items described in Visual Javascript JJG)
So, I'm using different SwingWorkers to create a set of C ++ source files that the diagram is converted to. Looking at the logs, I can see that my application is always creating new threads instead of reusing them.
15:29:55.750 [SwingWorker-pool-2-thread-26] DEBUG i.v.a.ui.worker.ConnectorGenerator - Building source code for transition: connector_29
15:29:55.750 [SwingWorker-pool-2-thread-26] DEBUG i.v.a.ui.worker.ConnectorGenerator - Project retrieved: sasdasdasd
15:29:55.750 [SwingWorker-pool-2-thread-26] INFO i.v.a.webapp.htcpp.CTransition - Generated C:\Workspaces\PFC\aedifico-ui\sasdasdasd\connector_29_action.h...
15:29:55.750 [SwingWorker-pool-2-thread-26] INFO i.v.a.webapp.htcpp.CTransition - Generated C:\Workspaces\PFC\aedifico-ui\sasdasdasd\connector_29_action.cpp...
15:29:55.750 [SwingWorker-pool-2-thread-26] DEBUG i.v.a.ui.worker.ConnectorGenerator - Transition generated at: C:\Workspaces\PFC\aedifico-ui\sasdasdasd/connector_29_action.cpp
All my employees do the same two things:
-
Create a pair of C ++ source and header files using the Freemarker templating engine.
-
Send messages in
EDT
through the publishing mechanism to inform the user how things are going.
I believe I have carefully coded SwingWorker
. I was particularly worried about FileWriter instances not being closed as expected, but I see no reason ThreadPoolExecutor
not to use re-created streams.
The magic happens in ConnectorGenerator
. BaseWorker
extends SwingWorker<V,T>
and simply stores the behavior for linking with the component to display messages to the user.
public class ConnectorGenerator<Void> extends BaseWorker<Void> {
@Override
public Void doInBackground() {
Transition transition = connector.getModel().getTransition();
logger.debug("Building source code for transition: {}", transition.getName());
logger.debug("Project retrieved: {}", project.getName());
try {
publish("Generating transition (%s) source code at %s", transition.getName(), project.getBaseDir());
/**
* Transition.build(String), attached below, is responsible of generating and writing the files
*/
transition.build(project.getBaseDir().getPath());
publish("Transition generated.");
} catch (BuilderException e) {
logger.error("Error: {}", e);
publish("There was an error that prevented generating %s source code", transition.getName());
}
logger.debug("Transition generated at: {}/{}", project.getBaseDir(), transition.getSource());
return null;
}
}
And the method Transition.build(String)
, including the try-catch-finally block of ugly hell:
@Override
public void build(String path) throws BuilderException {
generateFile(String.format("%s%s%s", path, File.separator, getHeader()), "action.h.ftl");
generateFile(String.format("%s%s%s", path, File.separator, getSource()), "action.cpp.ftl");
}
private void generateFile(String path, String templateName) throws BuilderException {
FileWriter out = null;
try {
Map<String, Object> model = new HashMap<String, Object>();
model.put("transition", this);
Configuration config = new Configuration();
config.setClassForTemplateLoading(CTransition.class, "/");
config.setObjectWrapper(ObjectWrapper.DEFAULT_WRAPPER);
out = new FileWriter(path);
freemarker.template.Template template = config.getTemplate(templateName);
template.process(model, out, ObjectWrapper.BEANS_WRAPPER);
stdout.info("Generated {}...", path);
} catch (IOException e) {
throw new BuilderException(e);
} catch (TemplateException e) {
throw new BuilderException(e);
} finally {
if (out != null)
try {
out.flush();
out.close();
} catch (IOException e) {
throw new BuilderException(e);
}
}
}
Does anyone see or know something that I am probably missing?
a source to share