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.LoggerContext;
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.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
@ -38,7 +39,7 @@ public class Log {
public static void setup(String fileName) {
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
RollingFileAppender appender = new RollingFileAppender();
RollingFileAppender<ILoggingEvent> appender = new RollingFileAppender<>();
appender.setContext(loggerContext);
appender.setFile(fileName + ".log");
@ -50,7 +51,7 @@ public class Log {
rollingPolicy.setMaxIndex(10);
rollingPolicy.start();
SizeBasedTriggeringPolicy triggeringPolicy = new SizeBasedTriggeringPolicy();
SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = new SizeBasedTriggeringPolicy<>();
triggeringPolicy.setMaxFileSize(FileSize.valueOf("10MB"));
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.start();
//noinspection unchecked
appender.setEncoder(encoder);
appender.setRollingPolicy(rollingPolicy);
//noinspection unchecked
appender.setTriggeringPolicy(triggeringPolicy);
appender.start();
logbackLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
//noinspection unchecked
logbackLogger.addAppender(appender);
logbackLogger.setLevel(Level.INFO);

View File

@ -77,15 +77,14 @@ public class ProtoUtil {
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()
.map(e -> {
final Message message = e.toProtoMessage();
try {
//noinspection unchecked
return (T) message;
} catch (Throwable t) {
log.error("message could not be casted. message=" + message);
return messageType.cast(message);
} catch (ClassCastException t) {
log.error("Message could not be cast. message={}, messageType={}", message, messageType);
return null;
}
})

View File

@ -361,11 +361,11 @@ public class BisqEnvironment extends StandardEnvironment {
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;
}
private List<String> getListProperty (String key, List defaultValue) {
private List<String> getListProperty(String key, List<String> defaultValue) {
final String value = getProperty(key, "");
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.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@ -465,7 +466,7 @@ public class WalletConfig extends AbstractIdleService {
vPeerGroup.startBlockChainDownload(listener);
listener.await();
} else {
Futures.addCallback(vPeerGroup.startAsync(), new FutureCallback() {
Futures.addCallback((ListenableFuture<?>) vPeerGroup.startAsync(), new FutureCallback<Object>() {
@Override
public void onSuccess(@Nullable Object result) {
final PeerDataEventListener listener = downloadListener == null ?
@ -476,7 +477,6 @@ public class WalletConfig extends AbstractIdleService {
@Override
public void onFailure(@NotNull Throwable t) {
throw new RuntimeException(t);
}
});
}

View File

@ -91,7 +91,7 @@ public abstract class PaymentAccount implements PersistablePayload {
.setCreationDate(creationDate)
.setPaymentAccountPayload((protobuf.PaymentAccountPayload) paymentAccountPayload.toProtoMessage())
.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()));
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 {
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<>();
tsMap.put("bitcoinFeesTs", ((Double) linkedTreeMap.get("bitcoinFeesTs")).longValue());
Map<String, Long> map = new HashMap<>();
try {
//noinspection unchecked
LinkedTreeMap<String, Double> dataMap = (LinkedTreeMap<String, Double>) linkedTreeMap.get("dataMap");
Long btcTxFee = dataMap.get("btcTxFee").longValue();
LinkedTreeMap<?, ?> dataMap = (LinkedTreeMap<?, ?>) linkedTreeMap.get("dataMap");
Long btcTxFee = ((Double) dataMap.get("btcTxFee")).longValue();
map.put("BTC", btcTxFee);
} catch (Throwable t) {

View File

@ -50,20 +50,20 @@ public class PriceProvider extends HttpClientProvider {
String json = httpClient.requestWithGET("getAllMarketPrices", "User-Agent", "bisq/"
+ 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<>();
tsMap.put("btcAverageTs", ((Double) map.get("btcAverageTs")).longValue());
tsMap.put("poloniexTs", ((Double) map.get("poloniexTs")).longValue());
tsMap.put("coinmarketcapTs", ((Double) map.get("coinmarketcapTs")).longValue());
//noinspection unchecked
List<LinkedTreeMap<String, Object>> list = (ArrayList<LinkedTreeMap<String, Object>>) map.get("data");
list.forEach(treeMap -> {
List<?> list = (ArrayList<?>) map.get("data");
list.forEach(obj -> {
try {
LinkedTreeMap<?, ?> treeMap = (LinkedTreeMap<?, ?>) obj;
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...
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));
} catch (Throwable t) {
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"));
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,

View File

@ -67,7 +67,7 @@ public final class MediationDisputeList extends DisputeList<MediationDisputeList
@Override
public Message toProtoMessage() {
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,

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"));
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,

View File

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

View File

@ -188,7 +188,8 @@ public class ProcessModel implements Model, PersistablePayload {
Optional.ofNullable(takeOfferFeeTxId).ifPresent(builder::setTakeOfferFeeTxId);
Optional.ofNullable(payoutTxSignature).ifPresent(e -> builder.setPayoutTxSignature(ByteString.copyFrom(payoutTxSignature)));
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(myMultiSigPubKey).ifPresent(e -> builder.setMyMultiSigPubKey(ByteString.copyFrom(myMultiSigPubKey)));
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(pubKeyRing).ifPresent(e -> builder.setPubKeyRing(e.toProtoMessage()));
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(accountAgeWitnessNonce).ifPresent(e -> builder.setAccountAgeWitnessNonce(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();
Optional.ofNullable(accountId).ifPresent(e -> builder.setAccountId(accountId));
Optional.ofNullable(paymentAccounts)
.ifPresent(e -> builder.addAllPaymentAccounts(ProtoUtil.collectionToProto(paymentAccounts)));
.ifPresent(e -> builder.addAllPaymentAccounts(ProtoUtil.collectionToProto(paymentAccounts, protobuf.PaymentAccount.class)));
Optional.ofNullable(currentPaymentAccount)
.ifPresent(e -> builder.setCurrentPaymentAccount(currentPaymentAccount.toProtoMessage()));
Optional.ofNullable(acceptedLanguageLocaleCodes)
@ -111,7 +111,7 @@ public class UserPayload implements PersistableEnvelope {
message -> ((protobuf.StoragePayload) message).getMediator())));
Optional.ofNullable(priceAlertFilter).ifPresent(priceAlertFilter -> builder.setPriceAlertFilter(priceAlertFilter.toProtoMessage()));
Optional.ofNullable(marketAlertFilters)
.ifPresent(e -> builder.addAllMarketAlertFilters(ProtoUtil.collectionToProto(marketAlertFilters)));
.ifPresent(e -> builder.addAllMarketAlertFilters(ProtoUtil.collectionToProto(marketAlertFilters, protobuf.MarketAlertFilter.class)));
Optional.ofNullable(registeredRefundAgent)
.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()
.map(className -> {
try {
//noinspection unchecked
return ((Class<? extends View>) Class.forName(className));
return (Class<? extends View>) Class.forName(className).asSubclass(View.class);
} catch (ClassNotFoundException 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);
temp.add(viewClass);
if (currentPath == null ||
(currentPath != null &&
currentPath.size() > i &&
(currentPath.size() > i &&
viewClass != currentPath.get(i) &&
i != newPath.size() - 1)) {
ArrayList<Class<? extends View>> temp2 = new ArrayList<>(temp);
for (int n = i + 1; n < newPath.size(); n++) {
//noinspection unchecked,unchecked,unchecked
//noinspection unchecked
Class<? extends View>[] newTemp = new Class[i + 1];
currentPath = ViewPath.to(temp2.toArray(newTemp));
navigateTo(currentPath, data);

View File

@ -22,16 +22,4 @@ public interface Activatable {
void _activate();
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"));
}
public ActivatableViewAndModel() {
//noinspection unchecked
this((M) Activatable.NO_OP_INSTANCE);
}
@Override
protected void prepareInitialize() {
if (root != null) {

View File

@ -46,7 +46,7 @@ import java.util.List;
public class AutocompleteComboBox<T> extends JFXComboBox<T> {
private ArrayList<T> completeList;
private ArrayList<T> matchingList;
private JFXComboBoxListViewSkin comboBoxListViewSkin;
private JFXComboBoxListViewSkin<T> comboBoxListViewSkin;
public AutocompleteComboBox() {
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().
*/
public void setAutocompleteItems(List<T> items) {
public void setAutocompleteItems(List<? extends T> items) {
completeList = new ArrayList<>(items);
matchingList = new ArrayList<>(completeList);
setValue(null);

View File

@ -211,10 +211,11 @@ public class AssetsForm extends PaymentMethodForm {
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.setConverter(new StringConverter<TradeCurrency>() {
currencyComboBox.setConverter(new StringConverter<>() {
@Override
public String toString(TradeCurrency tradeCurrency) {
return tradeCurrency != null ? tradeCurrency.getNameAndCode() : "";
@ -223,12 +224,12 @@ public class AssetsForm extends PaymentMethodForm {
@Override
public TradeCurrency fromString(String s) {
return currencyComboBox.getItems().stream().
filter(item -> item.getNameAndCode().equals(s)).
findAny().orElse(null);
filter(item -> item.getNameAndCode().equals(s)).
findAny().orElse(null);
}
});
((AutocompleteComboBox) currencyComboBox).setOnChangeConfirmed(e -> {
((AutocompleteComboBox<?>) currencyComboBox).setOnChangeConfirmed(e -> {
addressInputTextField.resetValidation();
addressInputTextField.validate();
paymentAccount.setSingleTradeCurrency(currencyComboBox.getSelectionModel().getSelectedItem());

View File

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

View File

@ -32,6 +32,7 @@ import bisq.desktop.util.Layout;
import bisq.core.app.AppOptionKeys;
import bisq.core.locale.LanguageUtil;
import bisq.core.locale.Res;
import bisq.core.support.dispute.agent.DisputeAgent;
import bisq.common.UserThread;
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.
// Lets do it for 1.1.7 the translator have time to add new string.
@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 ListView<String> languagesListView;

View File

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

View File

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

View File

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

View File

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

View File

@ -105,7 +105,7 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
private ChangeListener<Number> priceChangeListener;
private AreaChart bsqPriceChart;
private AreaChart<Number, Number> bsqPriceChart;
private XYChart.Series<Number, Number> seriesBSQPrice;
private TextField avgPrice90TextField, marketCapTextField, availableAmountTextField;
@ -254,7 +254,7 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
bsqPriceChart.setPrefHeight(bsqPriceChart.getMinHeight());
bsqPriceChart.setCreateSymbols(true);
bsqPriceChart.setPadding(new Insets(0));
bsqPriceChart.getData().addAll(seriesBSQPrice);
bsqPriceChart.getData().add(seriesBSQPrice);
AnchorPane chartPane = new AnchorPane();
chartPane.getStyleClass().add("chart-pane");
@ -368,7 +368,7 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
long average = getAverage(bsqTradePast90Days);
Coin oneBsq = Coin.valueOf(100);
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");
textField.setText(avg + " BSQ/BTC (" + "1 BSQ = " + bsqInUsdAvg + ")");
return average;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -121,7 +121,7 @@ import org.jetbrains.annotations.NotNull;
import static bisq.desktop.util.FormBuilder.*;
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";
protected final Navigation navigation;
private final Preferences preferences;
@ -438,7 +438,6 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel> extends
balanceTextField.setTargetAmount(model.getDataModel().totalToPayAsCoinProperty().get());
//noinspection PointlessBooleanExpression
if (!DevEnv.isDevMode()) {
String key = "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.locale.GlobalSettings;
import bisq.core.locale.LanguageUtil;
import bisq.core.locale.Res;
import bisq.core.user.DontShowAgainLookup;
import bisq.core.locale.LanguageUtil;
import bisq.common.Timer;
import bisq.common.UserThread;
import bisq.common.util.Utilities;
import com.google.common.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import de.jensd.fx.fontawesome.AwesomeIcon;
@ -68,8 +70,8 @@ import javafx.scene.transform.Rotate;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.NodeOrientation;
import javafx.geometry.Pos;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
@ -93,7 +95,7 @@ import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public abstract class Overlay<T extends Overlay> {
public abstract class Overlay<T extends Overlay<T>> {
///////////////////////////////////////////////////////////////////////////////////////////
// Enum
@ -185,12 +187,23 @@ public abstract class Overlay<T extends Overlay> {
protected int maxChar = 1800;
private T cast() {
//noinspection unchecked
return (T) this;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public API
///////////////////////////////////////////////////////////////////////////////////////////
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) {
@ -266,26 +279,22 @@ public abstract class Overlay<T extends Overlay> {
public T onClose(Runnable closeHandler) {
this.closeHandlerOptional = Optional.of(closeHandler);
//noinspection unchecked
return (T) this;
return cast();
}
public T onAction(Runnable actionHandler) {
this.actionHandlerOptional = Optional.of(actionHandler);
//noinspection unchecked
return (T) this;
return cast();
}
public T onSecondaryAction(Runnable secondaryActionHandlerOptional) {
this.secondaryActionHandlerOptional = Optional.of(secondaryActionHandlerOptional);
//noinspection unchecked
return (T) this;
return cast();
}
public T headLine(String headLine) {
this.headLine = headLine;
//noinspection unchecked
return (T) this;
return cast();
}
public T notification(String message) {
@ -294,8 +303,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.notification");
this.message = message;
setTruncatedMessage();
//noinspection unchecked
return (T) this;
return cast();
}
public T instruction(String message) {
@ -304,8 +312,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.instruction");
this.message = message;
setTruncatedMessage();
//noinspection unchecked
return (T) this;
return cast();
}
public T attention(String message) {
@ -314,8 +321,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.attention");
this.message = message;
setTruncatedMessage();
//noinspection unchecked
return (T) this;
return cast();
}
public T backgroundInfo(String message) {
@ -324,8 +330,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.backgroundInfo");
this.message = message;
setTruncatedMessage();
//noinspection unchecked
return (T) this;
return cast();
}
public T feedback(String message) {
@ -334,8 +339,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.feedback");
this.message = message;
setTruncatedMessage();
//noinspection unchecked
return (T) this;
return cast();
}
public T confirmation(String message) {
@ -344,8 +348,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.confirmation");
this.message = message;
setTruncatedMessage();
//noinspection unchecked
return (T) this;
return cast();
}
public T information(String message) {
@ -354,8 +357,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.information");
this.message = message;
setTruncatedMessage();
//noinspection unchecked
return (T) this;
return cast();
}
public T warning(String message) {
@ -365,8 +367,7 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.warning");
this.message = message;
setTruncatedMessage();
//noinspection unchecked
return (T) this;
return cast();
}
public T error(String message) {
@ -377,136 +378,116 @@ public abstract class Overlay<T extends Overlay> {
this.headLine = Res.get("popup.headline.error");
this.message = message;
setTruncatedMessage();
//noinspection unchecked
return (T) this;
return cast();
}
@SuppressWarnings("UnusedReturnValue")
public T showReportErrorButtons() {
this.showReportErrorButtons = true;
//noinspection unchecked
return (T) this;
return cast();
}
public T message(String message) {
this.message = message;
setTruncatedMessage();
//noinspection unchecked
return (T) this;
return cast();
}
public T closeButtonText(String closeButtonText) {
this.closeButtonText = closeButtonText;
//noinspection unchecked
return (T) this;
return cast();
}
public T useReportBugButton() {
this.closeButtonText = Res.get("shared.reportBug");
this.closeHandlerOptional = Optional.of(() -> GUIUtil.openWebPage("https://bisq.network/source/bisq/issues"));
//noinspection unchecked
return (T) this;
return cast();
}
public T useIUnderstandButton() {
this.closeButtonText = Res.get("shared.iUnderstand");
//noinspection unchecked
return (T) this;
return cast();
}
public T actionButtonTextWithGoTo(String target) {
this.actionButtonText = Res.get("shared.goTo", Res.get(target));
//noinspection unchecked
return (T) this;
return cast();
}
public T secondaryActionButtonTextWithGoTo(String target) {
this.secondaryActionButtonText = Res.get("shared.goTo", Res.get(target));
//noinspection unchecked
return (T) this;
return cast();
}
public T closeButtonTextWithGoTo(String target) {
this.closeButtonText = Res.get("shared.goTo", Res.get(target));
//noinspection unchecked
return (T) this;
return cast();
}
public T actionButtonText(String actionButtonText) {
this.actionButtonText = actionButtonText;
//noinspection unchecked
return (T) this;
return cast();
}
public T secondaryActionButtonText(String secondaryActionButtonText) {
this.secondaryActionButtonText = secondaryActionButtonText;
//noinspection unchecked
return (T) this;
return cast();
}
public T useShutDownButton() {
this.actionButtonText = Res.get("shared.shutDown");
this.actionHandlerOptional = Optional.ofNullable(BisqApp.getShutDownHandler());
//noinspection unchecked
return (T) this;
return cast();
}
public T buttonAlignment(HPos pos) {
this.buttonAlignment = pos;
return (T) this;
return cast();
}
public T width(double width) {
this.width = width;
//noinspection unchecked
return (T) this;
return cast();
}
public T maxMessageLength(int maxChar) {
this.maxChar = maxChar;
return (T) this;
return cast();
}
public T showBusyAnimation() {
this.showBusyAnimation = true;
//noinspection unchecked
return (T) this;
return cast();
}
public T dontShowAgainId(String key) {
this.dontShowAgainId = key;
//noinspection unchecked
return (T) this;
return cast();
}
public T dontShowAgainText(String dontShowAgainText) {
this.dontShowAgainText = dontShowAgainText;
//noinspection unchecked
return (T) this;
return cast();
}
public T hideCloseButton() {
this.hideCloseButton = true;
//noinspection unchecked
return (T) this;
return cast();
}
public T useAnimation(boolean useAnimation) {
this.useAnimation = useAnimation;
//noinspection unchecked
return (T) this;
return cast();
}
public T setHeadlineStyle(String headlineStyle) {
this.headlineStyle = headlineStyle;
//noinspection unchecked
return (T) this;
return cast();
}
public T disableActionButton() {
this.disableActionButton = true;
//noinspection unchecked
return (T) this;
return cast();
}

View File

@ -4,7 +4,7 @@ import com.jfoenix.controls.JFXTabPane;
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;

View File

@ -22,7 +22,8 @@ import bisq.desktop.main.overlays.Overlay;
import org.slf4j.Logger;
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());
public Popup() {
@ -41,6 +42,4 @@ public class Popup<T extends Overlay> extends Overlay<Popup> {
protected void onHidden() {
PopupManager.onHidden(this);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -188,11 +188,8 @@ public class GUIUtil {
});
}
@SuppressWarnings("PointlessBooleanExpression")
public static void showFeeInfoBeforeExecute(Runnable runnable) {
//noinspection UnusedAssignment
String key = "miningFeeInfo";
//noinspection ConstantConditions,ConstantConditions
if (!DevEnv.isDevMode() && DontShowAgainLookup.showAgain(key)) {
new Popup<>().attention(Res.get("guiUtil.miningFeeInfo", String.valueOf(GUIUtil.feeService.getTxFeePerByte().value)))
.onClose(runnable)
@ -682,8 +679,7 @@ public class GUIUtil {
parent = parent.getParent();
}
}
//noinspection unchecked
return parent != null ? (T) parent : null;
return t.cast(parent);
}
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);
final Map<NodeAddress, Statistics> versionBucketsPerHost = new ConcurrentHashMap<>();
final Map<NodeAddress, Statistics<Counter>> versionBucketsPerHost = new ConcurrentHashMap<>();
/**
* Efficient way to count occurrences.
@ -189,13 +189,13 @@ public class P2PMarketStats extends P2PSeedNodeSnapshotBase {
@Override
protected void report() {
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());
// do version statistics
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");
}

View File

@ -84,7 +84,7 @@ public class P2PSeedNodeSnapshot extends P2PSeedNodeSnapshotBase {
private static final String DATABASE_DIR = "run.dbDir";
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);
private int daostateheight = 594000;
private int proposalheight = daostateheight;
@ -174,19 +174,19 @@ public class P2PSeedNodeSnapshot extends P2PSeedNodeSnapshotBase {
Map<String, String> report = new HashMap<>();
// - assemble histograms
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
// - 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));
// - pick reference seed node and its values
String referenceHost = "overall_number_of_unique_messages";
Map<String, Set<Object>> referenceValues = new HashMap<>();
messagesPerHost.forEach((host, statistics) -> statistics.values().forEach((type, set) -> {
referenceValues.putIfAbsent((String) type, new HashSet<>());
referenceValues.get(type).addAll((Set) set);
referenceValues.putIfAbsent(type, new HashSet<>());
referenceValues.get(type).addAll(set);
}));
// - calculate diffs
@ -195,7 +195,7 @@ public class P2PSeedNodeSnapshot extends P2PSeedNodeSnapshotBase {
statistics.values().forEach((messageType, set) -> {
try {
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) {
log.error("we should never have gotten here", ignore);
}
@ -223,8 +223,8 @@ public class P2PSeedNodeSnapshot extends P2PSeedNodeSnapshotBase {
// - transcode
Map<String, Map<NodeAddress, Tuple>> perType = new HashMap<>();
daoData.forEach((nodeAddress, daostatistics) -> daostatistics.values().forEach((type, tuple) -> {
perType.putIfAbsent((String) type, new HashMap<>());
perType.get(type).put(nodeAddress, (Tuple) tuple);
perType.putIfAbsent(type, new HashMap<>());
perType.get(type).put(nodeAddress, tuple);
}));
// - 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) {
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 TOR_PROXY_PORT = "run.torProxyPort";
Statistics statistics;
final Map<NodeAddress, Statistics> bucketsPerHost = new ConcurrentHashMap<>();
final Map<NodeAddress, Statistics<?>> bucketsPerHost = new ConcurrentHashMap<>();
private final ThreadGate gate = new ThreadGate();
/**