mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-01-19 05:33:44 +01:00
walletfx: Introduce OverlayWindowController interface
Rationale: 1. Stronger typing makes code more readable and refactorable 2. Eliminates “automatic” reflection in MainController 3. Makes overlayUI field in implementing classes private 4. Is a step towards further refactoring and reusability
This commit is contained in:
parent
17aeea2d75
commit
44ca7f6689
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright by the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.bitcoinj.walletfx.overlay;
|
||||||
|
|
||||||
|
import wallettemplate.MainController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for controllers displayed via OverlayWindow.OverlayUI
|
||||||
|
*/
|
||||||
|
public interface OverlayWindowController<T> {
|
||||||
|
/**
|
||||||
|
* @param ui The overlay UI (node, controller pair)
|
||||||
|
*/
|
||||||
|
void setOverlayUI(MainController.OverlayUI<? extends OverlayWindowController<T>> ui);
|
||||||
|
}
|
@ -36,12 +36,12 @@ import javafx.scene.control.Button;
|
|||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
import org.bitcoinj.walletfx.overlay.OverlayWindowController;
|
||||||
import org.bitcoinj.walletfx.utils.GuiUtils;
|
import org.bitcoinj.walletfx.utils.GuiUtils;
|
||||||
import org.bitcoinj.walletfx.utils.TextFieldValidator;
|
import org.bitcoinj.walletfx.utils.TextFieldValidator;
|
||||||
import wallettemplate.controls.ClickableBitcoinAddress;
|
import wallettemplate.controls.ClickableBitcoinAddress;
|
||||||
import wallettemplate.controls.NotificationBarPane;
|
import wallettemplate.controls.NotificationBarPane;
|
||||||
import org.bitcoinj.walletfx.utils.BitcoinUIModel;
|
import org.bitcoinj.walletfx.utils.BitcoinUIModel;
|
||||||
import org.bitcoinj.walletfx.utils.GuiUtils;
|
|
||||||
import org.bitcoinj.walletfx.utils.easing.EasingMode;
|
import org.bitcoinj.walletfx.utils.easing.EasingMode;
|
||||||
import org.bitcoinj.walletfx.utils.easing.ElasticInterpolator;
|
import org.bitcoinj.walletfx.utils.easing.ElasticInterpolator;
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ public class MainController {
|
|||||||
return model.getDownloadProgressTracker();
|
return model.getDownloadProgressTracker();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OverlayUI<T> {
|
public class OverlayUI<T extends OverlayWindowController<T>> {
|
||||||
public Node ui;
|
public Node ui;
|
||||||
public T controller;
|
public T controller;
|
||||||
|
|
||||||
@ -219,22 +219,18 @@ public class MainController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private OverlayUI currentOverlay;
|
private OverlayUI<? extends OverlayWindowController<?>> currentOverlay;
|
||||||
|
|
||||||
public <T> OverlayUI<T> overlayUI(Node node, T controller) {
|
public <T extends OverlayWindowController<T>> OverlayUI<T> overlayUI(Node node, T controller) {
|
||||||
checkGuiThread();
|
checkGuiThread();
|
||||||
OverlayUI<T> pair = new OverlayUI<>(node, controller);
|
OverlayUI<T> pair = new OverlayUI<>(node, controller);
|
||||||
// Auto-magically set the overlayUI member, if it's there.
|
controller.setOverlayUI(pair);
|
||||||
try {
|
|
||||||
controller.getClass().getField("overlayUI").set(controller, pair);
|
|
||||||
} catch (IllegalAccessException | NoSuchFieldException ignored) {
|
|
||||||
}
|
|
||||||
pair.show();
|
pair.show();
|
||||||
return pair;
|
return pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Loads the FXML file with the given name, blurs out the main UI and puts this one on top. */
|
/** Loads the FXML file with the given name, blurs out the main UI and puts this one on top. */
|
||||||
public <T> OverlayUI<T> overlayUI(String name) {
|
public <T extends OverlayWindowController<T>> OverlayUI<T> overlayUI(String name) {
|
||||||
try {
|
try {
|
||||||
checkGuiThread();
|
checkGuiThread();
|
||||||
// Load the UI from disk.
|
// Load the UI from disk.
|
||||||
@ -243,13 +239,7 @@ public class MainController {
|
|||||||
Pane ui = loader.load();
|
Pane ui = loader.load();
|
||||||
T controller = loader.getController();
|
T controller = loader.getController();
|
||||||
OverlayUI<T> pair = new OverlayUI<>(ui, controller);
|
OverlayUI<T> pair = new OverlayUI<>(ui, controller);
|
||||||
// Auto-magically set the overlayUI member, if it's there.
|
controller.setOverlayUI(pair);
|
||||||
try {
|
|
||||||
if (controller != null)
|
|
||||||
controller.getClass().getField("overlayUI").set(controller, pair);
|
|
||||||
} catch (IllegalAccessException | NoSuchFieldException ignored) {
|
|
||||||
ignored.printStackTrace();
|
|
||||||
}
|
|
||||||
pair.show();
|
pair.show();
|
||||||
return pair;
|
return pair;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -29,6 +29,7 @@ import javafx.event.ActionEvent;
|
|||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
|
import org.bitcoinj.walletfx.overlay.OverlayWindowController;
|
||||||
import org.bouncycastle.crypto.params.KeyParameter;
|
import org.bouncycastle.crypto.params.KeyParameter;
|
||||||
import wallettemplate.controls.BitcoinAddressValidator;
|
import wallettemplate.controls.BitcoinAddressValidator;
|
||||||
import org.bitcoinj.walletfx.utils.TextFieldValidator;
|
import org.bitcoinj.walletfx.utils.TextFieldValidator;
|
||||||
@ -39,7 +40,7 @@ import static org.bitcoinj.walletfx.utils.GuiUtils.*;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class SendMoneyController {
|
public class SendMoneyController implements OverlayWindowController<SendMoneyController> {
|
||||||
public Button sendBtn;
|
public Button sendBtn;
|
||||||
public Button cancelBtn;
|
public Button cancelBtn;
|
||||||
public TextField address;
|
public TextField address;
|
||||||
@ -47,11 +48,16 @@ public class SendMoneyController {
|
|||||||
public TextField amountEdit;
|
public TextField amountEdit;
|
||||||
public Label btcLabel;
|
public Label btcLabel;
|
||||||
|
|
||||||
public MainController.OverlayUI overlayUI;
|
private MainController.OverlayUI<? extends OverlayWindowController<SendMoneyController>> overlayUI;
|
||||||
|
|
||||||
private Wallet.SendResult sendResult;
|
private Wallet.SendResult sendResult;
|
||||||
private KeyParameter aesKey;
|
private KeyParameter aesKey;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOverlayUI(MainController.OverlayUI<? extends OverlayWindowController<SendMoneyController>> ui) {
|
||||||
|
overlayUI = ui;
|
||||||
|
}
|
||||||
|
|
||||||
// Called by FXMLLoader
|
// Called by FXMLLoader
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
Coin balance = Main.bitcoin.wallet().getBalance();
|
Coin balance = Main.bitcoin.wallet().getBalance();
|
||||||
|
@ -30,6 +30,7 @@ import javafx.scene.control.ProgressIndicator;
|
|||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
|
import org.bitcoinj.walletfx.overlay.OverlayWindowController;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.bouncycastle.crypto.params.KeyParameter;
|
import org.bouncycastle.crypto.params.KeyParameter;
|
||||||
@ -44,7 +45,7 @@ import static org.bitcoinj.walletfx.utils.GuiUtils.*;
|
|||||||
* User interface for entering a password on demand, e.g. to send money. Also used when encrypting a wallet. Shows a
|
* User interface for entering a password on demand, e.g. to send money. Also used when encrypting a wallet. Shows a
|
||||||
* progress meter as we scrypt the password.
|
* progress meter as we scrypt the password.
|
||||||
*/
|
*/
|
||||||
public class WalletPasswordController {
|
public class WalletPasswordController implements OverlayWindowController<WalletPasswordController> {
|
||||||
private static final Logger log = LoggerFactory.getLogger(WalletPasswordController.class);
|
private static final Logger log = LoggerFactory.getLogger(WalletPasswordController.class);
|
||||||
|
|
||||||
@FXML HBox buttonsBox;
|
@FXML HBox buttonsBox;
|
||||||
@ -54,10 +55,15 @@ public class WalletPasswordController {
|
|||||||
@FXML GridPane widgetGrid;
|
@FXML GridPane widgetGrid;
|
||||||
@FXML Label explanationLabel;
|
@FXML Label explanationLabel;
|
||||||
|
|
||||||
public MainController.OverlayUI overlayUI;
|
private MainController.OverlayUI<? extends OverlayWindowController<WalletPasswordController>> overlayUI;
|
||||||
|
|
||||||
private SimpleObjectProperty<KeyParameter> aesKey = new SimpleObjectProperty<>();
|
private SimpleObjectProperty<KeyParameter> aesKey = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOverlayUI(MainController.OverlayUI<? extends OverlayWindowController<WalletPasswordController>> ui) {
|
||||||
|
overlayUI = ui;
|
||||||
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
progressMeter.setOpacity(0);
|
progressMeter.setOpacity(0);
|
||||||
Platform.runLater(pass1::requestFocus);
|
Platform.runLater(pass1::requestFocus);
|
||||||
|
@ -23,6 +23,7 @@ import javafx.scene.control.*;
|
|||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
import org.bitcoinj.crypto.*;
|
import org.bitcoinj.crypto.*;
|
||||||
import org.bitcoinj.wallet.*;
|
import org.bitcoinj.wallet.*;
|
||||||
|
import org.bitcoinj.walletfx.overlay.OverlayWindowController;
|
||||||
import org.slf4j.*;
|
import org.slf4j.*;
|
||||||
import org.bouncycastle.crypto.params.*;
|
import org.bouncycastle.crypto.params.*;
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ import java.util.concurrent.*;
|
|||||||
import org.bitcoinj.walletfx.utils.KeyDerivationTasks;
|
import org.bitcoinj.walletfx.utils.KeyDerivationTasks;
|
||||||
import static org.bitcoinj.walletfx.utils.GuiUtils.*;
|
import static org.bitcoinj.walletfx.utils.GuiUtils.*;
|
||||||
|
|
||||||
public class WalletSetPasswordController {
|
public class WalletSetPasswordController implements OverlayWindowController<WalletSetPasswordController> {
|
||||||
private static final Logger log = LoggerFactory.getLogger(WalletSetPasswordController.class);
|
private static final Logger log = LoggerFactory.getLogger(WalletSetPasswordController.class);
|
||||||
public PasswordField pass1, pass2;
|
public PasswordField pass1, pass2;
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ public class WalletSetPasswordController {
|
|||||||
public Button closeButton;
|
public Button closeButton;
|
||||||
public Label explanationLabel;
|
public Label explanationLabel;
|
||||||
|
|
||||||
public MainController.OverlayUI overlayUI;
|
private MainController.OverlayUI<? extends OverlayWindowController<WalletSetPasswordController>> overlayUI;
|
||||||
// These params were determined empirically on a top-range (as of 2014) MacBook Pro with native scrypt support,
|
// These params were determined empirically on a top-range (as of 2014) MacBook Pro with native scrypt support,
|
||||||
// using the scryptenc command line tool from the original scrypt distribution, given a memory limit of 40mb.
|
// using the scryptenc command line tool from the original scrypt distribution, given a memory limit of 40mb.
|
||||||
public static final Protos.ScryptParameters SCRYPT_PARAMETERS = Protos.ScryptParameters.newBuilder()
|
public static final Protos.ScryptParameters SCRYPT_PARAMETERS = Protos.ScryptParameters.newBuilder()
|
||||||
@ -53,6 +54,11 @@ public class WalletSetPasswordController {
|
|||||||
.setSalt(ByteString.copyFrom(KeyCrypterScrypt.randomSalt()))
|
.setSalt(ByteString.copyFrom(KeyCrypterScrypt.randomSalt()))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOverlayUI(MainController.OverlayUI<? extends OverlayWindowController<WalletSetPasswordController>> ui) {
|
||||||
|
overlayUI = ui;
|
||||||
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
progressMeter.setOpacity(0);
|
progressMeter.setOpacity(0);
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import javafx.fxml.FXML;
|
|||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.DatePicker;
|
import javafx.scene.control.DatePicker;
|
||||||
import javafx.scene.control.TextArea;
|
import javafx.scene.control.TextArea;
|
||||||
|
import org.bitcoinj.walletfx.overlay.OverlayWindowController;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.bouncycastle.crypto.params.KeyParameter;
|
import org.bouncycastle.crypto.params.KeyParameter;
|
||||||
@ -47,7 +48,7 @@ import static org.bitcoinj.walletfx.utils.GuiUtils.informationalAlert;
|
|||||||
import static org.bitcoinj.walletfx.utils.WTUtils.didThrow;
|
import static org.bitcoinj.walletfx.utils.WTUtils.didThrow;
|
||||||
import static org.bitcoinj.walletfx.utils.WTUtils.unchecked;
|
import static org.bitcoinj.walletfx.utils.WTUtils.unchecked;
|
||||||
|
|
||||||
public class WalletSettingsController {
|
public class WalletSettingsController implements OverlayWindowController<WalletSettingsController> {
|
||||||
private static final Logger log = LoggerFactory.getLogger(WalletSettingsController.class);
|
private static final Logger log = LoggerFactory.getLogger(WalletSettingsController.class);
|
||||||
|
|
||||||
@FXML Button passwordButton;
|
@FXML Button passwordButton;
|
||||||
@ -55,10 +56,15 @@ public class WalletSettingsController {
|
|||||||
@FXML TextArea wordsArea;
|
@FXML TextArea wordsArea;
|
||||||
@FXML Button restoreButton;
|
@FXML Button restoreButton;
|
||||||
|
|
||||||
public MainController.OverlayUI overlayUI;
|
private MainController.OverlayUI<? extends OverlayWindowController<WalletSettingsController>> overlayUI;
|
||||||
|
|
||||||
private KeyParameter aesKey;
|
private KeyParameter aesKey;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOverlayUI(MainController.OverlayUI<? extends OverlayWindowController<WalletSettingsController>> ui) {
|
||||||
|
overlayUI = ui;
|
||||||
|
}
|
||||||
|
|
||||||
// Note: NOT called by FXMLLoader!
|
// Note: NOT called by FXMLLoader!
|
||||||
public void initialize(@Nullable KeyParameter aesKey) {
|
public void initialize(@Nullable KeyParameter aesKey) {
|
||||||
DeterministicSeed seed = Main.bitcoin.wallet().getKeyChainSeed();
|
DeterministicSeed seed = Main.bitcoin.wallet().getKeyChainSeed();
|
||||||
|
@ -42,6 +42,7 @@ import javafx.scene.layout.Pane;
|
|||||||
import org.bitcoinj.core.Address;
|
import org.bitcoinj.core.Address;
|
||||||
import org.bitcoinj.uri.BitcoinURI;
|
import org.bitcoinj.uri.BitcoinURI;
|
||||||
|
|
||||||
|
import org.bitcoinj.walletfx.overlay.OverlayWindowController;
|
||||||
import wallettemplate.Main;
|
import wallettemplate.Main;
|
||||||
import org.bitcoinj.walletfx.utils.GuiUtils;
|
import org.bitcoinj.walletfx.utils.GuiUtils;
|
||||||
import org.bitcoinj.walletfx.utils.QRCodeImages;
|
import org.bitcoinj.walletfx.utils.QRCodeImages;
|
||||||
@ -57,7 +58,7 @@ import static javafx.beans.binding.Bindings.convert;
|
|||||||
* address looks like a blue hyperlink. Next to it there are two icons, one that copies to the clipboard and another
|
* address looks like a blue hyperlink. Next to it there are two icons, one that copies to the clipboard and another
|
||||||
* that shows a QRcode.
|
* that shows a QRcode.
|
||||||
*/
|
*/
|
||||||
public class ClickableBitcoinAddress extends AnchorPane {
|
public class ClickableBitcoinAddress extends AnchorPane implements OverlayWindowController<ClickableBitcoinAddress> {
|
||||||
@FXML protected Label addressLabel;
|
@FXML protected Label addressLabel;
|
||||||
@FXML protected ContextMenu addressMenu;
|
@FXML protected ContextMenu addressMenu;
|
||||||
@FXML protected Label copyWidget;
|
@FXML protected Label copyWidget;
|
||||||
@ -66,6 +67,10 @@ public class ClickableBitcoinAddress extends AnchorPane {
|
|||||||
protected SimpleObjectProperty<Address> address = new SimpleObjectProperty<>();
|
protected SimpleObjectProperty<Address> address = new SimpleObjectProperty<>();
|
||||||
private final StringExpression addressStr;
|
private final StringExpression addressStr;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOverlayUI(MainController.OverlayUI<? extends OverlayWindowController<ClickableBitcoinAddress>> ui) {
|
||||||
|
}
|
||||||
|
|
||||||
public ClickableBitcoinAddress() {
|
public ClickableBitcoinAddress() {
|
||||||
try {
|
try {
|
||||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("bitcoin_address.fxml"));
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("bitcoin_address.fxml"));
|
||||||
|
Loading…
Reference in New Issue
Block a user