mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-23 20:36:44 +00:00
add file logging
This commit is contained in:
parent
3556e4abc9
commit
827d35cba3
13 changed files with 60 additions and 29 deletions
2
drongo
2
drongo
|
@ -1 +1 @@
|
|||
Subproject commit b134fcd1e88ff0938623c96f039c10d468e5de02
|
||||
Subproject commit 04576bddff218f284e0cf925a1f790011203eec4
|
|
@ -43,6 +43,8 @@ import javafx.stage.FileChooser;
|
|||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
import org.controlsfx.control.StatusBar;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
|
@ -52,6 +54,8 @@ import java.util.*;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
public class AppController implements Initializable {
|
||||
private static final Logger log = LoggerFactory.getLogger(AppController.class);
|
||||
|
||||
private static final int SERVER_PING_PERIOD = 10 * 1000;
|
||||
private static final int ENUMERATE_HW_PERIOD = 30 * 1000;
|
||||
|
||||
|
@ -528,7 +532,7 @@ public class AppController implements Initializable {
|
|||
try {
|
||||
application.stop();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("Error quitting application", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -615,7 +619,7 @@ public class AppController implements Initializable {
|
|||
throw new IOException("Unsupported file type");
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("Error opening wallet", e);
|
||||
showErrorDialog("Error Opening Wallet", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -751,7 +755,7 @@ public class AppController implements Initializable {
|
|||
//addTransactionTab("combiner.psbt", "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000002202029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01220202dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887220203089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f012202023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d2010103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000");
|
||||
addTransactionTab("finalizer.psbt", "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000");
|
||||
} catch(Exception e) {
|
||||
System.out.println(e);
|
||||
log.error("Error opening examples", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,14 @@ import javafx.scene.control.cell.TextFieldTreeTableCell;
|
|||
import javafx.scene.input.Clipboard;
|
||||
import javafx.scene.input.ClipboardContent;
|
||||
import javafx.util.converter.DefaultStringConverter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
class LabelCell extends TextFieldTreeTableCell<Entry, String> {
|
||||
private static final Logger log = LoggerFactory.getLogger(LabelCell.class);
|
||||
|
||||
public LabelCell() {
|
||||
super(new DefaultStringConverter());
|
||||
getStyleClass().add("label-cell");
|
||||
|
@ -71,7 +75,7 @@ class LabelCell extends TextFieldTreeTableCell<Entry, String> {
|
|||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("Error starting edit", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,11 +20,15 @@ import javafx.scene.image.ImageView;
|
|||
import javafx.scene.layout.StackPane;
|
||||
import javafx.util.Duration;
|
||||
import org.controlsfx.tools.Borders;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class QRDisplayDialog extends Dialog<UR> {
|
||||
private static final Logger log = LoggerFactory.getLogger(QRDisplayDialog.class);
|
||||
|
||||
private static final int MIN_FRAGMENT_LENGTH = 10;
|
||||
private static final int MAX_FRAGMENT_LENGTH = 100;
|
||||
|
||||
|
@ -89,7 +93,7 @@ public class QRDisplayDialog extends Dialog<UR> {
|
|||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
return new Image(bais);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("Error generating QR", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -3,12 +3,16 @@ package com.sparrowwallet.sparrow.io;
|
|||
import com.google.gson.*;
|
||||
import com.sparrowwallet.drongo.BitcoinUnit;
|
||||
import com.sparrowwallet.sparrow.Mode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Currency;
|
||||
|
||||
public class Config {
|
||||
private static final Logger log = LoggerFactory.getLogger(Config.class);
|
||||
|
||||
public static final String CONFIG_FILENAME = ".config";
|
||||
|
||||
private Mode mode;
|
||||
|
@ -49,7 +53,7 @@ public class Config {
|
|||
return config;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error("Error opening " + configFile.getAbsolutePath(), e);
|
||||
//Ignore and assume no config
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ import javafx.concurrent.ScheduledService;
|
|||
import javafx.concurrent.Service;
|
||||
import javafx.concurrent.Task;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.SocketFactory;
|
||||
import javax.net.ssl.*;
|
||||
|
@ -39,11 +41,12 @@ import java.security.cert.CertificateException;
|
|||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ElectrumServer {
|
||||
private static final Logger log = LoggerFactory.getLogger(ElectrumServer.class);
|
||||
|
||||
private static final String[] SUPPORTED_VERSIONS = new String[]{"1.3", "1.4.2"};
|
||||
|
||||
public static final BlockTransaction UNFETCHABLE_BLOCK_TRANSACTION = new BlockTransaction(Sha256Hash.ZERO_HASH, 0, null, null, null);
|
||||
|
@ -388,7 +391,7 @@ public class ElectrumServer {
|
|||
}
|
||||
|
||||
if(!blockHeights.isEmpty()) {
|
||||
System.out.println("Could not retrieve " + blockHeights.size() + " blocks");
|
||||
log.warn("Could not retrieve " + blockHeights.size() + " blocks");
|
||||
}
|
||||
|
||||
return blockHeaderMap;
|
||||
|
@ -563,7 +566,7 @@ public class ElectrumServer {
|
|||
try {
|
||||
result = batchRequest.execute();
|
||||
} catch (JsonRpcBatchException e) {
|
||||
System.out.println("Some errors retrieving transactions: " + e.getErrors());
|
||||
log.warn("Some errors retrieving transactions: " + e.getErrors());
|
||||
result = (Map<String, VerboseTransaction>)e.getSuccesses();
|
||||
}
|
||||
|
||||
|
@ -704,7 +707,7 @@ public class ElectrumServer {
|
|||
public void scriptHashStatusUpdated(@JsonRpcParam("scripthash") final String scriptHash, @JsonRpcParam("status") final String status) {
|
||||
String oldStatus = subscribedScriptHashes.put(scriptHash, status);
|
||||
if(Objects.equals(oldStatus, status)) {
|
||||
System.out.println("Received script hash status update, but status has not changed");
|
||||
log.warn("Received script hash status update, but status has not changed");
|
||||
}
|
||||
|
||||
Platform.runLater(() -> EventManager.get().post(new WalletNodeHistoryChangedEvent(scriptHash)));
|
||||
|
@ -1002,7 +1005,7 @@ public class ElectrumServer {
|
|||
try {
|
||||
closeActiveConnection();
|
||||
} catch (ServerException e) {
|
||||
e.printStackTrace();
|
||||
log.error("Eror closing connection", e);
|
||||
}
|
||||
|
||||
return super.cancel();
|
||||
|
|
|
@ -10,6 +10,8 @@ import javafx.concurrent.ScheduledService;
|
|||
import javafx.concurrent.Service;
|
||||
import javafx.concurrent.Task;
|
||||
import org.controlsfx.tools.Platform;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Type;
|
||||
|
@ -26,6 +28,8 @@ import java.util.zip.ZipEntry;
|
|||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public class Hwi {
|
||||
private static final Logger log = LoggerFactory.getLogger(Hwi.class);
|
||||
|
||||
private static boolean isPromptActive = false;
|
||||
|
||||
public List<Device> enumerate(String passphrase) throws ImportException {
|
||||
|
@ -151,7 +155,7 @@ public class Hwi {
|
|||
Path tempHwiDirPath = Files.createTempDirectory("hwi", PosixFilePermissions.asFileAttribute(ownerExecutableWritable));
|
||||
File tempHwiDir = tempHwiDirPath.toFile();
|
||||
//tempHwiDir.deleteOnExit();
|
||||
//System.out.println(tempHwiDir.getAbsolutePath());
|
||||
log.debug("Using temp HWI path: " + tempHwiDir.getAbsolutePath());
|
||||
|
||||
File tempExec = null;
|
||||
ZipInputStream zis = new ZipInputStream(inputStream);
|
||||
|
@ -188,7 +192,7 @@ public class Hwi {
|
|||
hwiExecutable = tempExec;
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("Error initializing HWI", e);
|
||||
}
|
||||
|
||||
Config.get().setHwi(hwiExecutable);
|
||||
|
|
|
@ -22,12 +22,15 @@ import javafx.scene.control.cell.TextFieldTreeCell;
|
|||
import javafx.scene.layout.Pane;
|
||||
import javafx.util.StringConverter;
|
||||
import org.controlsfx.control.MasterDetailPane;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
public class TransactionController implements Initializable {
|
||||
private static final Logger log = LoggerFactory.getLogger(TransactionController.class);
|
||||
|
||||
@FXML
|
||||
private Node tabContent;
|
||||
|
@ -327,7 +330,7 @@ public class TransactionController implements Initializable {
|
|||
|
||||
references.remove(getTransaction().getTxId());
|
||||
if (!references.isEmpty()) {
|
||||
System.out.println("Failed to retrieve all referenced input transactions, aborting transaction fetch");
|
||||
log.warn("Failed to retrieve all referenced input transactions, aborting transaction fetch");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package com.sparrowwallet.sparrow.ur.fountain;
|
||||
|
||||
import com.sparrowwallet.sparrow.ur.ResultType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.*;
|
||||
|
@ -14,6 +16,8 @@ import static com.sparrowwallet.sparrow.ur.fountain.FountainUtils.chooseFragment
|
|||
* Ported from https://github.com/BlockchainCommons/URKit
|
||||
*/
|
||||
public class FountainDecoder {
|
||||
private static final Logger log = LoggerFactory.getLogger(FountainDecoder.class);
|
||||
|
||||
private final Set<Integer> recievedPartIndexes = new TreeSet<>();
|
||||
private Set<Integer> lastPartIndexes;
|
||||
private int processedPartsCount = 0;
|
||||
|
@ -123,12 +127,12 @@ public class FountainDecoder {
|
|||
|
||||
private void printPartEnd() {
|
||||
int percent = (int)Math.round(getEstimatedPercentComplete() * 100);
|
||||
System.out.println("processed: " + processedPartsCount + " expected: " + getExpectedPartCount() + " received: " + recievedPartIndexes.size() + " percent: " + percent + "%");
|
||||
log.debug("processed: " + processedPartsCount + " expected: " + getExpectedPartCount() + " received: " + recievedPartIndexes.size() + " percent: " + percent + "%");
|
||||
}
|
||||
|
||||
private void printPart(Part part) {
|
||||
List<Integer> sorted = part.partIndexes.stream().sorted().collect(Collectors.toList());
|
||||
System.out.println("part indexes: " + sorted);
|
||||
log.debug("part indexes: " + sorted);
|
||||
}
|
||||
|
||||
private void printState() {
|
||||
|
@ -138,7 +142,7 @@ public class FountainDecoder {
|
|||
return list;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
System.out.println("parts: " + getExpectedPartCount() + ", received: " + sortedReceived + ", mixed: " + mixed + ", queued: " + queuedParts.size() + ", result: " + result);
|
||||
log.debug("parts: " + getExpectedPartCount() + ", received: " + sortedReceived + ", mixed: " + mixed + ", queued: " + queuedParts.size() + ", result: " + result);
|
||||
}
|
||||
|
||||
private void processQueueItem() {
|
||||
|
|
|
@ -26,6 +26,8 @@ import javafx.scene.image.Image;
|
|||
import javafx.scene.image.ImageView;
|
||||
import org.controlsfx.glyphfont.Glyph;
|
||||
import org.fxmisc.richtext.CodeArea;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
@ -36,6 +38,8 @@ import java.util.ResourceBundle;
|
|||
import java.util.Set;
|
||||
|
||||
public class ReceiveController extends WalletFormController implements Initializable {
|
||||
private static final Logger log = LoggerFactory.getLogger(ReceiveController.class);
|
||||
|
||||
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
|
||||
@FXML
|
||||
|
@ -122,7 +126,7 @@ public class ReceiveController extends WalletFormController implements Initializ
|
|||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
return new Image(bais);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("Error generating QR", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -121,12 +121,4 @@ public class TransactionsController extends WalletFormController implements Init
|
|||
public void exchangeRatesUpdated(ExchangeRatesUpdatedEvent event) {
|
||||
setFiatBalance(event.getCurrencyRate(), getWalletForm().getWalletTransactionsEntry().getBalance());
|
||||
}
|
||||
|
||||
//TODO: Remove
|
||||
public void advanceBlock(MouseEvent event) {
|
||||
Integer currentBlock = getWalletForm().getWallet().getStoredBlockHeight();
|
||||
getWalletForm().getWallet().setStoredBlockHeight(currentBlock+1);
|
||||
System.out.println("Advancing from " + currentBlock + " to " + getWalletForm().getWallet().getStoredBlockHeight());
|
||||
EventManager.get().post(new WalletBlockHeightChangedEvent(getWalletForm().getWallet(), currentBlock+1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,16 @@ import com.sparrowwallet.sparrow.event.*;
|
|||
import com.sparrowwallet.sparrow.io.ElectrumServer;
|
||||
import com.sparrowwallet.sparrow.io.Storage;
|
||||
import javafx.application.Platform;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class WalletForm {
|
||||
private static final Logger log = LoggerFactory.getLogger(WalletForm.class);
|
||||
|
||||
private final Storage storage;
|
||||
protected Wallet wallet;
|
||||
|
||||
|
@ -173,7 +177,7 @@ public class WalletForm {
|
|||
save();
|
||||
} catch (IOException e) {
|
||||
//Background save failed
|
||||
e.printStackTrace();
|
||||
log.error("Background wallet save failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ open module com.sparrowwallet.sparrow {
|
|||
requires javafx.controls;
|
||||
requires javafx.fxml;
|
||||
requires javafx.graphics;
|
||||
requires javafx.swing;
|
||||
requires org.controlsfx.controls;
|
||||
requires org.fxmisc.richtext;
|
||||
requires tornadofx.controls;
|
||||
|
@ -20,5 +21,5 @@ open module com.sparrowwallet.sparrow {
|
|||
requires cbor;
|
||||
requires webcam.capture;
|
||||
requires centerdevice.nsmenufx;
|
||||
requires javafx.swing;
|
||||
requires slf4j.api;
|
||||
}
|
Loading…
Reference in a new issue