Skip to content

Commit f04aaed

Browse files
committed
added example 6a
1 parent f403f8e commit f04aaed

File tree

6 files changed

+427
-0
lines changed

6 files changed

+427
-0
lines changed

README.adoc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,29 @@ Tests:
214214

215215
link:./src/test/groovy/ch/petikoch/examples/mvvm_rxjava/example6[]
216216

217+
=== Example 6a: Form submit with exceptions in model (backend) calls
218+
219+
link:./src/main/java/ch/petikoch/examples/mvvm_rxjava/example6a[]
220+
221+
* Same as Example 6
222+
* But like in real world, there are sometimes exceptions during e.g. model (backend) method invoking's
223+
* How to handle them?
224+
225+
This is of course a challenging task: +
226+
How to combine results from asynchronous tasks? +
227+
How to handle exceptions in those?
228+
229+
This is a typical problem, which solves RxJava easily: It offers all the necessary API's.
230+
See e.g. https://github.com/ReactiveX/RxJava/wiki/Error-Handling-Operators or of course the `onError` `Action1` in `rx.Observable#subscribe(..)`.
231+
232+
In this example, there is some code to illustrate those.
233+
234+
image::example6a.png[]
235+
236+
Tests:
237+
238+
link:./src/test/groovy/ch/petikoch/examples/mvvm_rxjava/example6a[]
239+
217240
=== Example 7: Log table with LogRow's pushed up from the Model
218241

219242
link:./src/main/java/ch/petikoch/examples/mvvm_rxjava/example7[]

docs/example6a.png

69.5 KB
Loading
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Copyright 2015 Peti Koch
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 ch.petikoch.examples.mvvm_rxjava.example6a;
17+
18+
import ch.petikoch.examples.mvvm_rxjava.utils.SwingUtilities2;
19+
import ch.petikoch.examples.mvvm_rxjava.utils.SysOutUtils;
20+
import ch.petikoch.examples.mvvm_rxjava.utils.UncaughtExceptionHandlerInitializer;
21+
22+
import javax.swing.*;
23+
import java.lang.management.ManagementFactory;
24+
25+
class Example_6a_Main {
26+
27+
public static void main(String[] args) {
28+
SysOutUtils.sysout(ManagementFactory.getRuntimeMXBean().getName());
29+
UncaughtExceptionHandlerInitializer.initUncaughtExceptionHandler();
30+
31+
Example_6a_Model model = new Example_6a_Model();
32+
Example_6a_ViewModel viewModel = new Example_6a_ViewModel();
33+
viewModel.connectTo(model);
34+
35+
SwingUtilities2.invokeLater(() -> {
36+
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
37+
38+
Example_6a_View view = new Example_6a_View();
39+
view.bind(viewModel);
40+
view.setVisible(true);
41+
});
42+
}
43+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* Copyright 2015 Peti Koch
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 ch.petikoch.examples.mvvm_rxjava.example6a;
17+
18+
import ch.petikoch.examples.mvvm_rxjava.datatypes.NameFirstname;
19+
import ch.petikoch.examples.mvvm_rxjava.rxjava_mvvm.FinishedIndicator;
20+
import ch.petikoch.examples.mvvm_rxjava.utils.AsyncUtils;
21+
import ch.petikoch.examples.mvvm_rxjava.utils.SysOutUtils;
22+
import net.jcip.annotations.ThreadSafe;
23+
import rx.Single;
24+
25+
import java.util.concurrent.atomic.AtomicInteger;
26+
27+
@ThreadSafe
28+
class Example_6a_Model {
29+
30+
private final AtomicInteger failToken = new AtomicInteger(1);
31+
32+
public Single<FinishedIndicator> createAcount(NameFirstname nameFirstname) {
33+
return AsyncUtils.<FinishedIndicator>executeAsync(() -> {
34+
try {
35+
SysOutUtils.sysout("Processing createAcount: " + nameFirstname.toString());
36+
37+
if (failToken.incrementAndGet() % 3 == 0) {
38+
throw new RuntimeException("Ooops in createAcount");
39+
}
40+
41+
Thread.sleep(1000);
42+
SysOutUtils.sysout("Finished createAcount: " + nameFirstname.toString());
43+
} catch (InterruptedException e) {
44+
SysOutUtils.sysout("Interrupted (=cancelled) -> good!");
45+
}
46+
});
47+
}
48+
49+
public Single<FinishedIndicator> sendEmail(NameFirstname nameFirstname) {
50+
return AsyncUtils.<FinishedIndicator>executeAsync(() -> {
51+
try {
52+
SysOutUtils.sysout("Processing sendEmail: " + nameFirstname.toString());
53+
54+
if (failToken.incrementAndGet() % 3 == 0) {
55+
throw new RuntimeException("Ooops in sendEmail");
56+
}
57+
58+
Thread.sleep(1500);
59+
SysOutUtils.sysout("Finished sendEmail: " + nameFirstname.toString());
60+
} catch (InterruptedException e) {
61+
SysOutUtils.sysout("Interrupted (=cancelled) -> good!");
62+
}
63+
});
64+
}
65+
66+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/**
2+
* Copyright 2015 Peti Koch
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 ch.petikoch.examples.mvvm_rxjava.example6a;
17+
18+
import ch.petikoch.examples.mvvm_rxjava.rxjava_mvvm.IView;
19+
import ch.petikoch.examples.mvvm_rxjava.widgets.StrictThreadingJButton;
20+
import ch.petikoch.examples.mvvm_rxjava.widgets.StrictThreadingJFrame;
21+
import ch.petikoch.examples.mvvm_rxjava.widgets.StrictThreadingJLabel;
22+
import ch.petikoch.examples.mvvm_rxjava.widgets.StrictThreadingJTextField;
23+
24+
import java.awt.*;
25+
import java.lang.management.ManagementFactory;
26+
27+
import static ch.petikoch.examples.mvvm_rxjava.rxjava_mvvm.RxSwingView2ViewModelBinder.bindSwingView;
28+
import static ch.petikoch.examples.mvvm_rxjava.rxjava_mvvm.RxViewModel2SwingViewBinder.*;
29+
30+
class Example_6a_View extends StrictThreadingJFrame implements IView<Example_6a_ViewModel> {
31+
32+
private final StrictThreadingJTextField nameTextField;
33+
private final StrictThreadingJTextField firstnameTextField;
34+
private final StrictThreadingJButton submitButton;
35+
private final StrictThreadingJButton cancelButton;
36+
private StrictThreadingJLabel resultat1Label;
37+
private StrictThreadingJLabel resultat2Label;
38+
39+
@Override
40+
public void bind(final Example_6a_ViewModel viewModel) {
41+
bindSwingView(nameTextField).toViewModel(viewModel.v2vm_name);
42+
bindViewModelBoolean(viewModel.vm2v_nameEnabled).toSwingViewEnabledPropertyOf(nameTextField);
43+
44+
bindSwingView(firstnameTextField).toViewModel(viewModel.v2vm_firstname);
45+
bindViewModelBoolean(viewModel.vm2v_firstnameEnabled).toSwingViewEnabledPropertyOf(firstnameTextField);
46+
47+
bindSwingView(submitButton).toViewModel(viewModel.v2vm_submitButtonEvents);
48+
bindViewModelBoolean(viewModel.vm2v_submitButtonEnabled).toSwingViewEnabledPropertyOf(submitButton);
49+
50+
bindSwingView(cancelButton).toViewModel(viewModel.v2vm_cancelButtonEvents);
51+
bindViewModelBoolean(viewModel.vm2v_cancelButtonEnabled).toSwingViewEnabledPropertyOf(cancelButton);
52+
53+
bindViewModelString(viewModel.vm2v_result1).toSwingViewLabel(resultat1Label);
54+
bindViewModel(viewModel.vm2v_result1Color).toAction(color -> resultat1Label.setForeground(color));
55+
bindViewModelString(viewModel.vm2v_result2).toSwingViewLabel(resultat2Label);
56+
bindViewModel(viewModel.vm2v_result2Color).toAction(color -> resultat2Label.setForeground(color));
57+
}
58+
59+
public Example_6a_View() {
60+
super();
61+
setTitle(getClass().getSimpleName() + " " + ManagementFactory.getRuntimeMXBean().getName());
62+
63+
setBounds(100, 100, 450, 300);
64+
setDefaultCloseOperation(StrictThreadingJFrame.EXIT_ON_CLOSE);
65+
GridBagLayout gridBagLayout = new GridBagLayout();
66+
gridBagLayout.columnWidths = new int[]{0, 0, 0, 0, 0};
67+
gridBagLayout.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0};
68+
gridBagLayout.columnWeights = new double[]{0.0, 1.0, 0.0, 0.0, Double.MIN_VALUE};
69+
gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 1.0, 0.0, 0.0, Double.MIN_VALUE};
70+
getContentPane().setLayout(gridBagLayout);
71+
72+
StrictThreadingJLabel nameLabel = new StrictThreadingJLabel("Name");
73+
GridBagConstraints gbc_nameLabel = new GridBagConstraints();
74+
gbc_nameLabel.insets = new Insets(5, 5, 5, 5);
75+
gbc_nameLabel.anchor = GridBagConstraints.WEST;
76+
gbc_nameLabel.gridx = 0;
77+
gbc_nameLabel.gridy = 0;
78+
getContentPane().add(nameLabel, gbc_nameLabel);
79+
80+
nameTextField = new StrictThreadingJTextField();
81+
GridBagConstraints gbc_nameTextField = new GridBagConstraints();
82+
gbc_nameTextField.gridwidth = 3;
83+
gbc_nameTextField.insets = new Insets(5, 0, 5, 5);
84+
gbc_nameTextField.fill = GridBagConstraints.HORIZONTAL;
85+
gbc_nameTextField.gridx = 1;
86+
gbc_nameTextField.gridy = 0;
87+
getContentPane().add(nameTextField, gbc_nameTextField);
88+
nameTextField.setColumns(10);
89+
90+
StrictThreadingJLabel firstNameLabel = new StrictThreadingJLabel("Firstname");
91+
GridBagConstraints gbc_firstNameLabel = new GridBagConstraints();
92+
gbc_firstNameLabel.anchor = GridBagConstraints.WEST;
93+
gbc_firstNameLabel.insets = new Insets(0, 5, 5, 5);
94+
gbc_firstNameLabel.gridx = 0;
95+
gbc_firstNameLabel.gridy = 1;
96+
getContentPane().add(firstNameLabel, gbc_firstNameLabel);
97+
98+
firstnameTextField = new StrictThreadingJTextField();
99+
GridBagConstraints gbc_firstNameTextField = new GridBagConstraints();
100+
gbc_firstNameTextField.gridwidth = 3;
101+
gbc_firstNameTextField.insets = new Insets(0, 0, 5, 5);
102+
gbc_firstNameTextField.fill = GridBagConstraints.HORIZONTAL;
103+
gbc_firstNameTextField.gridx = 1;
104+
gbc_firstNameTextField.gridy = 1;
105+
getContentPane().add(firstnameTextField, gbc_firstNameTextField);
106+
firstnameTextField.setColumns(10);
107+
108+
submitButton = new StrictThreadingJButton("Submit");
109+
GridBagConstraints gbc_submitButton = new GridBagConstraints();
110+
gbc_submitButton.insets = new Insets(0, 0, 5, 5);
111+
gbc_submitButton.anchor = GridBagConstraints.EAST;
112+
gbc_submitButton.gridx = 2;
113+
gbc_submitButton.gridy = 2;
114+
getContentPane().add(submitButton, gbc_submitButton);
115+
116+
cancelButton = new StrictThreadingJButton("Cancel");
117+
GridBagConstraints gbc_cancelButton = new GridBagConstraints();
118+
gbc_cancelButton.insets = new Insets(0, 0, 5, 5);
119+
gbc_cancelButton.anchor = GridBagConstraints.EAST;
120+
gbc_cancelButton.gridx = 3;
121+
gbc_cancelButton.gridy = 2;
122+
getContentPane().add(cancelButton, gbc_cancelButton);
123+
124+
getRootPane().setDefaultButton(submitButton);
125+
126+
resultat1Label = new StrictThreadingJLabel("Ready");
127+
resultat1Label.setFont(new Font("Tahoma", Font.BOLD, 11));
128+
GridBagConstraints gbc_resultat1Label = new GridBagConstraints();
129+
gbc_resultat1Label.anchor = GridBagConstraints.WEST;
130+
gbc_resultat1Label.fill = GridBagConstraints.BOTH;
131+
gbc_resultat1Label.gridwidth = 4;
132+
gbc_resultat1Label.insets = new Insets(0, 5, 5, 5);
133+
gbc_resultat1Label.gridx = 0;
134+
gbc_resultat1Label.gridy = 4;
135+
getContentPane().add(resultat1Label, gbc_resultat1Label);
136+
137+
resultat2Label = new StrictThreadingJLabel("Ready, too");
138+
resultat2Label.setFont(new Font("Tahoma", Font.BOLD, 11));
139+
GridBagConstraints gbc_resultat2Label = new GridBagConstraints();
140+
gbc_resultat2Label.fill = GridBagConstraints.BOTH;
141+
gbc_resultat2Label.anchor = GridBagConstraints.WEST;
142+
gbc_resultat2Label.gridwidth = 4;
143+
gbc_resultat2Label.insets = new Insets(0, 5, 5, 5);
144+
gbc_resultat2Label.gridx = 0;
145+
gbc_resultat2Label.gridy = 5;
146+
getContentPane().add(resultat2Label, gbc_resultat2Label);
147+
}
148+
}

0 commit comments

Comments
 (0)