2017-08-14 5 views
1

私は次のパターン一般化したいと思います:のJavaFX:エラー・ログ記録のChangeListener

errorLoggingSetChangeListener = c -> { 
    // do something dangerous 
}; 

私はこのことについて考えていた:

setChangeListener = c -> { 
    try { 
    // do something dangerous 
    } catch (final IOException e) { 
    logger.error(e.getLocalizedMessage(), e); 
    } 
}; 

を私はこのようにそれを使用したいと思います

public class ErrorLoggingSetChangeListener<T> implements SetChangeListener<T> { 
    private static final Logger logger = Logger.getLogger(ErrorLoggingSetChangeListener.class); 
    private final SetChangeListener<T> delegate; 

    @Override 
    public void onChanged(final SetChangeListener.Change<? extends T> change) { 
    try { 
     delegate.onChanged(change); 
    } catch (final Exception e) { 
     if (logger.isEnabledFor(Level.ERROR)) { 
     logger.error(e.getLocalizedMessage(), e); 
     } 
    } 
    } 

    public ErrorLoggingSetChangeListener(final SetChangeListener<T> delegate) { 
    super(); 
    this.delegate = delegate; 
    } 
} 

ErrorLoggingSetChangeListenerはFunctionalインターフェイスではないので、これは不可能です。

このクラスを機能インターフェイスに変換する機会はありますか?

これはコンパイルされない:

public interface ErrorLoggingSetChangeListener<T> extends SetChangeListener<T> { 

    static final Logger logger = Logger.getLogger(ErrorLoggingSetChangeListener.class); 

    @Override 
    default void onChanged(final SetChangeListener.Change<? extends T> change) { 
    try { 
     SetChangeListener.super.onChanged(change); 
    } catch (final Exception e) { 
     if (logger.isEnabledFor(Level.ERROR)) { 
     logger.error(e.getLocalizedMessage(), e); 
     } 
    } 
    } 
} 

をこれもコンパイルされない:

errorLoggingSetChangeListener = new ErrorLoggingSetChangeListener<>(c -> { 
     throw new IOException(); 
    }); 

をエラーメッセージが

未処理の例外である[..]

ここ
+0

これは意味がありませんが、実装されていない関数を呼び出そうとします。あなたがそれを上書きするので、スーパーの機能は実装されていません。インターフェイスには1つの機能しか提供しませんが、2回使用するようにしてください。 – JohnnyAW

+0

@JohnnyAWが同意しました。これを修正するには? – kerner1000

+0

あなたはそれを使いたいと思う方法はありません(少なくともJavaでは、おそらく他の言語がそれを行うことができます)。あなたは 'ErrorLoggingSetChangeListener'を使用して、 – JohnnyAW

答えて

1

でそれをラップすることができ、何かを投げることができる新しいインターフェースを必要としません単一のインターフェイスへのクラス:

import javafx.collections.FXCollections; 
import javafx.collections.ObservableSet; 

public class Test { 

    public static void main(String[] args) { 
     ObservableSet<String> set = FXCollections.observableSet(); 
     ErrorLoggingSetChangeListener<String> listener = c -> { 
      if (c.wasAdded()) { 
       int i = Integer.parseInt(c.getElementAdded()); 
       System.out.println("Value added: "+i); 
      } 
     }; 
     set.addListener(listener); 

     set.add("42"); 
     set.add("What do you get when you multiply 6 by 9?"); 
    } 

} 

予想される出力を生成します:ここに

import javafx.collections.SetChangeListener; 

@FunctionalInterface 
public interface ErrorLoggingSetChangeListener<E> extends SetChangeListener<E> { 


    public void delegate(Change<? extends E> change) throws Exception ; 

    @Override 
    public default void onChanged(Change<? extends E> change) { 
     try { 
      delegate(change); 
     } catch (Exception exc) { 
      // just do a System.out.println here to demo we reach this block: 
      System.out.println("Custom error handling..."); 
      exc.printStackTrace(); 
     } 
    } 
} 

そして、これを使用してのデモです

Value added: 42 
Custom error handling... 
java.lang.NumberFormatException: For input string: "What do you get when you multiply 6 by 9?" 
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) 
    at java.lang.Integer.parseInt(Integer.java:580) 
    at java.lang.Integer.parseInt(Integer.java:615) 
    at Test.lambda$0(Test.java:10) 
    at ErrorLoggingSetChangeListener.onChanged(ErrorLoggingSetChangeListener.java:12) 
    at com.sun.javafx.collections.SetListenerHelper$SingleChange.fireValueChangedEvent(SetListenerHelper.java:163) 
    at com.sun.javafx.collections.SetListenerHelper.fireValueChangedEvent(SetListenerHelper.java:72) 
    at com.sun.javafx.collections.ObservableSetWrapper.callObservers(ObservableSetWrapper.java:128) 
    at com.sun.javafx.collections.ObservableSetWrapper.add(ObservableSetWrapper.java:269) 
    at Test.main(Test.java:17) 
+0

'DangerousInterface'は' SetChangeListener.Change'に依存していますが、Setや 'SetChangeListener'には一般的には接続されていないようです。これは完全にきれいに見える、ありがとう! – kerner1000

1

をコンパイルすることを、私の実装です:

ErrorLoggingSetChangeListener:

import javafx.collections.SetChangeListener; 

public class ErrorLoggingSetChangeListener<T> implements SetChangeListener<T> { 

    private DangerousInterface<T> delegate; 

    public ErrorLoggingSetChangeListener(DangerousInterface<T> delegate) { 
     super(); 
     this.delegate = delegate; 
    } 

    @Override 
    public void onChanged(Change<? extends T> change) { 
     try { 
      this.delegate.delegate(change); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

} 

DangerousInterface:

public interface DangerousInterface<T> { 

    public void delegate(Change<? extends T> change) throws Exception; 
} 

メイン:

SetChangeListener<String> listener = new ErrorLoggingSetChangeListener<>((test) -> { 
     //no errors here now 
     throw new Exception(); 
    }); 

私はdefinitelを得ましたYなしコンパイルエラー

EDIT:[OK]を、私は問題を抱えて、あなたが実際に今、あなたはこれがJonnyAWのソリューション@に似ていますが、両方兼ね備えonChanged

+0

独自の型 'SetChangeListener'を宣言しました。 'javafx.collections.SetChangeListener'を使ってみましょう。 – kerner1000

+0

これは違いはありませんが、悪い試して、もう一度待ちます – JohnnyAW

+0

違いは、このonChangeメソッドは例外をスローしません;) – kerner1000

関連する問題