Skip to content

Commit 862bd41

Browse files
committed
added example 7a
1 parent 5c78fbc commit 862bd41

File tree

6 files changed

+246
-0
lines changed

6 files changed

+246
-0
lines changed

README.adoc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,22 @@ Tests:
249249

250250
link:./src/test/groovy/ch/petikoch/examples/mvvm_rxjava/example7[]
251251

252+
253+
=== Example 7a: Log table with LogRow's pushed up from the Model and exception handling
254+
255+
link:./src/main/java/ch/petikoch/examples/mvvm_rxjava/example7a[]
256+
257+
* Same as example 7
258+
* But: The model's log Observable sometimes fail
259+
* We add some exception handling into the viewmodel, to keey the view alive
260+
261+
image::example7a.png[]
262+
263+
Tests:
264+
265+
link:./src/test/groovy/ch/petikoch/examples/mvvm_rxjava/example7a[]
266+
267+
252268
=== Example 8: Log table with LogRow's pushed up from the Model and dealing with backpressure
253269

254270
link:./src/main/java/ch/petikoch/examples/mvvm_rxjava/example8[]

docs/example7a.png

221 KB
Loading
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Copyright (c) 2015-2016 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.example7a;
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_7a_Main {
26+
27+
public static void main(String[] args) {
28+
SysOutUtils.sysout(ManagementFactory.getRuntimeMXBean().getName());
29+
UncaughtExceptionHandlerInitializer.initUncaughtExceptionHandler();
30+
31+
Example_7a_Model model = new Example_7a_Model();
32+
Example_7a_ViewModel viewModel = new Example_7a_ViewModel();
33+
viewModel.connectTo(model);
34+
35+
SwingUtilities2.invokeLater(() -> {
36+
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
37+
Example_7a_View view = new Example_7a_View();
38+
view.bind(viewModel);
39+
view.setVisible(true);
40+
});
41+
}
42+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Copyright (c) 2015-2016 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.example7a;
17+
18+
import ch.petikoch.examples.mvvm_rxjava.datatypes.LogRow;
19+
import ch.petikoch.examples.mvvm_rxjava.utils.SysOutUtils;
20+
import rx.Observable;
21+
22+
import java.time.LocalDateTime;
23+
import java.time.format.DateTimeFormatter;
24+
import java.util.concurrent.ThreadLocalRandom;
25+
import java.util.concurrent.TimeUnit;
26+
27+
class Example_7a_Model {
28+
29+
public Observable<LogRow> getLogs() {
30+
return Observable.interval(1, TimeUnit.SECONDS)
31+
.map(incrementingNumber -> new LogRow(
32+
DateTimeFormatter.ISO_DATE_TIME.format(LocalDateTime.now()),
33+
"Status " + Integer.toString(ThreadLocalRandom.current().nextInt(1, 5)),
34+
"Action " + incrementingNumber + " from " + Thread.currentThread().getName()))
35+
.map(logRow -> {
36+
if (ThreadLocalRandom.current().nextInt(5) == 0) {
37+
// occasionally happens something unexpected...
38+
throw new RuntimeException("This is totally unexpected...");
39+
} else {
40+
return logRow;
41+
}
42+
})
43+
.doOnNext(text -> SysOutUtils.sysout("Sending: " + text));
44+
}
45+
46+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/**
2+
* Copyright (c) 2015-2016 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.example7a;
17+
18+
import ch.petikoch.examples.mvvm_rxjava.datatypes.LogRow;
19+
import ch.petikoch.examples.mvvm_rxjava.rxjava_mvvm.IView;
20+
import ch.petikoch.examples.mvvm_rxjava.utils.GuiPreconditions;
21+
import ch.petikoch.examples.mvvm_rxjava.widgets.StrictThreadingJFrame;
22+
import com.google.common.collect.Lists;
23+
import org.jdesktop.swingx.JXTable;
24+
import org.jdesktop.swingx.decorator.HighlighterFactory;
25+
import org.jdesktop.swingx.table.TableUtilities;
26+
27+
import javax.swing.*;
28+
import javax.swing.event.TableModelEvent;
29+
import javax.swing.event.TableModelListener;
30+
import javax.swing.table.DefaultTableModel;
31+
import java.awt.*;
32+
import java.lang.management.ManagementFactory;
33+
import java.util.Vector;
34+
35+
import static ch.petikoch.examples.mvvm_rxjava.rxjava_mvvm.RxViewModel2SwingViewBinder.bindViewModel;
36+
37+
class Example_7a_View extends StrictThreadingJFrame implements IView<Example_7a_ViewModel> {
38+
39+
private final MyTableModel myTableModel = new MyTableModel();
40+
41+
@Override
42+
public void bind(final Example_7a_ViewModel viewModel) {
43+
bindViewModel(viewModel.vm2v_log).toAction(myTableModel::addRow);
44+
}
45+
46+
public Example_7a_View() {
47+
super();
48+
setTitle(getClass().getSimpleName() + " " + ManagementFactory.getRuntimeMXBean().getName());
49+
50+
setBounds(100, 100, 700, 500);
51+
setDefaultCloseOperation(StrictThreadingJFrame.EXIT_ON_CLOSE);
52+
getContentPane().setLayout(new BorderLayout(0, 0));
53+
54+
final JXTable table = new JXTable(myTableModel);
55+
table.setHighlighters(HighlighterFactory.createSimpleStriping());
56+
table.setSortable(false);
57+
table.getTableHeader().setReorderingAllowed(false);
58+
59+
myTableModel.addTableModelListener(new TableModelListener() {
60+
61+
int lastRowCountScrolledTo = -1;
62+
63+
@Override
64+
public void tableChanged(final TableModelEvent e) {
65+
if (TableUtilities.isInsert(e)) {
66+
final int currentRowCount = myTableModel.getRowCount();
67+
if (currentRowCount != lastRowCountScrolledTo) {
68+
lastRowCountScrolledTo = currentRowCount;
69+
SwingUtilities.invokeLater(() -> table.scrollRectToVisible(table.getCellRect(myTableModel.getRowCount() - 1, 0, false)));
70+
}
71+
}
72+
}
73+
});
74+
75+
JScrollPane scrollPane = new JScrollPane(table);
76+
getContentPane().add(scrollPane, BorderLayout.CENTER);
77+
}
78+
79+
private static class MyTableModel extends DefaultTableModel {
80+
81+
public MyTableModel() {
82+
super(new Vector<>(Lists.newArrayList("Timestamp", "Status", "Text")), 0);
83+
GuiPreconditions.assertOnAwtEdt();
84+
}
85+
86+
public void addRow(LogRow logRow) {
87+
GuiPreconditions.assertOnAwtEdt();
88+
addRow(new Object[]{logRow.getTimestamp(), logRow.getStatus(), logRow.getText()});
89+
}
90+
91+
@Override
92+
public boolean isCellEditable(final int row, final int column) {
93+
GuiPreconditions.assertOnAwtEdt();
94+
return false;
95+
}
96+
}
97+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* Copyright (c) 2015-2016 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.example7a;
17+
18+
import ch.petikoch.examples.mvvm_rxjava.datatypes.LogRow;
19+
import ch.petikoch.examples.mvvm_rxjava.rxjava_mvvm.IViewModel;
20+
import net.jcip.annotations.ThreadSafe;
21+
import rx.subjects.BehaviorSubject;
22+
23+
@ThreadSafe
24+
class Example_7a_ViewModel implements IViewModel<Example_7a_Model> {
25+
26+
public final BehaviorSubject<LogRow> vm2v_log = BehaviorSubject.create();
27+
28+
public Example_7a_ViewModel() {
29+
wireInternally();
30+
}
31+
32+
private void wireInternally() {
33+
// NO-OP
34+
}
35+
36+
@Override
37+
public void connectTo(final Example_7a_Model model) {
38+
model.getLogs()
39+
.doOnError(throwable -> vm2v_log.onNext(new LogRow("!", "Unexpected error -> will retry here in ViewModel", "Error: " + throwable.getMessage())))
40+
.retry(5)
41+
.onErrorReturn(throwable -> new LogRow("!!!", "Too many unexpected errors -> stop", "Error: " + throwable.getMessage()))
42+
.subscribe(vm2v_log);
43+
}
44+
45+
}

0 commit comments

Comments
 (0)