Avoid unchecked casts/assignments/calls (#3626)

* Don't extend ActivatableViewAndModel when the model is empty

Remove the no-arg constructor from ActivatableViewAndModel, which sets
a dummy Activatable singleton as the model. (Since the model type param
can't be checked at runtime, improper use of the constructor could cause
heap pollution.)

Instead, extend 'ActivatableView<R, Void>' consistently, as other views
without a model currently do.

* Improve type safety of the fluent interface of Overlay<T>

Refactor all the unchecked casts from Overlay<T> to T into a single
private cast() method. Also add a runtime type check to the constructor
to prevent creation of window objects of the form "A extends Overlay<B>"
for unrelated A & B, as such casts would then subvert the type system.

* Improve type safety of ProtoUtil.collectionToProto(Collection)

Add a Class<T> parameter to the method, in order to avoid an unchecked
cast to the Message type T. The cast was wrapped in a try-catch block,
which is useless due to erasure, so use Class.cast(..) instead.

* Avoid raw types to prevent unchecked casts in Log.java

Add missing ILoggingEvent type arg to local variable declarations.

* Avoid unchecked casts when deserializing JSON using Gson

* Fix unchecked casts in views due to raw chart point types

Add missing 'Number' coord type args to some XYChart.(Data|Series) &
AreaChart declarations, and avoid passing them as generic varargs, in
order to eliminate some more unchecked cast warnings.

Also simplify OfferBookChartView.updateChartData() by unboxing the x-
coordinate of each (buy & sell) datapoint.

* Avoid raw type bounds in class declarations to fix unchecked warnings

Make sure the generic classes MutableOfferView & AgentRegistrationView
don't use raw bounds for their associated view models, as that leads to
unchecked assignments from the model fields further down.

* Fix some remaining suppressed unchecked casts in the UI logic

(This still leaves a few more which are hard to avoid.)

* Fix a few remaining unsuppressed unchecked warnings
This commit is contained in:
Christoph Atteneder 2019-11-18 15:41:23 +01:00 committed by GitHub
commit ec5e2b76d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 239 additions and 253 deletions

View File

@ -23,6 +23,7 @@ import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder; import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy; import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
import ch.qos.logback.core.rolling.RollingFileAppender; import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy; import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
@ -38,7 +39,7 @@ public class Log {
public static void setup(String fileName) { public static void setup(String fileName) {
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
RollingFileAppender appender = new RollingFileAppender(); RollingFileAppender<ILoggingEvent> appender = new RollingFileAppender<>();
appender.setContext(loggerContext); appender.setContext(loggerContext);
appender.setFile(fileName + ".log"); appender.setFile(fileName + ".log");
@ -50,7 +51,7 @@ public class Log {
rollingPolicy.setMaxIndex(10); rollingPolicy.setMaxIndex(10);
rollingPolicy.start(); rollingPolicy.start();
SizeBasedTriggeringPolicy triggeringPolicy = new SizeBasedTriggeringPolicy(); SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = new SizeBasedTriggeringPolicy<>();
triggeringPolicy.setMaxFileSize(FileSize.valueOf("10MB")); triggeringPolicy.setMaxFileSize(FileSize.valueOf("10MB"));
triggeringPolicy.start(); triggeringPolicy.start();
@ -59,15 +60,12 @@ public class Log {
encoder.setPattern("%d{MMM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{15}: %msg %xEx%n"); encoder.setPattern("%d{MMM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{15}: %msg %xEx%n");
encoder.start(); encoder.start();
//noinspection unchecked
appender.setEncoder(encoder); appender.setEncoder(encoder);
appender.setRollingPolicy(rollingPolicy); appender.setRollingPolicy(rollingPolicy);
//noinspection unchecked
appender.setTriggeringPolicy(triggeringPolicy); appender.setTriggeringPolicy(triggeringPolicy);
appender.start(); appender.start();
logbackLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); logbackLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
//noinspection unchecked
logbackLogger.addAppender(appender); logbackLogger.addAppender(appender);
logbackLogger.setLevel(Level.INFO); logbackLogger.setLevel(Level.INFO);

View File

@ -77,15 +77,14 @@ public class ProtoUtil {
return result; return result;
} }
public static <T extends Message> Iterable<T> collectionToProto(Collection<? extends Proto> collection) { public static <T extends Message> Iterable<T> collectionToProto(Collection<? extends Proto> collection, Class<T> messageType) {
return collection.stream() return collection.stream()
.map(e -> { .map(e -> {
final Message message = e.toProtoMessage(); final Message message = e.toProtoMessage();
try { try {
//noinspection unchecked return messageType.cast(message);
return (T) message; } catch (ClassCastException t) {
} catch (Throwable t) { log.error("Message could not be cast. message={}, messageType={}", message, messageType);
log.error("message could not be casted. message=" + message);
return null; return null;
} }
}) })

View File

@ -361,11 +361,11 @@ public class BisqEnvironment extends StandardEnvironment {
return new ResourcePropertySource(BISQ_APP_DIR_PROPERTY_SOURCE_NAME, resource); return new ResourcePropertySource(BISQ_APP_DIR_PROPERTY_SOURCE_NAME, resource);
} }
private String getProperty (PropertySource properties, String propertyKey, String defaultValue) { private String getProperty(PropertySource properties, String propertyKey, String defaultValue) {
return properties.containsProperty(propertyKey) ? (String) properties.getProperty(propertyKey) : defaultValue; return properties.containsProperty(propertyKey) ? (String) properties.getProperty(propertyKey) : defaultValue;
} }
private List<String> getListProperty (String key, List defaultValue) { private List<String> getListProperty(String key, List<String> defaultValue) {
final String value = getProperty(key, ""); final String value = getProperty(key, "");
return value.isEmpty() ? defaultValue : Arrays.asList(StringUtils.deleteWhitespace(value).split(",")); return value.isEmpty() ? defaultValue : Arrays.asList(StringUtils.deleteWhitespace(value).split(","));
} }

View File

@ -55,6 +55,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.AbstractIdleService; import com.google.common.util.concurrent.AbstractIdleService;
import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -465,7 +466,7 @@ public class WalletConfig extends AbstractIdleService {
vPeerGroup.startBlockChainDownload(listener); vPeerGroup.startBlockChainDownload(listener);
listener.await(); listener.await();
} else { } else {
Futures.addCallback(vPeerGroup.startAsync(), new FutureCallback() { Futures.addCallback((ListenableFuture<?>) vPeerGroup.startAsync(), new FutureCallback<Object>() {
@Override @Override
public void onSuccess(@Nullable Object result) { public void onSuccess(@Nullable Object result) {
final PeerDataEventListener listener = downloadListener == null ? final PeerDataEventListener listener = downloadListener == null ?
@ -476,7 +477,6 @@ public class WalletConfig extends AbstractIdleService {
@Override @Override
public void onFailure(@NotNull Throwable t) { public void onFailure(@NotNull Throwable t) {
throw new RuntimeException(t); throw new RuntimeException(t);
} }
}); });
} }

View File

@ -91,7 +91,7 @@ public abstract class PaymentAccount implements PersistablePayload {
.setCreationDate(creationDate) .setCreationDate(creationDate)
.setPaymentAccountPayload((protobuf.PaymentAccountPayload) paymentAccountPayload.toProtoMessage()) .setPaymentAccountPayload((protobuf.PaymentAccountPayload) paymentAccountPayload.toProtoMessage())
.setAccountName(accountName) .setAccountName(accountName)
.addAllTradeCurrencies(ProtoUtil.<protobuf.TradeCurrency>collectionToProto(tradeCurrencies)); .addAllTradeCurrencies(ProtoUtil.collectionToProto(tradeCurrencies, protobuf.TradeCurrency.class));
Optional.ofNullable(selectedTradeCurrency).ifPresent(selectedTradeCurrency -> builder.setSelectedTradeCurrency((protobuf.TradeCurrency) selectedTradeCurrency.toProtoMessage())); Optional.ofNullable(selectedTradeCurrency).ifPresent(selectedTradeCurrency -> builder.setSelectedTradeCurrency((protobuf.TradeCurrency) selectedTradeCurrency.toProtoMessage()));
return builder.build(); return builder.build();
} }

View File

@ -47,16 +47,15 @@ public class FeeProvider extends HttpClientProvider {
public Tuple2<Map<String, Long>, Map<String, Long>> getFees() throws IOException { public Tuple2<Map<String, Long>, Map<String, Long>> getFees() throws IOException {
String json = httpClient.requestWithGET("getFees", "User-Agent", "bisq/" + Version.VERSION + ", uid:" + httpClient.getUid()); String json = httpClient.requestWithGET("getFees", "User-Agent", "bisq/" + Version.VERSION + ", uid:" + httpClient.getUid());
LinkedTreeMap<String, Object> linkedTreeMap = new Gson().<LinkedTreeMap<String, Object>>fromJson(json, LinkedTreeMap.class); LinkedTreeMap<?, ?> linkedTreeMap = new Gson().fromJson(json, LinkedTreeMap.class);
Map<String, Long> tsMap = new HashMap<>(); Map<String, Long> tsMap = new HashMap<>();
tsMap.put("bitcoinFeesTs", ((Double) linkedTreeMap.get("bitcoinFeesTs")).longValue()); tsMap.put("bitcoinFeesTs", ((Double) linkedTreeMap.get("bitcoinFeesTs")).longValue());
Map<String, Long> map = new HashMap<>(); Map<String, Long> map = new HashMap<>();
try { try {
//noinspection unchecked LinkedTreeMap<?, ?> dataMap = (LinkedTreeMap<?, ?>) linkedTreeMap.get("dataMap");
LinkedTreeMap<String, Double> dataMap = (LinkedTreeMap<String, Double>) linkedTreeMap.get("dataMap"); Long btcTxFee = ((Double) dataMap.get("btcTxFee")).longValue();
Long btcTxFee = dataMap.get("btcTxFee").longValue();
map.put("BTC", btcTxFee); map.put("BTC", btcTxFee);
} catch (Throwable t) { } catch (Throwable t) {

View File

@ -50,20 +50,20 @@ public class PriceProvider extends HttpClientProvider {
String json = httpClient.requestWithGET("getAllMarketPrices", "User-Agent", "bisq/" String json = httpClient.requestWithGET("getAllMarketPrices", "User-Agent", "bisq/"
+ Version.VERSION + ", uid:" + httpClient.getUid()); + Version.VERSION + ", uid:" + httpClient.getUid());
LinkedTreeMap<String, Object> map = new Gson().<LinkedTreeMap<String, Object>>fromJson(json, LinkedTreeMap.class); LinkedTreeMap<?, ?> map = new Gson().fromJson(json, LinkedTreeMap.class);
Map<String, Long> tsMap = new HashMap<>(); Map<String, Long> tsMap = new HashMap<>();
tsMap.put("btcAverageTs", ((Double) map.get("btcAverageTs")).longValue()); tsMap.put("btcAverageTs", ((Double) map.get("btcAverageTs")).longValue());
tsMap.put("poloniexTs", ((Double) map.get("poloniexTs")).longValue()); tsMap.put("poloniexTs", ((Double) map.get("poloniexTs")).longValue());
tsMap.put("coinmarketcapTs", ((Double) map.get("coinmarketcapTs")).longValue()); tsMap.put("coinmarketcapTs", ((Double) map.get("coinmarketcapTs")).longValue());
//noinspection unchecked List<?> list = (ArrayList<?>) map.get("data");
List<LinkedTreeMap<String, Object>> list = (ArrayList<LinkedTreeMap<String, Object>>) map.get("data"); list.forEach(obj -> {
list.forEach(treeMap -> {
try { try {
LinkedTreeMap<?, ?> treeMap = (LinkedTreeMap<?, ?>) obj;
final String currencyCode = (String) treeMap.get("currencyCode"); final String currencyCode = (String) treeMap.get("currencyCode");
final double price = (double) treeMap.get("price"); final double price = (Double) treeMap.get("price");
// json uses double for our timestampSec long value... // json uses double for our timestampSec long value...
final long timestampSec = MathUtils.doubleToLong((double) treeMap.get("timestampSec")); final long timestampSec = MathUtils.doubleToLong((Double) treeMap.get("timestampSec"));
marketPriceMap.put(currencyCode, new MarketPrice(currencyCode, price, timestampSec, true)); marketPriceMap.put(currencyCode, new MarketPrice(currencyCode, price, timestampSec, true));
} catch (Throwable t) { } catch (Throwable t) {
log.error(t.toString()); log.error(t.toString());

View File

@ -74,7 +74,7 @@ public final class ArbitrationDisputeList extends DisputeList<ArbitrationDispute
list.forEach(dispute -> checkArgument(dispute.getSupportType().equals(SupportType.ARBITRATION), "Support type has to be ARBITRATION")); list.forEach(dispute -> checkArgument(dispute.getSupportType().equals(SupportType.ARBITRATION), "Support type has to be ARBITRATION"));
return protobuf.PersistableEnvelope.newBuilder().setArbitrationDisputeList(protobuf.ArbitrationDisputeList.newBuilder() return protobuf.PersistableEnvelope.newBuilder().setArbitrationDisputeList(protobuf.ArbitrationDisputeList.newBuilder()
.addAllDispute(ProtoUtil.collectionToProto(new ArrayList<>(list)))).build(); .addAllDispute(ProtoUtil.collectionToProto(new ArrayList<>(list), protobuf.Dispute.class))).build();
} }
public static ArbitrationDisputeList fromProto(protobuf.ArbitrationDisputeList proto, public static ArbitrationDisputeList fromProto(protobuf.ArbitrationDisputeList proto,

View File

@ -67,7 +67,7 @@ public final class MediationDisputeList extends DisputeList<MediationDisputeList
@Override @Override
public Message toProtoMessage() { public Message toProtoMessage() {
return protobuf.PersistableEnvelope.newBuilder().setMediationDisputeList(protobuf.MediationDisputeList.newBuilder() return protobuf.PersistableEnvelope.newBuilder().setMediationDisputeList(protobuf.MediationDisputeList.newBuilder()
.addAllDispute(ProtoUtil.collectionToProto(new ArrayList<>(list)))).build(); .addAllDispute(ProtoUtil.collectionToProto(new ArrayList<>(list), protobuf.Dispute.class))).build();
} }
public static MediationDisputeList fromProto(protobuf.MediationDisputeList proto, public static MediationDisputeList fromProto(protobuf.MediationDisputeList proto,

View File

@ -74,7 +74,7 @@ public final class RefundDisputeList extends DisputeList<RefundDisputeList> {
list.forEach(dispute -> checkArgument(dispute.getSupportType().equals(SupportType.REFUND), "Support type has to be REFUND")); list.forEach(dispute -> checkArgument(dispute.getSupportType().equals(SupportType.REFUND), "Support type has to be REFUND"));
return protobuf.PersistableEnvelope.newBuilder().setRefundDisputeList(protobuf.RefundDisputeList.newBuilder() return protobuf.PersistableEnvelope.newBuilder().setRefundDisputeList(protobuf.RefundDisputeList.newBuilder()
.addAllDispute(ProtoUtil.collectionToProto(new ArrayList<>(list)))).build(); .addAllDispute(ProtoUtil.collectionToProto(new ArrayList<>(list), protobuf.Dispute.class))).build();
} }
public static RefundDisputeList fromProto(protobuf.RefundDisputeList proto, public static RefundDisputeList fromProto(protobuf.RefundDisputeList proto,

View File

@ -74,7 +74,7 @@ public final class TradableList<T extends Tradable> implements PersistableEnvelo
ArrayList<T> clonedList = new ArrayList<>(this.list); ArrayList<T> clonedList = new ArrayList<>(this.list);
return protobuf.PersistableEnvelope.newBuilder() return protobuf.PersistableEnvelope.newBuilder()
.setTradableList(protobuf.TradableList.newBuilder() .setTradableList(protobuf.TradableList.newBuilder()
.addAllTradable(ProtoUtil.collectionToProto(clonedList))) .addAllTradable(ProtoUtil.collectionToProto(clonedList, protobuf.Tradable.class)))
.build(); .build();
} }

View File

@ -188,7 +188,8 @@ public class ProcessModel implements Model, PersistablePayload {
Optional.ofNullable(takeOfferFeeTxId).ifPresent(builder::setTakeOfferFeeTxId); Optional.ofNullable(takeOfferFeeTxId).ifPresent(builder::setTakeOfferFeeTxId);
Optional.ofNullable(payoutTxSignature).ifPresent(e -> builder.setPayoutTxSignature(ByteString.copyFrom(payoutTxSignature))); Optional.ofNullable(payoutTxSignature).ifPresent(e -> builder.setPayoutTxSignature(ByteString.copyFrom(payoutTxSignature)));
Optional.ofNullable(preparedDepositTx).ifPresent(e -> builder.setPreparedDepositTx(ByteString.copyFrom(preparedDepositTx))); Optional.ofNullable(preparedDepositTx).ifPresent(e -> builder.setPreparedDepositTx(ByteString.copyFrom(preparedDepositTx)));
Optional.ofNullable(rawTransactionInputs).ifPresent(e -> builder.addAllRawTransactionInputs(ProtoUtil.collectionToProto(rawTransactionInputs))); Optional.ofNullable(rawTransactionInputs).ifPresent(e -> builder.addAllRawTransactionInputs(
ProtoUtil.collectionToProto(rawTransactionInputs, protobuf.RawTransactionInput.class)));
Optional.ofNullable(changeOutputAddress).ifPresent(builder::setChangeOutputAddress); Optional.ofNullable(changeOutputAddress).ifPresent(builder::setChangeOutputAddress);
Optional.ofNullable(myMultiSigPubKey).ifPresent(e -> builder.setMyMultiSigPubKey(ByteString.copyFrom(myMultiSigPubKey))); Optional.ofNullable(myMultiSigPubKey).ifPresent(e -> builder.setMyMultiSigPubKey(ByteString.copyFrom(myMultiSigPubKey)));
Optional.ofNullable(tempTradingPeerNodeAddress).ifPresent(e -> builder.setTempTradingPeerNodeAddress(tempTradingPeerNodeAddress.toProtoMessage())); Optional.ofNullable(tempTradingPeerNodeAddress).ifPresent(e -> builder.setTempTradingPeerNodeAddress(tempTradingPeerNodeAddress.toProtoMessage()));

View File

@ -104,7 +104,8 @@ public final class TradingPeer implements PersistablePayload {
Optional.ofNullable(signature).ifPresent(e -> builder.setSignature(ByteString.copyFrom(e))); Optional.ofNullable(signature).ifPresent(e -> builder.setSignature(ByteString.copyFrom(e)));
Optional.ofNullable(pubKeyRing).ifPresent(e -> builder.setPubKeyRing(e.toProtoMessage())); Optional.ofNullable(pubKeyRing).ifPresent(e -> builder.setPubKeyRing(e.toProtoMessage()));
Optional.ofNullable(multiSigPubKey).ifPresent(e -> builder.setMultiSigPubKey(ByteString.copyFrom(e))); Optional.ofNullable(multiSigPubKey).ifPresent(e -> builder.setMultiSigPubKey(ByteString.copyFrom(e)));
Optional.ofNullable(rawTransactionInputs).ifPresent(e -> builder.addAllRawTransactionInputs(ProtoUtil.collectionToProto(e))); Optional.ofNullable(rawTransactionInputs).ifPresent(e -> builder.addAllRawTransactionInputs(
ProtoUtil.collectionToProto(e, protobuf.RawTransactionInput.class)));
Optional.ofNullable(changeOutputAddress).ifPresent(builder::setChangeOutputAddress); Optional.ofNullable(changeOutputAddress).ifPresent(builder::setChangeOutputAddress);
Optional.ofNullable(accountAgeWitnessNonce).ifPresent(e -> builder.setAccountAgeWitnessNonce(ByteString.copyFrom(e))); Optional.ofNullable(accountAgeWitnessNonce).ifPresent(e -> builder.setAccountAgeWitnessNonce(ByteString.copyFrom(e)));
Optional.ofNullable(accountAgeWitnessSignature).ifPresent(e -> builder.setAccountAgeWitnessSignature(ByteString.copyFrom(e))); Optional.ofNullable(accountAgeWitnessSignature).ifPresent(e -> builder.setAccountAgeWitnessSignature(ByteString.copyFrom(e)));

View File

@ -88,7 +88,7 @@ public class UserPayload implements PersistableEnvelope {
protobuf.UserPayload.Builder builder = protobuf.UserPayload.newBuilder(); protobuf.UserPayload.Builder builder = protobuf.UserPayload.newBuilder();
Optional.ofNullable(accountId).ifPresent(e -> builder.setAccountId(accountId)); Optional.ofNullable(accountId).ifPresent(e -> builder.setAccountId(accountId));
Optional.ofNullable(paymentAccounts) Optional.ofNullable(paymentAccounts)
.ifPresent(e -> builder.addAllPaymentAccounts(ProtoUtil.collectionToProto(paymentAccounts))); .ifPresent(e -> builder.addAllPaymentAccounts(ProtoUtil.collectionToProto(paymentAccounts, protobuf.PaymentAccount.class)));
Optional.ofNullable(currentPaymentAccount) Optional.ofNullable(currentPaymentAccount)
.ifPresent(e -> builder.setCurrentPaymentAccount(currentPaymentAccount.toProtoMessage())); .ifPresent(e -> builder.setCurrentPaymentAccount(currentPaymentAccount.toProtoMessage()));
Optional.ofNullable(acceptedLanguageLocaleCodes) Optional.ofNullable(acceptedLanguageLocaleCodes)
@ -111,7 +111,7 @@ public class UserPayload implements PersistableEnvelope {
message -> ((protobuf.StoragePayload) message).getMediator()))); message -> ((protobuf.StoragePayload) message).getMediator())));
Optional.ofNullable(priceAlertFilter).ifPresent(priceAlertFilter -> builder.setPriceAlertFilter(priceAlertFilter.toProtoMessage())); Optional.ofNullable(priceAlertFilter).ifPresent(priceAlertFilter -> builder.setPriceAlertFilter(priceAlertFilter.toProtoMessage()));
Optional.ofNullable(marketAlertFilters) Optional.ofNullable(marketAlertFilters)
.ifPresent(e -> builder.addAllMarketAlertFilters(ProtoUtil.collectionToProto(marketAlertFilters))); .ifPresent(e -> builder.addAllMarketAlertFilters(ProtoUtil.collectionToProto(marketAlertFilters, protobuf.MarketAlertFilter.class)));
Optional.ofNullable(registeredRefundAgent) Optional.ofNullable(registeredRefundAgent)
.ifPresent(registeredRefundAgent -> builder.setRegisteredRefundAgent(registeredRefundAgent.toProtoMessage().getRefundAgent())); .ifPresent(registeredRefundAgent -> builder.setRegisteredRefundAgent(registeredRefundAgent.toProtoMessage().getRefundAgent()));

View File

@ -84,8 +84,7 @@ public final class Navigation implements PersistedDataHost {
List<Class<? extends View>> viewClasses = persisted.getPath().stream() List<Class<? extends View>> viewClasses = persisted.getPath().stream()
.map(className -> { .map(className -> {
try { try {
//noinspection unchecked return (Class<? extends View>) Class.forName(className).asSubclass(View.class);
return ((Class<? extends View>) Class.forName(className));
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
log.warn("Could not find the viewPath class {}; exception: {}", className, e); log.warn("Could not find the viewPath class {}; exception: {}", className, e);
} }
@ -118,13 +117,12 @@ public final class Navigation implements PersistedDataHost {
Class<? extends View> viewClass = newPath.get(i); Class<? extends View> viewClass = newPath.get(i);
temp.add(viewClass); temp.add(viewClass);
if (currentPath == null || if (currentPath == null ||
(currentPath != null && (currentPath.size() > i &&
currentPath.size() > i &&
viewClass != currentPath.get(i) && viewClass != currentPath.get(i) &&
i != newPath.size() - 1)) { i != newPath.size() - 1)) {
ArrayList<Class<? extends View>> temp2 = new ArrayList<>(temp); ArrayList<Class<? extends View>> temp2 = new ArrayList<>(temp);
for (int n = i + 1; n < newPath.size(); n++) { for (int n = i + 1; n < newPath.size(); n++) {
//noinspection unchecked,unchecked,unchecked //noinspection unchecked
Class<? extends View>[] newTemp = new Class[i + 1]; Class<? extends View>[] newTemp = new Class[i + 1];
currentPath = ViewPath.to(temp2.toArray(newTemp)); currentPath = ViewPath.to(temp2.toArray(newTemp));
navigateTo(currentPath, data); navigateTo(currentPath, data);

View File

@ -22,16 +22,4 @@ public interface Activatable {
void _activate(); void _activate();
void _deactivate(); void _deactivate();
Activatable NO_OP_INSTANCE = new Activatable() {
@Override
public void _activate() {
}
@Override
public void _deactivate() {
}
};
} }

View File

@ -29,11 +29,6 @@ public abstract class ActivatableViewAndModel<R extends Node, M extends Activata
super(checkNotNull(model, "Model must not be null")); super(checkNotNull(model, "Model must not be null"));
} }
public ActivatableViewAndModel() {
//noinspection unchecked
this((M) Activatable.NO_OP_INSTANCE);
}
@Override @Override
protected void prepareInitialize() { protected void prepareInitialize() {
if (root != null) { if (root != null) {

View File

@ -46,7 +46,7 @@ import java.util.List;
public class AutocompleteComboBox<T> extends JFXComboBox<T> { public class AutocompleteComboBox<T> extends JFXComboBox<T> {
private ArrayList<T> completeList; private ArrayList<T> completeList;
private ArrayList<T> matchingList; private ArrayList<T> matchingList;
private JFXComboBoxListViewSkin comboBoxListViewSkin; private JFXComboBoxListViewSkin<T> comboBoxListViewSkin;
public AutocompleteComboBox() { public AutocompleteComboBox() {
this(FXCollections.observableArrayList()); this(FXCollections.observableArrayList());
@ -65,7 +65,7 @@ public class AutocompleteComboBox<T> extends JFXComboBox<T> {
/** /**
* Set the complete list of ComboBox items. Use this instead of setItems(). * Set the complete list of ComboBox items. Use this instead of setItems().
*/ */
public void setAutocompleteItems(List<T> items) { public void setAutocompleteItems(List<? extends T> items) {
completeList = new ArrayList<>(items); completeList = new ArrayList<>(items);
matchingList = new ArrayList<>(completeList); matchingList = new ArrayList<>(completeList);
setValue(null); setValue(null);

View File

@ -211,10 +211,11 @@ public class AssetsForm extends PaymentMethodForm {
currencyComboBox.setPromptText(""); currencyComboBox.setPromptText("");
}); });
((AutocompleteComboBox) currencyComboBox).setAutocompleteItems(CurrencyUtil.getActiveSortedCryptoCurrencies(assetService, filterManager)); ((AutocompleteComboBox<TradeCurrency>) currencyComboBox).setAutocompleteItems(
CurrencyUtil.getActiveSortedCryptoCurrencies(assetService, filterManager));
currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 10)); currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 10));
currencyComboBox.setConverter(new StringConverter<TradeCurrency>() { currencyComboBox.setConverter(new StringConverter<>() {
@Override @Override
public String toString(TradeCurrency tradeCurrency) { public String toString(TradeCurrency tradeCurrency) {
return tradeCurrency != null ? tradeCurrency.getNameAndCode() : ""; return tradeCurrency != null ? tradeCurrency.getNameAndCode() : "";
@ -223,12 +224,12 @@ public class AssetsForm extends PaymentMethodForm {
@Override @Override
public TradeCurrency fromString(String s) { public TradeCurrency fromString(String s) {
return currencyComboBox.getItems().stream(). return currencyComboBox.getItems().stream().
filter(item -> item.getNameAndCode().equals(s)). filter(item -> item.getNameAndCode().equals(s)).
findAny().orElse(null); findAny().orElse(null);
} }
}); });
((AutocompleteComboBox) currencyComboBox).setOnChangeConfirmed(e -> { ((AutocompleteComboBox<?>) currencyComboBox).setOnChangeConfirmed(e -> {
addressInputTextField.resetValidation(); addressInputTextField.resetValidation();
addressInputTextField.validate(); addressInputTextField.validate();
paymentAccount.setSingleTradeCurrency(currencyComboBox.getSelectionModel().getSelectedItem()); paymentAccount.setSingleTradeCurrency(currencyComboBox.getSelectionModel().getSelectedItem());

View File

@ -197,12 +197,12 @@ public class JapanBankTransferForm extends PaymentMethodForm
return s != null ? s : ""; return s != null ? s : "";
} }
}); });
((AutocompleteComboBox) bankComboBox).setAutocompleteItems(JapanBankData.prettyPrintBankList()); ((AutocompleteComboBox<String>) bankComboBox).setAutocompleteItems(JapanBankData.prettyPrintBankList());
bankComboBox.setPrefWidth(430); bankComboBox.setPrefWidth(430);
bankComboBox.setVisibleRowCount(430); bankComboBox.setVisibleRowCount(430);
((AutocompleteComboBox) bankComboBox).setOnChangeConfirmed(e -> { ((AutocompleteComboBox<?>) bankComboBox).setOnChangeConfirmed(e -> {
// get selected value // get selected value
String bank = bankComboBox.getSelectionModel().getSelectedItem(); String bank = bankComboBox.getSelectionModel().getSelectedItem();

View File

@ -32,6 +32,7 @@ import bisq.desktop.util.Layout;
import bisq.core.app.AppOptionKeys; import bisq.core.app.AppOptionKeys;
import bisq.core.locale.LanguageUtil; import bisq.core.locale.LanguageUtil;
import bisq.core.locale.Res; import bisq.core.locale.Res;
import bisq.core.support.dispute.agent.DisputeAgent;
import bisq.common.UserThread; import bisq.common.UserThread;
import bisq.common.util.Tuple2; import bisq.common.util.Tuple2;
@ -70,7 +71,8 @@ import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
// TODO translation string keys should renamed to be more generic. // TODO translation string keys should renamed to be more generic.
// Lets do it for 1.1.7 the translator have time to add new string. // Lets do it for 1.1.7 the translator have time to add new string.
@FxmlView @FxmlView
public abstract class AgentRegistrationView<R, T extends AgentRegistrationViewModel> extends ActivatableViewAndModel<VBox, T> { public abstract class AgentRegistrationView<R extends DisputeAgent, T extends AgentRegistrationViewModel<R, ?>>
extends ActivatableViewAndModel<VBox, T> {
private final boolean useDevPrivilegeKeys; private final boolean useDevPrivilegeKeys;
private ListView<String> languagesListView; private ListView<String> languagesListView;

View File

@ -18,8 +18,7 @@
package bisq.desktop.main.dao; package bisq.desktop.main.dao;
import bisq.desktop.Navigation; import bisq.desktop.Navigation;
import bisq.desktop.common.model.Activatable; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.ActivatableViewAndModel;
import bisq.desktop.common.view.CachingViewLoader; import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View; import bisq.desktop.common.view.View;
@ -53,7 +52,7 @@ import javafx.scene.control.TabPane;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
@FxmlView @FxmlView
public class DaoView extends ActivatableViewAndModel<TabPane, Activatable> { public class DaoView extends ActivatableView<TabPane, Void> {
@FXML @FXML
private Tab bsqWalletTab, proposalsTab, bondingTab, burnBsqTab, daoNewsTab, monitorTab, factsAndFiguresTab; private Tab bsqWalletTab, proposalsTab, bondingTab, burnBsqTab, daoNewsTab, monitorTab, factsAndFiguresTab;

View File

@ -18,7 +18,7 @@
package bisq.desktop.main.dao.bonding; package bisq.desktop.main.dao.bonding;
import bisq.desktop.Navigation; import bisq.desktop.Navigation;
import bisq.desktop.common.view.ActivatableViewAndModel; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.CachingViewLoader; import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View; import bisq.desktop.common.view.View;
@ -49,7 +49,7 @@ import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@FxmlView @FxmlView
public class BondingView extends ActivatableViewAndModel { public class BondingView extends ActivatableView<AnchorPane, Void> {
private final ViewLoader viewLoader; private final ViewLoader viewLoader;
private final Navigation navigation; private final Navigation navigation;

View File

@ -18,7 +18,7 @@
package bisq.desktop.main.dao.burnbsq; package bisq.desktop.main.dao.burnbsq;
import bisq.desktop.Navigation; import bisq.desktop.Navigation;
import bisq.desktop.common.view.ActivatableViewAndModel; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.CachingViewLoader; import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View; import bisq.desktop.common.view.View;
@ -44,7 +44,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
@FxmlView @FxmlView
public class BurnBsqView extends ActivatableViewAndModel { public class BurnBsqView extends ActivatableView<AnchorPane, Void> {
private final ViewLoader viewLoader; private final ViewLoader viewLoader;
private final Navigation navigation; private final Navigation navigation;

View File

@ -18,7 +18,7 @@
package bisq.desktop.main.dao.economy; package bisq.desktop.main.dao.economy;
import bisq.desktop.Navigation; import bisq.desktop.Navigation;
import bisq.desktop.common.view.ActivatableViewAndModel; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.CachingViewLoader; import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View; import bisq.desktop.common.view.View;
@ -47,7 +47,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
@FxmlView @FxmlView
public class EconomyView extends ActivatableViewAndModel { public class EconomyView extends ActivatableView<AnchorPane, Void> {
private final ViewLoader viewLoader; private final ViewLoader viewLoader;
private final Navigation navigation; private final Navigation navigation;

View File

@ -105,7 +105,7 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
private ChangeListener<Number> priceChangeListener; private ChangeListener<Number> priceChangeListener;
private AreaChart bsqPriceChart; private AreaChart<Number, Number> bsqPriceChart;
private XYChart.Series<Number, Number> seriesBSQPrice; private XYChart.Series<Number, Number> seriesBSQPrice;
private TextField avgPrice90TextField, marketCapTextField, availableAmountTextField; private TextField avgPrice90TextField, marketCapTextField, availableAmountTextField;
@ -254,7 +254,7 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
bsqPriceChart.setPrefHeight(bsqPriceChart.getMinHeight()); bsqPriceChart.setPrefHeight(bsqPriceChart.getMinHeight());
bsqPriceChart.setCreateSymbols(true); bsqPriceChart.setCreateSymbols(true);
bsqPriceChart.setPadding(new Insets(0)); bsqPriceChart.setPadding(new Insets(0));
bsqPriceChart.getData().addAll(seriesBSQPrice); bsqPriceChart.getData().add(seriesBSQPrice);
AnchorPane chartPane = new AnchorPane(); AnchorPane chartPane = new AnchorPane();
chartPane.getStyleClass().add("chart-pane"); chartPane.getStyleClass().add("chart-pane");
@ -368,7 +368,7 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
long average = getAverage(bsqTradePast90Days); long average = getAverage(bsqTradePast90Days);
Coin oneBsq = Coin.valueOf(100); Coin oneBsq = Coin.valueOf(100);
Price avgPrice = Price.valueOf("BSQ", average); Price avgPrice = Price.valueOf("BSQ", average);
String avg = bsqFormatter.formatPrice(avgPrice); String avg = BsqFormatter.formatPrice(avgPrice);
String bsqInUsdAvg = average > 0 ? GUIUtil.getBsqInUsd(avgPrice, oneBsq, priceFeedService, bsqFormatter) : Res.get("shared.na"); String bsqInUsdAvg = average > 0 ? GUIUtil.getBsqInUsd(avgPrice, oneBsq, priceFeedService, bsqFormatter) : Res.get("shared.na");
textField.setText(avg + " BSQ/BTC (" + "1 BSQ = " + bsqInUsdAvg + ")"); textField.setText(avg + " BSQ/BTC (" + "1 BSQ = " + bsqInUsdAvg + ")");
return average; return average;

View File

@ -195,7 +195,6 @@ public class SupplyView extends ActivatableView<GridPane, Void> implements DaoSt
Res.get("dao.factsAndFigures.supply.totalConfiscatedAmount")).second; Res.get("dao.factsAndFigures.supply.totalConfiscatedAmount")).second;
} }
@SuppressWarnings("unchecked")
private void createChart(XYChart.Series<Number, Number> series, String seriesLabel, String datePattern) { private void createChart(XYChart.Series<Number, Number> series, String seriesLabel, String datePattern) {
NumberAxis xAxis = new NumberAxis(); NumberAxis xAxis = new NumberAxis();
xAxis.setForceZeroInRange(false); xAxis.setForceZeroInRange(false);
@ -246,7 +245,7 @@ public class SupplyView extends ActivatableView<GridPane, Void> implements DaoSt
chart.setPrefHeight(250); chart.setPrefHeight(250);
chart.setCreateSymbols(true); chart.setCreateSymbols(true);
chart.setPadding(new Insets(0)); chart.setPadding(new Insets(0));
chart.getData().addAll(series); chart.getData().add(series);
AnchorPane chartPane = new AnchorPane(); AnchorPane chartPane = new AnchorPane();
chartPane.getStyleClass().add("chart-pane"); chartPane.getStyleClass().add("chart-pane");

View File

@ -18,7 +18,7 @@
package bisq.desktop.main.dao.governance; package bisq.desktop.main.dao.governance;
import bisq.desktop.Navigation; import bisq.desktop.Navigation;
import bisq.desktop.common.view.ActivatableViewAndModel; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.CachingViewLoader; import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View; import bisq.desktop.common.view.View;
@ -52,7 +52,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
@FxmlView @FxmlView
public class GovernanceView extends ActivatableViewAndModel implements DaoStateListener { public class GovernanceView extends ActivatableView<AnchorPane, Void> implements DaoStateListener {
private final ViewLoader viewLoader; private final ViewLoader viewLoader;
private final Navigation navigation; private final Navigation navigation;
private final DaoFacade daoFacade; private final DaoFacade daoFacade;

View File

@ -136,7 +136,7 @@ public class ProposalDisplay {
@Getter @Getter
private List<TextInputControl> inputControls = new ArrayList<>(); private List<TextInputControl> inputControls = new ArrayList<>();
@Getter @Getter
private List<ComboBox> comboBoxes = new ArrayList<>(); private List<ComboBox<?>> comboBoxes = new ArrayList<>();
private final ChangeListener<Boolean> focusOutListener; private final ChangeListener<Boolean> focusOutListener;
private final ChangeListener<Object> inputListener; private final ChangeListener<Object> inputListener;
private ChangeListener<Param> paramChangeListener; private ChangeListener<Param> paramChangeListener;
@ -602,10 +602,8 @@ public class ProposalDisplay {
inputControl.focusedProperty().addListener(focusOutListener); inputControl.focusedProperty().addListener(focusOutListener);
}); });
comboBoxes.stream() comboBoxes.stream()
.filter(Objects::nonNull).forEach(comboBox -> { .filter(Objects::nonNull)
//noinspection unchecked .forEach(comboBox -> comboBox.getSelectionModel().selectedItemProperty().addListener(inputListener));
comboBox.getSelectionModel().selectedItemProperty().addListener(inputListener);
});
} }
public void removeListeners() { public void removeListeners() {
@ -615,10 +613,8 @@ public class ProposalDisplay {
inputControl.focusedProperty().removeListener(focusOutListener); inputControl.focusedProperty().removeListener(focusOutListener);
}); });
comboBoxes.stream() comboBoxes.stream()
.filter(Objects::nonNull).forEach(comboBox -> { .filter(Objects::nonNull)
//noinspection unchecked .forEach(comboBox -> comboBox.getSelectionModel().selectedItemProperty().removeListener(inputListener));
comboBox.getSelectionModel().selectedItemProperty().removeListener(inputListener);
});
if (paramComboBox != null && paramChangeListener != null) if (paramComboBox != null && paramChangeListener != null)
paramComboBox.getSelectionModel().selectedItemProperty().removeListener(paramChangeListener); paramComboBox.getSelectionModel().selectedItemProperty().removeListener(paramChangeListener);

View File

@ -18,7 +18,7 @@
package bisq.desktop.main.dao.monitor; package bisq.desktop.main.dao.monitor;
import bisq.desktop.Navigation; import bisq.desktop.Navigation;
import bisq.desktop.common.view.ActivatableViewAndModel; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.CachingViewLoader; import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View; import bisq.desktop.common.view.View;
@ -45,7 +45,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
@FxmlView @FxmlView
public class MonitorView extends ActivatableViewAndModel { public class MonitorView extends ActivatableView<AnchorPane, Void> {
private final ViewLoader viewLoader; private final ViewLoader viewLoader;
private final Navigation navigation; private final Navigation navigation;

View File

@ -18,7 +18,7 @@
package bisq.desktop.main.dao.wallet; package bisq.desktop.main.dao.wallet;
import bisq.desktop.Navigation; import bisq.desktop.Navigation;
import bisq.desktop.common.view.ActivatableViewAndModel; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.CachingViewLoader; import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View; import bisq.desktop.common.view.View;
@ -47,7 +47,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
@FxmlView @FxmlView
public class BsqWalletView extends ActivatableViewAndModel { public class BsqWalletView extends ActivatableView<AnchorPane, Void> {
private final ViewLoader viewLoader; private final ViewLoader viewLoader;
private final Navigation navigation; private final Navigation navigation;

View File

@ -18,8 +18,7 @@
package bisq.desktop.main.funds; package bisq.desktop.main.funds;
import bisq.desktop.Navigation; import bisq.desktop.Navigation;
import bisq.desktop.common.model.Activatable; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.ActivatableViewAndModel;
import bisq.desktop.common.view.CachingViewLoader; import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View; import bisq.desktop.common.view.View;
@ -43,7 +42,7 @@ import javafx.scene.control.TabPane;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
@FxmlView @FxmlView
public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> { public class FundsView extends ActivatableView<TabPane, Void> {
@FXML @FXML
Tab depositTab, withdrawalTab, reservedTab, lockedTab, transactionsTab; Tab depositTab, withdrawalTab, reservedTab, lockedTab, transactionsTab;

View File

@ -18,8 +18,7 @@
package bisq.desktop.main.market; package bisq.desktop.main.market;
import bisq.desktop.Navigation; import bisq.desktop.Navigation;
import bisq.desktop.common.model.Activatable; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.ActivatableViewAndModel;
import bisq.desktop.common.view.CachingViewLoader; import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View; import bisq.desktop.common.view.View;
@ -65,7 +64,7 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@FxmlView @FxmlView
public class MarketView extends ActivatableViewAndModel<TabPane, Activatable> { public class MarketView extends ActivatableView<TabPane, Void> {
@FXML @FXML
Tab offerBookTab, tradesTab, spreadTab; Tab offerBookTab, tradesTab, spreadTab;
private final ViewLoader viewLoader; private final ViewLoader viewLoader;

View File

@ -89,10 +89,8 @@ import javafx.util.Callback;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.List;
import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier;
import static bisq.desktop.util.FormBuilder.addTopLabelAutocompleteComboBox; import static bisq.desktop.util.FormBuilder.addTopLabelAutocompleteComboBox;
import static bisq.desktop.util.Layout.INITIAL_WINDOW_HEIGHT; import static bisq.desktop.util.Layout.INITIAL_WINDOW_HEIGHT;
@ -102,7 +100,7 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
private final boolean useDevPrivilegeKeys; private final boolean useDevPrivilegeKeys;
private NumberAxis xAxis; private NumberAxis xAxis;
private XYChart.Series seriesBuy, seriesSell; private XYChart.Series<Number, Number> seriesBuy, seriesSell;
private final Navigation navigation; private final Navigation navigation;
private final BSFormatter formatter; private final BSFormatter formatter;
private TableView<OfferListItem> buyOfferTableView; private TableView<OfferListItem> buyOfferTableView;
@ -369,7 +367,7 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
areaChart.setPrefHeight(270); areaChart.setPrefHeight(270);
areaChart.setCreateSymbols(true); areaChart.setCreateSymbols(true);
areaChart.setPadding(new Insets(0, 10, 0, 10)); areaChart.setPadding(new Insets(0, 10, 0, 10));
areaChart.getData().addAll(seriesBuy, seriesSell); areaChart.getData().addAll(List.of(seriesBuy, seriesSell));
chartPane = new AnchorPane(); chartPane = new AnchorPane();
chartPane.getStyleClass().add("chart-pane"); chartPane.getStyleClass().add("chart-pane");
@ -387,33 +385,32 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
seriesSell.getData().clear(); seriesSell.getData().clear();
areaChart.getData().clear(); areaChart.getData().clear();
final Supplier<Optional<? extends XYChart.Data>> optionalMaxSupplier = () -> double buyMinValue = model.getBuyData().stream()
Optional.of(new XYChart.Data<>(Double.MAX_VALUE, Double.MAX_VALUE)); .mapToDouble(o -> o.getXValue().doubleValue())
.min()
.orElse(Double.MAX_VALUE);
final Optional<XYChart.Data> buyMinOptional = model.getBuyData().stream() // Hide buy offers that are more than a factor 3 higher than the lowest buy offer
.min(Comparator.comparingDouble(o -> (double) o.getXValue())) double buyMaxValue = model.getBuyData().stream()
.or(optionalMaxSupplier); .mapToDouble(o -> o.getXValue().doubleValue())
.filter(o -> o < buyMinValue * 3)
.max()
.orElse(Double.MIN_VALUE);
final Supplier<Optional<? extends XYChart.Data>> optionalMinSupplier = () -> double sellMaxValue = model.getSellData().stream()
Optional.of(new XYChart.Data<>(Double.MIN_VALUE, Double.MIN_VALUE)); .mapToDouble(o -> o.getXValue().doubleValue())
.max()
.orElse(Double.MIN_VALUE);
// Hide buy offers that are more than a factor 5 higher than the lowest buy offer // Hide sell offers that are less than a factor 3 lower than the highest sell offer
final Optional<XYChart.Data> buyMaxOptional = model.getBuyData().stream() double sellMinValue = model.getSellData().stream()
.filter(o -> (double) o.getXValue() < (double) buyMinOptional.get().getXValue() * 3) .mapToDouble(o -> o.getXValue().doubleValue())
.max(Comparator.comparingDouble(o -> (double) o.getXValue())) .filter(o -> o > sellMaxValue / 3)
.or(optionalMinSupplier); .min()
.orElse(Double.MAX_VALUE);
final Optional<XYChart.Data> sellMaxOptional = model.getSellData().stream() double minValue = Double.min(buyMinValue, sellMinValue);
.max(Comparator.comparingDouble(o -> (double) o.getXValue())) double maxValue = Double.max(buyMaxValue, sellMaxValue);
.or(optionalMinSupplier);
final Optional<XYChart.Data> sellMinOptional = model.getSellData().stream()
.filter(o -> (double) o.getXValue() > (double) sellMaxOptional.get().getXValue() / 3)
.min(Comparator.comparingDouble(o -> (double) o.getXValue()))
.or(optionalMaxSupplier);
final double minValue = Double.min((double) buyMinOptional.get().getXValue(), (double) sellMinOptional.get().getXValue());
final double maxValue = Double.max((double) buyMaxOptional.get().getXValue(), (double) sellMaxOptional.get().getXValue());
if (minValue == Double.MAX_VALUE || maxValue == Double.MIN_VALUE) { if (minValue == Double.MAX_VALUE || maxValue == Double.MIN_VALUE) {
xAxis.setAutoRanging(true); xAxis.setAutoRanging(true);
@ -424,11 +421,9 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
xAxis.setTickUnit((maxValue - minValue) / 13); xAxis.setTickUnit((maxValue - minValue) / 13);
} }
//noinspection unchecked
seriesBuy.getData().addAll(model.getBuyData()); seriesBuy.getData().addAll(model.getBuyData());
//noinspection unchecked
seriesSell.getData().addAll(model.getSellData()); seriesSell.getData().addAll(model.getSellData());
areaChart.getData().addAll(seriesBuy, seriesSell); areaChart.getData().addAll(List.of(seriesBuy, seriesSell));
} }
private Tuple4<TableView<OfferListItem>, VBox, Button, Label> getOfferTable(OfferPayload.Direction direction) { private Tuple4<TableView<OfferListItem>, VBox, Button, Label> getOfferTable(OfferPayload.Direction direction) {

View File

@ -74,8 +74,8 @@ class OfferBookChartViewModel extends ActivatableViewModel {
private final Navigation navigation; private final Navigation navigation;
final ObjectProperty<TradeCurrency> selectedTradeCurrencyProperty = new SimpleObjectProperty<>(); final ObjectProperty<TradeCurrency> selectedTradeCurrencyProperty = new SimpleObjectProperty<>();
private final List<XYChart.Data> buyData = new ArrayList<>(); private final List<XYChart.Data<Number, Number>> buyData = new ArrayList<>();
private final List<XYChart.Data> sellData = new ArrayList<>(); private final List<XYChart.Data<Number, Number>> sellData = new ArrayList<>();
private final ObservableList<OfferBookListItem> offerBookListItems; private final ObservableList<OfferBookListItem> offerBookListItems;
private final ListChangeListener<OfferBookListItem> offerBookListItemsListener; private final ListChangeListener<OfferBookListItem> offerBookListItemsListener;
final CurrencyList currencyListItems; final CurrencyList currencyListItems;
@ -131,7 +131,7 @@ class OfferBookChartViewModel extends ActivatableViewModel {
fillTradeCurrencies(); fillTradeCurrencies();
}; };
currenciesUpdatedListener = new ChangeListener<Number>() { currenciesUpdatedListener = new ChangeListener<>() {
@Override @Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
if (!isAnyPricePresent()) { if (!isAnyPricePresent()) {
@ -210,11 +210,11 @@ class OfferBookChartViewModel extends ActivatableViewModel {
// Getters // Getters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public List<XYChart.Data> getBuyData() { public List<XYChart.Data<Number, Number>> getBuyData() {
return buyData; return buyData;
} }
public List<XYChart.Data> getSellData() { public List<XYChart.Data<Number, Number>> getSellData() {
return sellData; return sellData;
} }
@ -359,7 +359,10 @@ class OfferBookChartViewModel extends ActivatableViewModel {
buildChartAndTableEntries(allSellOffers, OfferPayload.Direction.SELL, sellData, topSellOfferList); buildChartAndTableEntries(allSellOffers, OfferPayload.Direction.SELL, sellData, topSellOfferList);
} }
private void buildChartAndTableEntries(List<Offer> sortedList, OfferPayload.Direction direction, List<XYChart.Data> data, ObservableList<OfferListItem> offerTableList) { private void buildChartAndTableEntries(List<Offer> sortedList,
OfferPayload.Direction direction,
List<XYChart.Data<Number, Number>> data,
ObservableList<OfferListItem> offerTableList) {
data.clear(); data.clear();
double accumulatedAmount = 0; double accumulatedAmount = 0;
List<OfferListItem> offerTableListTemp = new ArrayList<>(); List<OfferListItem> offerTableListTemp = new ArrayList<>();

View File

@ -88,7 +88,7 @@ import javafx.util.StringConverter;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.Objects; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -184,7 +184,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
@Override @Override
protected void activate() { protected void activate() {
// root.getParent() is null at initialize // root.getParent() is null at initialize
tabPaneSelectionModel = Objects.requireNonNull(GUIUtil.getParentOfType(root, JFXTabPane.class)).getSelectionModel(); tabPaneSelectionModel = GUIUtil.getParentOfType(root, JFXTabPane.class).getSelectionModel();
selectedTabIndexListener = (observable, oldValue, newValue) -> model.setSelectedTabIndex((int) newValue); selectedTabIndexListener = (observable, oldValue, newValue) -> model.setSelectedTabIndex((int) newValue);
model.setSelectedTabIndex(tabPaneSelectionModel.getSelectedIndex()); model.setSelectedTabIndex(tabPaneSelectionModel.getSelectedIndex());
tabPaneSelectionModel.selectedIndexProperty().addListener(selectedTabIndexListener); tabPaneSelectionModel.selectedIndexProperty().addListener(selectedTabIndexListener);
@ -380,8 +380,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
priceChart.setMaxHeight(300); priceChart.setMaxHeight(300);
priceChart.setLegendVisible(false); priceChart.setLegendVisible(false);
priceChart.setPadding(new Insets(0)); priceChart.setPadding(new Insets(0));
//noinspection unchecked priceChart.setData(FXCollections.observableArrayList(List.of(priceSeries)));
priceChart.setData(FXCollections.observableArrayList(priceSeries));
priceChartPane = new AnchorPane(); priceChartPane = new AnchorPane();
priceChartPane.getStyleClass().add("chart-pane"); priceChartPane.getStyleClass().add("chart-pane");
@ -428,9 +427,8 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
return null; return null;
} }
}); });
//noinspection unchecked
volumeChart.setId("volume-chart"); volumeChart.setId("volume-chart");
volumeChart.setData(FXCollections.observableArrayList(volumeSeries)); volumeChart.setData(FXCollections.observableArrayList(List.of(volumeSeries)));
volumeChart.setMinHeight(128); volumeChart.setMinHeight(128);
volumeChart.setPrefHeight(128); volumeChart.setPrefHeight(128);
volumeChart.setMaxHeight(200); volumeChart.setMaxHeight(200);
@ -457,8 +455,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
priceSeries = new XYChart.Series<>(); priceSeries = new XYChart.Series<>();
priceSeries.getData().setAll(model.priceItems); priceSeries.getData().setAll(model.priceItems);
priceChart.getData().clear(); priceChart.getData().clear();
//noinspection unchecked priceChart.setData(FXCollections.observableArrayList(List.of(priceSeries)));
priceChart.setData(FXCollections.observableArrayList(priceSeries));
} }
private void layoutChart() { private void layoutChart() {

View File

@ -121,7 +121,7 @@ import org.jetbrains.annotations.NotNull;
import static bisq.desktop.util.FormBuilder.*; import static bisq.desktop.util.FormBuilder.*;
import static javafx.beans.binding.Bindings.createStringBinding; import static javafx.beans.binding.Bindings.createStringBinding;
public abstract class MutableOfferView<M extends MutableOfferViewModel> extends ActivatableViewAndModel<AnchorPane, M> { public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> extends ActivatableViewAndModel<AnchorPane, M> {
public static final String BUYER_SECURITY_DEPOSIT_NEWS = "buyerSecurityDepositNews0.9.5"; public static final String BUYER_SECURITY_DEPOSIT_NEWS = "buyerSecurityDepositNews0.9.5";
protected final Navigation navigation; protected final Navigation navigation;
private final Preferences preferences; private final Preferences preferences;
@ -438,7 +438,6 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel> extends
balanceTextField.setTargetAmount(model.getDataModel().totalToPayAsCoinProperty().get()); balanceTextField.setTargetAmount(model.getDataModel().totalToPayAsCoinProperty().get());
//noinspection PointlessBooleanExpression
if (!DevEnv.isDevMode()) { if (!DevEnv.isDevMode()) {
String key = "securityDepositInfo"; String key = "securityDepositInfo";
new Popup<>().backgroundInfo(Res.get("popup.info.securityDepositInfo")) new Popup<>().backgroundInfo(Res.get("popup.info.securityDepositInfo"))

View File

@ -29,14 +29,16 @@ import bisq.desktop.util.Transitions;
import bisq.core.app.BisqEnvironment; import bisq.core.app.BisqEnvironment;
import bisq.core.locale.GlobalSettings; import bisq.core.locale.GlobalSettings;
import bisq.core.locale.LanguageUtil;
import bisq.core.locale.Res; import bisq.core.locale.Res;
import bisq.core.user.DontShowAgainLookup; import bisq.core.user.DontShowAgainLookup;
import bisq.core.locale.LanguageUtil;
import bisq.common.Timer; import bisq.common.Timer;
import bisq.common.UserThread; import bisq.common.UserThread;
import bisq.common.util.Utilities; import bisq.common.util.Utilities;
import com.google.common.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import de.jensd.fx.fontawesome.AwesomeIcon; import de.jensd.fx.fontawesome.AwesomeIcon;
@ -68,8 +70,8 @@ import javafx.scene.transform.Rotate;
import javafx.geometry.HPos; import javafx.geometry.HPos;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.NodeOrientation; import javafx.geometry.NodeOrientation;
import javafx.geometry.Pos;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
@ -93,7 +95,7 @@ import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public abstract class Overlay<T extends Overlay> { public abstract class Overlay<T extends Overlay<T>> {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Enum // Enum
@ -185,12 +187,23 @@ public abstract class Overlay<T extends Overlay> {
protected int maxChar = 1800; protected int maxChar = 1800;
private T cast() {
//noinspection unchecked
return (T) this;
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Public API // Public API
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public Overlay() { public Overlay() {
//noinspection UnstableApiUsage
TypeToken<T> typeToken = new TypeToken<>(getClass()) {
};
if (!typeToken.isSupertypeOf(getClass())) {
throw new RuntimeException("Subclass of Overlay<T> should be castable to T");
}
} }
public void show(boolean showAgainChecked) { public void show(boolean showAgainChecked) {
@ -266,26 +279,22 @@ public abstract class Overlay<T extends Overlay> {
public T onClose(Runnable closeHandler) { public T onClose(Runnable closeHandler) {
this.closeHandlerOptional = Optional.of(closeHandler); this.closeHandlerOptional = Optional.of(closeHandler);
//noinspection unchecked return cast();
return (T) this;
} }
public T onAction(Runnable actionHandler) { public T onAction(Runnable actionHandler) {
this.actionHandlerOptional = Optional.of(actionHandler); this.actionHandlerOptional = Optional.of(actionHandler);
//noinspection unchecked return cast();
return (T) this;
} }
public T onSecondaryAction(Runnable secondaryActionHandlerOptional) { public T onSecondaryAction(Runnable secondaryActionHandlerOptional) {
this.secondaryActionHandlerOptional = Optional.of(secondaryActionHandlerOptional); this.secondaryActionHandlerOptional = Optional.of(secondaryActionHandlerOptional);
//noinspection unchecked return cast();
return (T) this;
} }
public T headLine(String headLine) { public T headLine(String headLine) {
this.headLine = headLine; this.headLine = headLine;
//noinspection unchecked return cast();
return (T) this;
} }
public T notification(String message) { public T notification(String message) {
@ -294,8 +303,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.notification"); this.headLine = Res.get("popup.headline.notification");
this.message = message; this.message = message;
setTruncatedMessage(); setTruncatedMessage();
//noinspection unchecked return cast();
return (T) this;
} }
public T instruction(String message) { public T instruction(String message) {
@ -304,8 +312,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.instruction"); this.headLine = Res.get("popup.headline.instruction");
this.message = message; this.message = message;
setTruncatedMessage(); setTruncatedMessage();
//noinspection unchecked return cast();
return (T) this;
} }
public T attention(String message) { public T attention(String message) {
@ -314,8 +321,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.attention"); this.headLine = Res.get("popup.headline.attention");
this.message = message; this.message = message;
setTruncatedMessage(); setTruncatedMessage();
//noinspection unchecked return cast();
return (T) this;
} }
public T backgroundInfo(String message) { public T backgroundInfo(String message) {
@ -324,8 +330,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.backgroundInfo"); this.headLine = Res.get("popup.headline.backgroundInfo");
this.message = message; this.message = message;
setTruncatedMessage(); setTruncatedMessage();
//noinspection unchecked return cast();
return (T) this;
} }
public T feedback(String message) { public T feedback(String message) {
@ -334,8 +339,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.feedback"); this.headLine = Res.get("popup.headline.feedback");
this.message = message; this.message = message;
setTruncatedMessage(); setTruncatedMessage();
//noinspection unchecked return cast();
return (T) this;
} }
public T confirmation(String message) { public T confirmation(String message) {
@ -344,8 +348,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.confirmation"); this.headLine = Res.get("popup.headline.confirmation");
this.message = message; this.message = message;
setTruncatedMessage(); setTruncatedMessage();
//noinspection unchecked return cast();
return (T) this;
} }
public T information(String message) { public T information(String message) {
@ -354,8 +357,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.information"); this.headLine = Res.get("popup.headline.information");
this.message = message; this.message = message;
setTruncatedMessage(); setTruncatedMessage();
//noinspection unchecked return cast();
return (T) this;
} }
public T warning(String message) { public T warning(String message) {
@ -365,8 +367,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.warning"); this.headLine = Res.get("popup.headline.warning");
this.message = message; this.message = message;
setTruncatedMessage(); setTruncatedMessage();
//noinspection unchecked return cast();
return (T) this;
} }
public T error(String message) { public T error(String message) {
@ -377,136 +378,116 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.error"); this.headLine = Res.get("popup.headline.error");
this.message = message; this.message = message;
setTruncatedMessage(); setTruncatedMessage();
//noinspection unchecked return cast();
return (T) this;
} }
@SuppressWarnings("UnusedReturnValue") @SuppressWarnings("UnusedReturnValue")
public T showReportErrorButtons() { public T showReportErrorButtons() {
this.showReportErrorButtons = true; this.showReportErrorButtons = true;
//noinspection unchecked return cast();
return (T) this;
} }
public T message(String message) { public T message(String message) {
this.message = message; this.message = message;
setTruncatedMessage(); setTruncatedMessage();
//noinspection unchecked return cast();
return (T) this;
} }
public T closeButtonText(String closeButtonText) { public T closeButtonText(String closeButtonText) {
this.closeButtonText = closeButtonText; this.closeButtonText = closeButtonText;
//noinspection unchecked return cast();
return (T) this;
} }
public T useReportBugButton() { public T useReportBugButton() {
this.closeButtonText = Res.get("shared.reportBug"); this.closeButtonText = Res.get("shared.reportBug");
this.closeHandlerOptional = Optional.of(() -> GUIUtil.openWebPage("https://bisq.network/source/bisq/issues")); this.closeHandlerOptional = Optional.of(() -> GUIUtil.openWebPage("https://bisq.network/source/bisq/issues"));
//noinspection unchecked return cast();
return (T) this;
} }
public T useIUnderstandButton() { public T useIUnderstandButton() {
this.closeButtonText = Res.get("shared.iUnderstand"); this.closeButtonText = Res.get("shared.iUnderstand");
//noinspection unchecked return cast();
return (T) this;
} }
public T actionButtonTextWithGoTo(String target) { public T actionButtonTextWithGoTo(String target) {
this.actionButtonText = Res.get("shared.goTo", Res.get(target)); this.actionButtonText = Res.get("shared.goTo", Res.get(target));
//noinspection unchecked return cast();
return (T) this;
} }
public T secondaryActionButtonTextWithGoTo(String target) { public T secondaryActionButtonTextWithGoTo(String target) {
this.secondaryActionButtonText = Res.get("shared.goTo", Res.get(target)); this.secondaryActionButtonText = Res.get("shared.goTo", Res.get(target));
//noinspection unchecked return cast();
return (T) this;
} }
public T closeButtonTextWithGoTo(String target) { public T closeButtonTextWithGoTo(String target) {
this.closeButtonText = Res.get("shared.goTo", Res.get(target)); this.closeButtonText = Res.get("shared.goTo", Res.get(target));
//noinspection unchecked return cast();
return (T) this;
} }
public T actionButtonText(String actionButtonText) { public T actionButtonText(String actionButtonText) {
this.actionButtonText = actionButtonText; this.actionButtonText = actionButtonText;
//noinspection unchecked return cast();
return (T) this;
} }
public T secondaryActionButtonText(String secondaryActionButtonText) { public T secondaryActionButtonText(String secondaryActionButtonText) {
this.secondaryActionButtonText = secondaryActionButtonText; this.secondaryActionButtonText = secondaryActionButtonText;
//noinspection unchecked return cast();
return (T) this;
} }
public T useShutDownButton() { public T useShutDownButton() {
this.actionButtonText = Res.get("shared.shutDown"); this.actionButtonText = Res.get("shared.shutDown");
this.actionHandlerOptional = Optional.ofNullable(BisqApp.getShutDownHandler()); this.actionHandlerOptional = Optional.ofNullable(BisqApp.getShutDownHandler());
//noinspection unchecked return cast();
return (T) this;
} }
public T buttonAlignment(HPos pos) { public T buttonAlignment(HPos pos) {
this.buttonAlignment = pos; this.buttonAlignment = pos;
return (T) this; return cast();
} }
public T width(double width) { public T width(double width) {
this.width = width; this.width = width;
//noinspection unchecked return cast();
return (T) this;
} }
public T maxMessageLength(int maxChar) { public T maxMessageLength(int maxChar) {
this.maxChar = maxChar; this.maxChar = maxChar;
return (T) this; return cast();
} }
public T showBusyAnimation() { public T showBusyAnimation() {
this.showBusyAnimation = true; this.showBusyAnimation = true;
//noinspection unchecked return cast();
return (T) this;
} }
public T dontShowAgainId(String key) { public T dontShowAgainId(String key) {
this.dontShowAgainId = key; this.dontShowAgainId = key;
//noinspection unchecked return cast();
return (T) this;
} }
public T dontShowAgainText(String dontShowAgainText) { public T dontShowAgainText(String dontShowAgainText) {
this.dontShowAgainText = dontShowAgainText; this.dontShowAgainText = dontShowAgainText;
//noinspection unchecked return cast();
return (T) this;
} }
public T hideCloseButton() { public T hideCloseButton() {
this.hideCloseButton = true; this.hideCloseButton = true;
//noinspection unchecked return cast();
return (T) this;
} }
public T useAnimation(boolean useAnimation) { public T useAnimation(boolean useAnimation) {
this.useAnimation = useAnimation; this.useAnimation = useAnimation;
//noinspection unchecked return cast();
return (T) this;
} }
public T setHeadlineStyle(String headlineStyle) { public T setHeadlineStyle(String headlineStyle) {
this.headlineStyle = headlineStyle; this.headlineStyle = headlineStyle;
//noinspection unchecked return cast();
return (T) this;
} }
public T disableActionButton() { public T disableActionButton() {
this.disableActionButton = true; this.disableActionButton = true;
//noinspection unchecked return cast();
return (T) this;
} }

View File

@ -4,7 +4,7 @@ import com.jfoenix.controls.JFXTabPane;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
public abstract class TabbedOverlay<T extends TabbedOverlay> extends Overlay { public abstract class TabbedOverlay<T extends TabbedOverlay<T>> extends Overlay<T> {
protected JFXTabPane tabPane; protected JFXTabPane tabPane;

View File

@ -22,7 +22,8 @@ import bisq.desktop.main.overlays.Overlay;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class Popup<T extends Overlay> extends Overlay<Popup> { // TODO: Type parameter is unused - remove:
public class Popup<T> extends Overlay<Popup<T>> {
protected final Logger log = LoggerFactory.getLogger(this.getClass()); protected final Logger log = LoggerFactory.getLogger(this.getClass());
public Popup() { public Popup() {
@ -41,6 +42,4 @@ public class Popup<T extends Overlay> extends Overlay<Popup> {
protected void onHidden() { protected void onHidden() {
PopupManager.onHidden(this); PopupManager.onHidden(this);
} }
} }

View File

@ -18,8 +18,7 @@
package bisq.desktop.main.portfolio; package bisq.desktop.main.portfolio;
import bisq.desktop.Navigation; import bisq.desktop.Navigation;
import bisq.desktop.common.model.Activatable; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.ActivatableViewAndModel;
import bisq.desktop.common.view.CachingViewLoader; import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View; import bisq.desktop.common.view.View;
@ -50,7 +49,7 @@ import javafx.collections.ListChangeListener;
import java.util.List; import java.util.List;
@FxmlView @FxmlView
public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> { public class PortfolioView extends ActivatableView<TabPane, Void> {
@FXML @FXML
Tab openOffersTab, pendingTradesTab, closedTradesTab; Tab openOffersTab, pendingTradesTab, closedTradesTab;

View File

@ -18,8 +18,7 @@
package bisq.desktop.main.settings; package bisq.desktop.main.settings;
import bisq.desktop.Navigation; import bisq.desktop.Navigation;
import bisq.desktop.common.model.Activatable; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.ActivatableViewAndModel;
import bisq.desktop.common.view.CachingViewLoader; import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View; import bisq.desktop.common.view.View;
@ -42,7 +41,7 @@ import javafx.scene.control.TabPane;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
@FxmlView @FxmlView
public class SettingsView extends ActivatableViewAndModel<TabPane, Activatable> { public class SettingsView extends ActivatableView<TabPane, Void> {
@FXML @FXML
Tab preferencesTab, networkTab, aboutTab; Tab preferencesTab, networkTab, aboutTab;
private final ViewLoader viewLoader; private final ViewLoader viewLoader;

View File

@ -17,8 +17,7 @@
package bisq.desktop.main.settings.about; package bisq.desktop.main.settings.about;
import bisq.desktop.common.model.Activatable; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.ActivatableViewAndModel;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.components.HyperlinkWithIcon;
import bisq.desktop.components.TitledGroupBg; import bisq.desktop.components.TitledGroupBg;
@ -41,7 +40,7 @@ import static bisq.desktop.util.FormBuilder.addLabel;
import static bisq.desktop.util.FormBuilder.addTitledGroupBg; import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
@FxmlView @FxmlView
public class AboutView extends ActivatableViewAndModel<GridPane, Activatable> { public class AboutView extends ActivatableView<GridPane, Void> {
private int gridRow = 0; private int gridRow = 0;

View File

@ -18,8 +18,7 @@
package bisq.desktop.main.settings.network; package bisq.desktop.main.settings.network;
import bisq.desktop.app.BisqApp; import bisq.desktop.app.BisqApp;
import bisq.desktop.common.model.Activatable; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.ActivatableViewAndModel;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.components.AutoTooltipButton; import bisq.desktop.components.AutoTooltipButton;
import bisq.desktop.components.AutoTooltipLabel; import bisq.desktop.components.AutoTooltipLabel;
@ -74,7 +73,7 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@FxmlView @FxmlView
public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activatable> { public class NetworkSettingsView extends ActivatableView<GridPane, Void> {
@FXML @FXML
TitledGroupBg p2pHeader, btcHeader; TitledGroupBg p2pHeader, btcHeader;

View File

@ -18,8 +18,7 @@
package bisq.desktop.main.support; package bisq.desktop.main.support;
import bisq.desktop.Navigation; import bisq.desktop.Navigation;
import bisq.desktop.common.model.Activatable; import bisq.desktop.common.view.ActivatableView;
import bisq.desktop.common.view.ActivatableViewAndModel;
import bisq.desktop.common.view.CachingViewLoader; import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.FxmlView; import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View; import bisq.desktop.common.view.View;
@ -62,7 +61,7 @@ import javafx.beans.value.ChangeListener;
import javafx.collections.MapChangeListener; import javafx.collections.MapChangeListener;
@FxmlView @FxmlView
public class SupportView extends ActivatableViewAndModel<TabPane, Activatable> { public class SupportView extends ActivatableView<TabPane, Void> {
@FXML @FXML
Tab tradersMediationDisputesTab, tradersRefundDisputesTab, tradersArbitrationDisputesTab; Tab tradersMediationDisputesTab, tradersRefundDisputesTab, tradersArbitrationDisputesTab;

View File

@ -188,11 +188,8 @@ public class GUIUtil {
}); });
} }
@SuppressWarnings("PointlessBooleanExpression")
public static void showFeeInfoBeforeExecute(Runnable runnable) { public static void showFeeInfoBeforeExecute(Runnable runnable) {
//noinspection UnusedAssignment
String key = "miningFeeInfo"; String key = "miningFeeInfo";
//noinspection ConstantConditions,ConstantConditions
if (!DevEnv.isDevMode() && DontShowAgainLookup.showAgain(key)) { if (!DevEnv.isDevMode() && DontShowAgainLookup.showAgain(key)) {
new Popup<>().attention(Res.get("guiUtil.miningFeeInfo", String.valueOf(GUIUtil.feeService.getTxFeePerByte().value))) new Popup<>().attention(Res.get("guiUtil.miningFeeInfo", String.valueOf(GUIUtil.feeService.getTxFeePerByte().value)))
.onClose(runnable) .onClose(runnable)
@ -682,8 +679,7 @@ public class GUIUtil {
parent = parent.getParent(); parent = parent.getParent();
} }
} }
//noinspection unchecked return t.cast(parent);
return parent != null ? (T) parent : null;
} }
public static void showClearXchangeWarning() { public static void showClearXchangeWarning() {

View File

@ -0,0 +1,47 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.overlays;
import org.junit.Test;
public class OverlayTest {
@Test
public void typeSafeCreation() {
new A();
new C();
new D<>();
}
@Test(expected = RuntimeException.class)
public void typeUnsafeCreation() {
new B();
}
private static class A extends Overlay<A> {
}
private static class B extends Overlay<A> {
}
private static class C extends TabbedOverlay<C> {
}
private static class D<T> extends Overlay<D<T>> {
}
}

View File

@ -68,7 +68,7 @@ public class P2PMarketStats extends P2PSeedNodeSnapshotBase {
private final Set<byte[]> hashes = new TreeSet<>(Arrays::compare); private final Set<byte[]> hashes = new TreeSet<>(Arrays::compare);
final Map<NodeAddress, Statistics> versionBucketsPerHost = new ConcurrentHashMap<>(); final Map<NodeAddress, Statistics<Counter>> versionBucketsPerHost = new ConcurrentHashMap<>();
/** /**
* Efficient way to count occurrences. * Efficient way to count occurrences.
@ -189,13 +189,13 @@ public class P2PMarketStats extends P2PSeedNodeSnapshotBase {
@Override @Override
protected void report() { protected void report() {
Map<String, String> report = new HashMap<>(); Map<String, String> report = new HashMap<>();
bucketsPerHost.forEach((host, statistics) -> statistics.values().forEach((market, numberOfOffers) -> report.put(OnionParser.prettyPrint(host) + "." + market.toString(), String.valueOf(((Counter) numberOfOffers).value())))); bucketsPerHost.forEach((host, statistics) -> statistics.values().forEach((market, numberOfOffers) -> report.put(OnionParser.prettyPrint(host) + "." + market, String.valueOf(((Counter) numberOfOffers).value()))));
reporter.report(report, getName()); reporter.report(report, getName());
// do version statistics // do version statistics
report.clear(); report.clear();
versionBucketsPerHost.values().stream().findAny().get().values().forEach((version, numberOfOccurrences) -> report.put(version.toString(), String.valueOf(((Counter) numberOfOccurrences).value()))); versionBucketsPerHost.values().stream().findAny().get().values().forEach((version, numberOfOccurrences) -> report.put(version, String.valueOf(numberOfOccurrences.value())));
reporter.report(report, "versions"); reporter.report(report, "versions");
} }

View File

@ -84,7 +84,7 @@ public class P2PSeedNodeSnapshot extends P2PSeedNodeSnapshotBase {
private static final String DATABASE_DIR = "run.dbDir"; private static final String DATABASE_DIR = "run.dbDir";
Statistics statistics; Statistics statistics;
final Map<NodeAddress, Statistics> bucketsPerHost = new ConcurrentHashMap<>(); final Map<NodeAddress, Statistics<Set<Integer>>> bucketsPerHost = new ConcurrentHashMap<>();
protected final Set<byte[]> hashes = new TreeSet<>(Arrays::compare); protected final Set<byte[]> hashes = new TreeSet<>(Arrays::compare);
private int daostateheight = 594000; private int daostateheight = 594000;
private int proposalheight = daostateheight; private int proposalheight = daostateheight;
@ -174,19 +174,19 @@ public class P2PSeedNodeSnapshot extends P2PSeedNodeSnapshotBase {
Map<String, String> report = new HashMap<>(); Map<String, String> report = new HashMap<>();
// - assemble histograms // - assemble histograms
bucketsPerHost.forEach((host, statistics) -> statistics.values().forEach((type, set) -> report bucketsPerHost.forEach((host, statistics) -> statistics.values().forEach((type, set) -> report
.put(OnionParser.prettyPrint(host) + ".numberOfMessages." + type, Integer.toString(((Set) set).size())))); .put(OnionParser.prettyPrint(host) + ".numberOfMessages." + type, Integer.toString(set.size()))));
// - assemble diffs // - assemble diffs
// - transfer values // - transfer values
Map<String, Statistics> messagesPerHost = new HashMap<>(); Map<String, Statistics<Set<Integer>>> messagesPerHost = new HashMap<>();
bucketsPerHost.forEach((host, value) -> messagesPerHost.put(OnionParser.prettyPrint(host), value)); bucketsPerHost.forEach((host, value) -> messagesPerHost.put(OnionParser.prettyPrint(host), value));
// - pick reference seed node and its values // - pick reference seed node and its values
String referenceHost = "overall_number_of_unique_messages"; String referenceHost = "overall_number_of_unique_messages";
Map<String, Set<Object>> referenceValues = new HashMap<>(); Map<String, Set<Object>> referenceValues = new HashMap<>();
messagesPerHost.forEach((host, statistics) -> statistics.values().forEach((type, set) -> { messagesPerHost.forEach((host, statistics) -> statistics.values().forEach((type, set) -> {
referenceValues.putIfAbsent((String) type, new HashSet<>()); referenceValues.putIfAbsent(type, new HashSet<>());
referenceValues.get(type).addAll((Set) set); referenceValues.get(type).addAll(set);
})); }));
// - calculate diffs // - calculate diffs
@ -195,7 +195,7 @@ public class P2PSeedNodeSnapshot extends P2PSeedNodeSnapshotBase {
statistics.values().forEach((messageType, set) -> { statistics.values().forEach((messageType, set) -> {
try { try {
report.put(OnionParser.prettyPrint(host) + ".relativeNumberOfMessages." + messageType, report.put(OnionParser.prettyPrint(host) + ".relativeNumberOfMessages." + messageType,
String.valueOf(((Set) set).size() - referenceValues.get(messageType).size())); String.valueOf(set.size() - referenceValues.get(messageType).size()));
} catch (MalformedURLException | NullPointerException ignore) { } catch (MalformedURLException | NullPointerException ignore) {
log.error("we should never have gotten here", ignore); log.error("we should never have gotten here", ignore);
} }
@ -223,8 +223,8 @@ public class P2PSeedNodeSnapshot extends P2PSeedNodeSnapshotBase {
// - transcode // - transcode
Map<String, Map<NodeAddress, Tuple>> perType = new HashMap<>(); Map<String, Map<NodeAddress, Tuple>> perType = new HashMap<>();
daoData.forEach((nodeAddress, daostatistics) -> daostatistics.values().forEach((type, tuple) -> { daoData.forEach((nodeAddress, daostatistics) -> daostatistics.values().forEach((type, tuple) -> {
perType.putIfAbsent((String) type, new HashMap<>()); perType.putIfAbsent(type, new HashMap<>());
perType.get(type).put(nodeAddress, (Tuple) tuple); perType.get(type).put(nodeAddress, tuple);
})); }));
// - process dao data // - process dao data
@ -311,7 +311,7 @@ public class P2PSeedNodeSnapshot extends P2PSeedNodeSnapshotBase {
} }
} }
private Map<NodeAddress, Statistics> daoData = new ConcurrentHashMap<>(); private Map<NodeAddress, Statistics<Tuple>> daoData = new ConcurrentHashMap<>();
protected boolean treatMessage(NetworkEnvelope networkEnvelope, Connection connection) { protected boolean treatMessage(NetworkEnvelope networkEnvelope, Connection connection) {
checkNotNull(connection.getPeersNodeAddressProperty(), checkNotNull(connection.getPeersNodeAddressProperty(),

View File

@ -65,7 +65,7 @@ public abstract class P2PSeedNodeSnapshotBase extends Metric implements MessageL
private static final String HOSTS = "run.hosts"; private static final String HOSTS = "run.hosts";
private static final String TOR_PROXY_PORT = "run.torProxyPort"; private static final String TOR_PROXY_PORT = "run.torProxyPort";
Statistics statistics; Statistics statistics;
final Map<NodeAddress, Statistics> bucketsPerHost = new ConcurrentHashMap<>(); final Map<NodeAddress, Statistics<?>> bucketsPerHost = new ConcurrentHashMap<>();
private final ThreadGate gate = new ThreadGate(); private final ThreadGate gate = new ThreadGate();
/** /**