Calculation in Wizard - java

This is more of a general question. We have a lot of wizard, some of which start a long-running process and display the result after. The question is: what is the correct way to do long calculations?
Formerly most wizards did their calculations in DialogPage#setVisible, something like that:
public void setVisible(final boolean visible) {
if (visible) {
getWizard().getContainer().run(true, true, new MyCalculation());
}
super.setVisible(visible);
}
I don't think that's a good idea, since usually getWizard() gets called a lot in these methods. Moreover, usually the parent wizard gets cast to a specific implementation to get input values from or set the result to other pages. So usually it looks something like this:
public void setVisible(final boolean visible) {
if (visible) {
Input input = ((MyCalculationWizard)getWizard()).getInputPage().getInput();
MyCalculation calculation = new MyCalculation(input);
getWizard().getContainer().run(true, true, calculation);
Output output = calculation.getOutput();
((MyCalculationWizard)getWizard()).getOtherPage().setOutput(output);
}
super.setVisible(visible);
}
Just from looking at the code you know that's very bad style.
So we replaced it with something that calculates in Wizard#getNextPage():
public IWizardPage getNextPage(final IWizardPage page) {
final IWizardPage nextPage = super.getNextPage(page);
if (nextPage == this.myResultPage)
getContainer().run(true, true, new MyCalculation());
return nextPage;
}
That way, the wizard is able to fine-tune a lot better than a page would, and the wizard already knows it's pages and can handle input and output a lot better than a page ever could.
The drawback is: getNextPage() gets called a lot for updating the buttons and every time really the wizard feels like it. So while it works for small processes, it does not cut it for long-running ones.
After some more poking around I found the following to work while overriding Wizard#setContainer:
public void setContainer(final IWizardContainer wizardContainer) {
final IWizardContainer oldContainer = getContainer();
if (oldContainer instanceof WizardDialog)
((WizardDialog) oldContainer).removePageChangingListener(this);
super.setContainer(wizardContainer);
if (wizardContainer instanceof WizardDialog)
((WizardDialog) wizardContainer).addPageChangingListener(this);
}
public void handlePageChanging(final PageChangingEvent event) {
final IWizardPage currentPage = (IWizardPage) event.getCurrentPage();
final IWizardPage nextPage = (IWizardPage) event.getTargetPage();
if (currentPage == this.myInputPage && nextPage == this.myResultPage)
getContainer().run(true, true, new MyCalculation());
}
The big advantage here is that the listener only gets called if the wizard wants to jump between pages, and we are able to really fine-tune the calculation (e.g. to not be called when calling 'Previous'). We are even able to not show the next page after all (event.doit = false).
The drawback is the cast of the container to WizardDialog, because potentially it could be an entirely different implementation.
So the question stands: What is the best way to start long processes in wizards?

Related

Java convention in practice - return mutliple values from method

I have two questions about Java Convention. I try to make use od Robert C. Martin's "Clean Code".
Following case:
public void startProgressIfAllowed() {
try {
tryStartProgressIfAllowed();
} catch (Exception exception) {
// log error
}
}
private void tryStartProgressIfAllowed() {
if (isStartProgressAllowed()) {
stopProgressOnCurrentlyStartedTask();
startProgressOnThisTask();
}
}
private boolean isStartProgressAllowed() {
// Calls JOptionPane.showConfirmDialog with JOptionPane.YES_NO_OPTION.
// Created dialog contains checkbox indicating that saving currently started task is required.
// returns boolean depending on JOptionPane.YES_NO_OPTION clicked button
}
private void stopProgressOnCurrentlyStartedTask() {
// Saves currently started task depending on checkbox selecion property and stops currently started.
// What is the correct way to get checkbox selecion property?
}
Proposed solution:
public void tryStartProgressIfAllowed() {
if (tryToStopProgressOnStartedTaskIfNecessary()) {
startProgressOnThisTask();
}
}
private boolean tryToStopProgressOnStartedTaskIfNecessary() {
// Calls JOptionPane.showConfirmDialog with JOptionPane.YES_NO_OPTION.
// Created dialog contains checkbox indicating that saving currently started task is required.
// Depending on checkbox selecion property saves task.
// returns boolean depending on JOptionPane.YES_NO_OPTION clicked button
}
But this approach doesn't meet the "Command Query Separation" principle, because tryToStopProgressOnStartedTaskIfNecessary(...) method performs some logic and returns success/failure value.
I think this approach also doesn't meet the "One level of abstraction per function" principle, because I suppose "check" and "save" operations are on different levels of abstraction.
Is the method name correct to avoid disinformation? Maybe better name would be tryToStopProgressAndSaveStartedTaskIfNecessary(...)?
Is there any better solution for above problem?
What about the following:
public void tryStartProgressOnThisTaskIfAllowed() {
tryStopTaskInProgressIfAllowed()
if (!isTaskInProgress()) {
tryStartProgressOnThisTask();
}
}
private void tryStopTaskInProgressIfAllowed() {
if (!isTaskInProgress()) {
return;
}
TaskInProgressResult result = whatToDoWithTaskInProgress();
if (result == Result.KEEP) {
return;
} else if (result == Result.DROP)
tryDropTaskInProgress();
} else if (result == Result.SAVE) {
trySaveTaskInProgress();
}
}
About your points:
You now have two separate methods for C and Q
I think the two things whatToDoWithTaskInProgress and tryDropTaskInProgress are the same level of abstraction. If you'd inline the code of one or the other you were absolutely right of course.
I changed some of the method names according to my taste :) The only thing I still don't like is the part "OnThisTask" because this task is somewhat meaningless. Maybe it's only because the rest of the code is unknown maybe OnNextTask or OnNewTask are better.
The problem we were having is that we were thinking in UI terms YES/NO + checkbox value. But it is much better to think in business terms here. I identified three different outcomes that are of interest: KEEP, SAVE, DROP How the answer is obtained should not matter to the calling method.
This seems something to ask on CodeReview, see the drop down at the top left of the page.
An example of how such stateliness is realized in Java SE: the regex Matcher class.
String s = ...
Pattern pattern = Pattern.compile("...");
Matcher m = pattern.matcher(s);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, ... m.group(1) ...);
}
m.appendTail(sb);
with m.matches() and m.lookingAt as alternative circuits too.
In short state is held in a processing class on the actual data (String here).

Where should I validate JavaFX Property changes?

I have a mvp structured javafx application. There is a view with a textfield, which has its own textProperty of type StringProperty. There is also a model which contains an Object called Item. Item has an IntegerProperty.
Now I'd like to bind these two Properties within my presenter-class, so that they get updated, when one or another changes. Eventhough they have different types, there is the possibility to bind them the following way:
Bindings.bindBidirectional( textField.textProperty(), item.percentProperty(), new NumberStringConverter() );
This works perfectly fine, unless the value of the textfield gets cleared, which results in a NullPointerException, because an empty value of textProperty results in a Null-Value and setting a null Value in IntegerProperty results in a NullPointerException. Can you think of any way to avoid this? Do I have to write my own NumberStringConverter?
Moreover I'd like to define, that Item can only hold a percent value between 0 and 100. The View should be informed, when the value is invalid, so the user can get feedback. Where should I verify these kind of businessrules?
I came up with a first example, but I am not sure, if that should be the way to go, so I'd be curious, if you might have better ideas how to solve this.
class PercentProperty extends SimpleIntegerProperty
{
private InvalidValueListener invalidValueListener = null;
public PercentProperty ( final Integer defaultValue )
{
set( defaultValue );
}
#Override
public void set( final int newValue )
{
if ( isValid( newValue ) )
{
super.set( newValue );
if ( invalidValueListener != null )
invalidValueListener.validValue();
}
else
{
if ( invalidValueListener != null )
invalidValueListener.invalidValue();
}
}
private boolean isValid( final int value )
{
return (value >= 0 && value <= 100);//FIXME: Better use Predicates to define Rules.
}
public void setListener( final InvalidValueListener listener )
{
invalidValueListener = listener;
}
public void removeListener( #SuppressWarnings( "unused" ) final InvalidValueListener listener )
{
invalidValueListener = null;
}
protected void fireInvalidationValue()
{
invalidValueListener.invalidValue();
}
}
interface InvalidValueListener
{
void validValue();
void invalidValue();
}
JavaFX is a simple graphical toolkit, not a comprehensive framework, and this means that lots of things you have to engineer yourself. Data validation is such a thing, and you have to find your own way among your previous experience and others' suggestions.
I would not bind the two properties: the text field should be initialized (just set, not bound, to avoid glitches while the user is typing without her explicit consensus) with the value from the model, and then the integer property should be updated by a listener (a text field's ChangeListener or a listener to the form submission, if appliable and depending on your likes), which is responsible for validating input and reporting errors to the user.
This way you decouple two things that are indeed unrelated: one is a widget for accepting user input (a text you need to parse to get a number), and the other is a number in your model, which is used to make a computation.
As a side note, I would not use two properties altogether, and I'd revisit your three tiers parition. MVP and all MVC derivatives proved to be good patterns to build GUI toolkits, but I was never convinced they were equally good for structuring GUI applications. I mean, if what you call model is a way to share session data between different parts of the application (kind of an events sink) then it's a perfectly legitimate implementation, otherwise I see no use in having a separate bunch of properties grouped in a class. In the latter case, the widgets themselves are the model:
// This is the controller
public class PesonalDetails {
// Model starts here: it's implicitely defined by the widgets
// You may also use #FXML
private final TextField first = new TextField();
private final TextField last = new TextField();
// Model ends here
}
Note I'm not saying MVC should be thrown away and everything should be collapsed in one single file. Just that MVC, MVP, MVVM are design patterns and it's up to you to decide when, where and how to implement them - depending on how much they buy to you. With JavaFX I like to use these tiers:
A visual layout tier (a layout builder implemented in Java or FXML)
Event handling code
If appliable, a data access layer (and you can apply a pattern here, like ActiveRecord)
(The new version of the answer)
I think the best aproach is to not let a user enter an incorrect value in the first place. You can achive this easily with help of JideFX Fields:
FormattedTextField<Integer> field = new FormattedTextField<>();
field.getPatternVerifiers().put("p", new IntegerRangePatternVerifier(0, 100));
field.setPattern("p");
field.valueProperty().bindBidirectional(item.percentProperty());
Particularly FormattedTextField is very convenient because it do text-to-value conversion and validation for you, so there is no need to implement any utility classes yourself.
Links:
JideFX Fields Developer Guide: http://www.jidesoft.com/jidefx/JideFX_Fields_Developer_Guide.pdf
Source code: https://github.com/jidesoft/jidefx-oss
Binary: http://search.maven.org/#search%7Cga%7C1%7Cjidefx

Should Page Objects Return Page Objects?

We're currently working on building up a good test frame in our company. It's for a medium-to-large-sized webapp, perhaps with a couple dozen pages. We're currently writing mostly WebDriver Selenium UI-based tests.
We are trying to decide on some coding standards, and one thing we're discussing is whether to use Page Objects (PO) that always return PO (even if the page is the same), only return PO when you leave the current page for a new one, or even to not return PO. I've always thought returning PO is a key feature of the PO design pattern, but I may be incorrect about this.
Basically, we're trying to decide between the following patterns:
class SomePage {
// constructor
public SomePage(Driver) { //... }
// always return a page object
public SomePage fillInTextField(String val){
// details
return new SomePage(driver);
// only return a PO if it's a different page
public void fillInTextField(String val){
// details
return;
}
Is one preferable over the other?
It's a matter of style.
Using:
class SomePage {
...
// always return a page object
public SomePage fillInTextField(String val){
...
return this; // Note: NOT "new SomePage(driver)"
}
}
allows you to write things like:
SomePage somePage = HoweverYouGetASomePage();
NextPage nextPage = somePage.fillInTextField1("value1").fillInTextField2("value2").submit();
Using:
class SomePage {
...
// only return a PO if it's a different page
public void fillInTextField(String val){
...
return;
}
}
forces you to write things like:
SomePage somePage = HoweverYouGetASomePage();
somePage.fillInTextField1("value1");
somePage.fillInTextField2("value2");
NextPage nextPage = somePage.submit();
Which one you like depends on ... which one you like. But if you like being able to write the former, you need to always return the page object.
Short answer is that don't return same page objects if you are on the same page and state of the page is not changing. You would return new page objects if you are navigating from one page to another. It wouldn't make sense to return the same object when lets say you want to get some text or get a selected option from a page, since essentially nothing changed. If the state of the page is changing, then you would need to return the new page object otherwise you may likely face StaleElementException. In google docs, If you notice the LoginPage, getErrorMessage() does not return the same page object back
A little off from your original question, but I would recommend to use PageFactory, if you already aren't and are in the process of formalizing standards.
I've found it extremely maintainable to do this. Especially with Java 8. Using default methods in Java 8, components and widgets now become Mixins. By always returning a Page, you end up with test cases that look like this:
public class HomePageITest {
#Test
public we_should_be_able_to_search_from_the_homepage() {
pageFactory.getHomePage()
.get()
.doSomethingOnTheHomePage()
.clickSearchWidgetSubmitButton()
.doSomethingElseOnTheHomePage()
;
}
}
I have a blog post describing this in more detail here: http://blog.jsdevel.me/2015/04/pageobjects-done-right-in-java-8.html
As the PageObject Selenium help page said "Methods return other PageObjects"

How to properly add an ActionListeren to a custom JComponent

I often implement some panels, which provide common functionality like controls. For this I want to be able to add listeners, so that the caller can attach to the control and get notifications about changes.
So far I have simply used my own List where I keep the listeners and when I want to fire an action I loop through the list and call the listeners. From the outside this basically looks like any other Swing controls, however I was wondering if this is really the approach which should be used.
Especcially I was wondering if calling the listeners in a loop is what Swing itself also does, or if there is some kind of queue where you would put the actions, so that Swing decides when to deliver such actions.
When I investiaged this I came across this code:
protected void fireActionPerformed(ActionEvent event)
{
Object[] listeners = listenerList.getListenerList();
ActionEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2)
{
if(listeners[i] instanceof ActionListener)
{
// Lazily create the event:
if (e == null)
{
String actionCommand = event.getActionCommand();
e = new ActionEvent(this,
ActionEvent.ACTION_PERFORMED,
actionCommand,
event.getWhen(),
event.getModifiers());
e.setSource(event.getSource());
}
((ActionListener)listeners[i+1]).actionPerformed(e);
}
}
}
The member listenerList from JComponent is directly accessed, whcih feels a bit strange. However I didn't really find a better way so far. Also when adding a new listener to this, I do it now like shown below, but I'm not sure if this is really the appropriate way:
public void addQueryListener(ActionListener oListener)
{
listenerList.add(ActionListener.class, oListener);
}
public void removeQueryListener(ActionListener oListener)
{
listenerList.remove(ActionListener.class, oListener);
}
So I would like to know, is accessing the listenerList member the correct way to add and remove listeners, so that they behave like any other standard control? Or is there some best practice how this should be done, which I'm missing so far?
Keeping mind the restriction Swings put for Creating the gui. There is no harm accessing the
** listenerlist ** this way. May be this is not best approach.
Swing is Suppose to be Single Threaded and is not Thread Safe.
http://codeidol.com/java/java-concurrency/GUI-Applications/Why-are-GUIs-Single-threaded/
AddListener and RemoveListener needed to be called on EDT(Event Dispatch Thread)
see See http://en.wikipedia.org/wiki/Event_dispatching_thread.
Also See for iteration of Listenere i.e when you call getActionListeners
its creates a copy of ListenersList and returns you back
Below Code from EventListenerList
public <T extends EventListener> T[] getListeners(Class<T> t) {
Object[] lList = listenerList;
int n = getListenerCount(lList, t);
T[] result = (T[])Array.newInstance(t, n);
int j = 0;
for (int i = lList.length-2; i>=0; i-=2) {
if (lList[i] == t) {
result[j++] = (T)lList[i+1];
}
}
return result;
}
There's a good example in the EventListenerList docs, and this Converter example uses its own listenerList in ConverterRangeModel.

How to refactor to avoid passing "special values" into a Java method?

I'm sure there must be a standard way to do this, but my attempts to search Stackoverflow have failed.
I have a method like:
public void processSomeWidgetsForUser(int userItemId) {
Iterator<Widgets> iter = allWidgets.values().iterator();
while(iter.hasNext()) {
Widget thisWidget = iter.next();
if (userItemId == -1 || thisWidget.getUsersItemId() == userItemId) {
widget.process();
}
}
}
As you can see -1 is a "special value" meaning process all. Doing this saves repeating the loop code in another method called processSomeWidgetsForAllUsers.
But I dislike special values like this because they are easy to misuse or misunderstand, which is exactly the situation what I'm having to fix now (where someone thought -1 meant something else).
I can only think of two ways to improve this.
have a constant, containing -1 called something like
Widget.ALLWIDGETS which at least is self-documenting, but doesn't
stop code from using a -1 (if someone integrates old code in, for
example)
change the method to take a list of all user ids to
process, which can be empty, but that doesn't seem great
performance-wise (would need to retrieve all user ids first and then loop through
removing. Also what happens if the number of widgets in the list changes between
retreiving the ids and removing
Is there a better way? I'm sure I'm missing something obvious.
The above code has been changed slightly, so may not compile, but you should get the gist.
Although somewhat redundant, a fairly neat self-documenting approach could be to have 3 methods rather than one;
Make your original method private, and make one small change which would be to add your static final int EXECUTE_ALL = -1 and use that in your original method, then add the two new methods;
public void processWidget(int wID) throws IllegalArgumentException {
if(wID == EXECUTE_ALL) throw new IllegalArgumentException();
originalMethod(wID);
}
public void processAllWidgets() {
originalMethod(EXECUTE_ALL);
}
It makes your class a little more cluttered, but as far as the exposed methods go, it is clearer and hopefully foolproof. You could alter it not to throw an exception and just ignore any invalid ids, that just depends on your situation.
This approach of course has the major downside that it changes how the class appears to other classes, breaking everything that currently uses the, now private, originalMethod().
Number 1 would work very nicely. Be sure to document what the variable is though, so future coders (possibly yourself) know what it means.
/**This is the explanation for the below variable*/
public final static int ALL_WIDGETS = -1;
Have an external method like so:
static boolean idRepresentsAll(int id) {
return id == -1;
}
In this case, if you decide to replace it with a different mechanism, you only replace your magic number one place in your code.
At the very least, you would want to do something like this:
public static final int ID_REPRESENTING_ALL = -1;
You can change the method signature to accept a boolean for when you want to process them all.
public void processSomeWidgets(boolean doAll, int userItemId) {
Iterator<Widgets> iter = allWidgets.values().iterator();
while(iter.hasNext()) {
Widget thisWidget = iter.next();
if (doAll || thisWidget.getUsersItemId() == userItemId) {
widget.process();
}
}
}
This makes it more explicit, and easier to read in my opinion as there are no special values.

Categories

Resources