Skip to content

Commit

Permalink
added default error handling in SButton.onAction
Browse files Browse the repository at this point in the history
  • Loading branch information
tbee committed Mar 1, 2023
1 parent e788c21 commit 861587a
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 18 deletions.
58 changes: 53 additions & 5 deletions src/main/java/org/tbee/sway/SButton.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package org.tbee.sway;

import org.tbee.sway.support.HAlign;
import org.tbee.sway.support.VAlign;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import java.awt.Insets;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;

import org.tbee.sway.binding.ExceptionHandler;
import org.tbee.sway.support.HAlign;
import org.tbee.sway.support.VAlign;
import org.tbee.util.ExceptionUtil;

public class SButton extends JButton {
final static private org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(SButton.class);

public SButton() {
}
Expand All @@ -31,7 +37,7 @@ public SButton(String text, Icon icon) {
}

// ==============================================
// JavaBaan
// JavaBean

/**
* Enum variant of HorizontalAlignment
Expand Down Expand Up @@ -69,6 +75,48 @@ public SButton VAlign(VAlign v) {
}
final static public String VALIGN = "vAlign";

// ==============================================
// ExceptionHandler

/**
* Set the ExceptionHandler used a.o. when the actionListeners are called.
* @param v
*/
public void setExceptionHandler(ExceptionHandler v) {
firePropertyChange(EXCEPTIONHANDLER, exceptionHandler, exceptionHandler = v);
}
public ExceptionHandler getExceptionHandler() {
return exceptionHandler;
}
public SButton exceptionHandler(ExceptionHandler v) {
setExceptionHandler(v);
return this;
}
final static public String EXCEPTIONHANDLER = "exceptionHandler";
ExceptionHandler exceptionHandler = this::handleException;

private boolean handleException(Throwable e, Object oldValue, Object newValue) {

if (LOGGER.isDebugEnabled()) LOGGER.debug(e.getMessage(), e);
JOptionPane.showMessageDialog(this, ExceptionUtil.determineMessage(e), "ERROR", JOptionPane.ERROR_MESSAGE);

// Mark exception as handled
return true;
}

@Override
protected void fireActionPerformed(ActionEvent event) {
try {
super.fireActionPerformed(event);
}
catch (Throwable t) {
if (exceptionHandler != null && exceptionHandler.handle(t, null, null)) {
return;
}
throw t;
}
}

// ==============================================
// FLUENT API

Expand Down
30 changes: 24 additions & 6 deletions src/main/java/org/tbee/sway/STextField.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.tbee.sway.binding.BeanBinder;
import org.tbee.sway.binding.BindUtil;
import org.tbee.sway.binding.Binding;
import org.tbee.sway.binding.ExceptionHandler;
import org.tbee.sway.format.Format;
import org.tbee.sway.format.FormatRegistry;
import org.tbee.sway.format.JavaFormat;
Expand Down Expand Up @@ -104,7 +105,7 @@
* @param <T> the type of value the textfield holds.
*/
public class STextField<T> extends javax.swing.JTextField {
static private org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(STextField.class);
final static private org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(STextField.class);

final private Format<T> format;

Expand Down Expand Up @@ -288,10 +289,27 @@ public boolean setValueFromText() {
return true;
}

protected boolean handleException(Throwable e, Object oldValue, Object newValue) {
/**
* Set the ExceptionHandler used a.o. in binding
* @param v
*/
public void setExceptionHandler(ExceptionHandler v) {
firePropertyChange(EXCEPTIONHANDLER, exceptionHandler, exceptionHandler = v);
}
public ExceptionHandler getExceptionHandler() {
return exceptionHandler;
}
public STextField<T> exceptionHandler(ExceptionHandler v) {
setExceptionHandler(v);
return this;
}
final static public String EXCEPTIONHANDLER = "exceptionHandler";
ExceptionHandler exceptionHandler = this::handleException;

private boolean handleException(Throwable e, Object oldValue, Object newValue) {
return handleException(e);
}
protected boolean handleException(Throwable e) {
private boolean handleException(Throwable e) {
if (handlingExceptionCnt > 0) {
return false;
}
Expand All @@ -303,7 +321,7 @@ protected boolean handleException(Throwable e) {
SwingUtilities.invokeLater(() -> this.grabFocus());

// Display the error
if (logger.isDebugEnabled()) logger.debug(e.getMessage(), e);
if (LOGGER.isDebugEnabled()) LOGGER.debug(e.getMessage(), e);
JOptionPane.showMessageDialog(this, ExceptionUtil.determineMessage(e), "ERROR", JOptionPane.ERROR_MESSAGE);

// Mark exception as handled
Expand Down Expand Up @@ -413,7 +431,7 @@ public STextField<T> editable(boolean enabled) {
* @return Binding, so unbind() can be called
*/
public Binding binding(Object bean, String propertyName) {
return BindUtil.bind(this, VALUE, bean, propertyName, this::handleException);
return BindUtil.bind(this, VALUE, bean, propertyName, exceptionHandler);
}

/**
Expand All @@ -438,7 +456,7 @@ public STextField<T> bind(Object bean, String propertyName) {
* @return Binding, so unbind() can be called
*/
public Binding binding(BeanBinder<?> beanBinder, String propertyName) {
return BindUtil.bind(this, VALUE, beanBinder, propertyName, this::handleException);
return BindUtil.bind(this, VALUE, beanBinder, propertyName, exceptionHandler);
}

/**
Expand Down
12 changes: 5 additions & 7 deletions src/main/java/org/tbee/sway/binding/ExceptionCatcher.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package org.tbee.sway.binding;

import com.jgoodies.binding.beans.PropertyAdapter;
import org.tbee.util.AbstractBean;
import org.tbee.util.ExceptionUtil;

import com.jgoodies.binding.beans.PropertyAdapter;

/**
* Catches any exception and forwards them to the exception handler
*/
Expand All @@ -29,13 +30,10 @@ public void setValue(Object v) {
}
catch (RuntimeException e) {
Throwable ultimateCause = ExceptionUtil.findUltimateCause(e);
if (handler != null) {
boolean handled = handler.handle(ultimateCause, oldValue, v);
if (handled) {
return;
}
if (handler != null && handler.handle(ultimateCause, oldValue, v)) {
return;
}
throw e; // TBEERNOT: check if this exception is swalled, if so log it
throw e;
}
}
public Object getValue() {
Expand Down
32 changes: 32 additions & 0 deletions src/test/java/org/tbee/sway/SButtonTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.tbee.sway;

import org.assertj.swing.finder.JOptionPaneFinder;
import org.assertj.swing.fixture.JOptionPaneFixture;
import org.junit.jupiter.api.Test;

public class SButtonTest extends TestBase {

SButton sButton;

@Test
public void happyTest() throws Exception {

// GIVEN
construct(() -> {
sButton = new SButton("test") //
.onAction(e -> {
throw new RuntimeException("oops");
}) //
.name("sButton");
return TestUtil.inJFrame(sButton, focusMeComponent());
});

// WHEN
frameFixture.button("sButton").click();

// THEN
JOptionPaneFixture optionPaneFixture = JOptionPaneFinder.findOptionPane().using(frameFixture.robot());
optionPaneFixture.requireErrorMessage().requireMessage("oops");
optionPaneFixture.okButton().click();
}
}

0 comments on commit 861587a

Please sign in to comment.