Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
d99f6962df
|
@ -69,7 +69,7 @@ Add the platform-tools to you PATH to use 'adb' command:
|
|||
export PATH="$PATH:/home/mark/Android/Sdk/platform-tools/"
|
||||
```
|
||||
|
||||
Run the 'adb devices' and 'adb usb' to verify your Android device is in development mode and allows connections.
|
||||
Run the 'adb devices' and 'adb usb' to verify your Android networkService is in development mode and allows connections.
|
||||
|
||||
### MacOS
|
||||
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
package biz.nellemann.mdexpl;
|
||||
|
||||
import biz.nellemann.mdexpl.model.Device;
|
||||
import biz.nellemann.mdexpl.model.Devices;
|
||||
import com.gluonhq.charm.glisten.control.CharmListCell;
|
||||
import com.gluonhq.charm.glisten.control.ListTile;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
|
||||
public class DeviceCell extends CharmListCell<Device> {
|
||||
|
||||
private final ListTile tile;
|
||||
private final ImageView imageView;
|
||||
|
||||
public DeviceCell() {
|
||||
this.tile = new ListTile();
|
||||
imageView = new ImageView();
|
||||
imageView.setFitHeight(15);
|
||||
imageView.setFitWidth(25);
|
||||
tile.setPrimaryGraphic(imageView);
|
||||
setText(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItem(Device item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty) {
|
||||
tile.textProperty().setAll(item.getName() + " (" + item.getAbbr() + ")",
|
||||
"Capital: " + item.getCapital() +
|
||||
", Population (M): " + String.format("%.2f", item.getPopulation() / 1_000_000d),
|
||||
"Area (km" + "\u00B2" + "): " + item.getArea() +
|
||||
", Density (pop/km" + "\u00B2" + "): " + String.format("%.1f", item.getDensity())
|
||||
);
|
||||
final Image image = Devices.getImage(item.getFlag());
|
||||
if (image != null) {
|
||||
imageView.setImage(image);
|
||||
}
|
||||
setGraphic(tile);
|
||||
} else {
|
||||
setGraphic(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
45
src/main/java/biz/nellemann/mdexpl/NetworkServiceCell.java
Normal file
45
src/main/java/biz/nellemann/mdexpl/NetworkServiceCell.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
package biz.nellemann.mdexpl;
|
||||
|
||||
import biz.nellemann.mdexpl.model.NetworkService;
|
||||
import com.gluonhq.charm.glisten.control.CharmListCell;
|
||||
import com.gluonhq.charm.glisten.control.ListTile;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
|
||||
public class NetworkServiceCell extends CharmListCell<NetworkService> {
|
||||
|
||||
private final ListTile tile;
|
||||
//private final ImageView imageView;
|
||||
private final Rectangle icon;
|
||||
|
||||
public NetworkServiceCell() {
|
||||
this.tile = new ListTile();
|
||||
//imageView = new ImageView();
|
||||
//imageView.setFitHeight(15);
|
||||
//imageView.setFitWidth(25);
|
||||
//tile.setPrimaryGraphic(imageView);
|
||||
icon = new Rectangle();
|
||||
icon.setHeight(25);
|
||||
icon.setWidth(25);
|
||||
tile.setPrimaryGraphic(icon);
|
||||
tile.setOnMouseClicked(e -> { System.out.println("Selected -> " + itemProperty().get().getName() ); });
|
||||
setText(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItem(NetworkService item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty) {
|
||||
tile.textProperty().setAll(item.getName(),
|
||||
"App: " + item.getApp(), "URL: " + item.getUrl()
|
||||
);
|
||||
icon.setFill(item.getColor());
|
||||
setGraphic(tile);
|
||||
} else {
|
||||
setGraphic(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,24 +1,30 @@
|
|||
package biz.nellemann.mdexpl;
|
||||
|
||||
import biz.nellemann.mdexpl.model.NetworkService;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.paint.Color;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.jmdns.ServiceEvent;
|
||||
import javax.jmdns.ServiceInfo;
|
||||
import javax.jmdns.ServiceListener;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class NetworkServiceListener implements ServiceListener {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(NetworkServiceListener.class);
|
||||
|
||||
private final HashMap<String, String> onlineList = new HashMap<>();
|
||||
private final String service;
|
||||
private final ObservableList<NetworkService> observableList;
|
||||
|
||||
private final String serviceType;
|
||||
private final Color color;
|
||||
|
||||
public NetworkServiceListener(String type) {
|
||||
log.info("NetworkServiceListener() - type: {}", type);
|
||||
this.serviceType = type;
|
||||
public NetworkServiceListener(String service, ObservableList<NetworkService> observableList, Color color) {
|
||||
log.info("NetworkServiceListener() - type: {}", service);
|
||||
this.service = service;
|
||||
this.observableList = observableList;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,8 +36,11 @@ public class NetworkServiceListener implements ServiceListener {
|
|||
ServiceInfo serviceInfo = event.getInfo();
|
||||
if (serviceInfo != null) {
|
||||
String name = serviceInfo.getName();
|
||||
onlineList.remove(name);
|
||||
log.info("serviceRemoved() - Removed service: " + name);
|
||||
log.info("serviceRemoved() - Service: " + name);
|
||||
NetworkService oldNetworkService = new NetworkService(name, service, serviceInfo.getApplication(), serviceInfo.getURLs()[0], color);
|
||||
Platform.runLater(() -> {
|
||||
observableList.remove(oldNetworkService);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,9 +51,13 @@ public class NetworkServiceListener implements ServiceListener {
|
|||
String url = serviceInfo.getURLs()[0];
|
||||
String name = serviceInfo.getName();
|
||||
String app = serviceInfo.getApplication();
|
||||
log.debug(serviceInfo.toString());
|
||||
onlineList.put(name, url);
|
||||
log.info("serviceResolved() - Found {}: {} with url {}", app, name, url);
|
||||
log.info("serviceResolved() - Service: {} - {} with url {}", app, name, url);
|
||||
NetworkService newNetworkService = new NetworkService(name, service, app, url, color);
|
||||
Platform.runLater(() -> {
|
||||
if(!observableList.contains(newNetworkService)) {
|
||||
observableList.add(newNetworkService);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
package biz.nellemann.mdexpl.model;
|
||||
|
||||
public class Device {
|
||||
|
||||
private String name;
|
||||
private String abbr;
|
||||
private String capital;
|
||||
private int population;
|
||||
private int area; /* km^2 */
|
||||
private String flag;
|
||||
|
||||
public Device(String name, String abbr, String capital, int population, int area, String flag) {
|
||||
this.name = name;
|
||||
this.abbr = abbr;
|
||||
this.capital = capital;
|
||||
this.population = population;
|
||||
this.area = area;
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAbbr() {
|
||||
return abbr;
|
||||
}
|
||||
|
||||
public void setAbbr(String abbr) {
|
||||
this.abbr = abbr;
|
||||
}
|
||||
|
||||
public String getCapital() {
|
||||
return capital;
|
||||
}
|
||||
|
||||
public void setCapital(String capital) {
|
||||
this.capital = capital;
|
||||
}
|
||||
|
||||
public int getPopulation() {
|
||||
return population;
|
||||
}
|
||||
|
||||
public void setPopulation(int population) {
|
||||
this.population = population;
|
||||
}
|
||||
|
||||
public int getArea() {
|
||||
return area;
|
||||
}
|
||||
|
||||
public void setArea(int area) {
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
public String getFlag() {
|
||||
return flag;
|
||||
}
|
||||
|
||||
public void setFlag(String flag) {
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Population density
|
||||
* @return population density (pop. per km^2)
|
||||
*/
|
||||
public double getDensity() {
|
||||
if (area > 0) {
|
||||
return (double) population / (double) area;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + " (" + abbr + "), capital=" + capital + ", population=" + population + ", area=" + area;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
package biz.nellemann.mdexpl.model;
|
||||
|
||||
import com.gluonhq.attach.cache.Cache;
|
||||
import com.gluonhq.attach.cache.CacheService;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.image.Image;
|
||||
|
||||
public class Devices {
|
||||
|
||||
private static final Cache<String, Image> CACHE;
|
||||
|
||||
static {
|
||||
CACHE = CacheService.create()
|
||||
.map(cache -> cache.<String, Image>getCache("images"))
|
||||
.orElseThrow(() -> new RuntimeException("No CacheService available"));
|
||||
}
|
||||
|
||||
private static final String URL_PATH = "https://upload.wikimedia.org/wikipedia/commons/thumb/";
|
||||
|
||||
public static ObservableList<Device> statesList = FXCollections.observableArrayList(
|
||||
new Device("Alabama", "AL", "Montgomery", 4903185, 135767, URL_PATH + "5/5c/Flag_of_Alabama.svg/23px-Flag_of_Alabama.svg.png"),
|
||||
new Device("Alaska", "AK", "Juneau", 731545, 1723337, URL_PATH + "e/e6/Flag_of_Alaska.svg/21px-Flag_of_Alaska.svg.png"),
|
||||
new Device("Arizona", "AZ", "Phoenix", 7278717, 295233, URL_PATH + "9/9d/Flag_of_Arizona.svg/23px-Flag_of_Arizona.svg.png"),
|
||||
new Device("Arkansas", "AR", "Little Rock", 3017804, 137733, URL_PATH + "9/9d/Flag_of_Arkansas.svg/23px-Flag_of_Arkansas.svg.png"),
|
||||
new Device("California", "CA", "Sacramento", 39512223, 423968, URL_PATH + "0/01/Flag_of_California.svg/23px-Flag_of_California.svg.png"),
|
||||
new Device("Colorado", "CO", "Denver", 5758736, 269602, URL_PATH + "4/46/Flag_of_Colorado.svg/23px-Flag_of_Colorado.svg.png"),
|
||||
new Device("Connecticut", "CT", "Hartford", 3565287, 14356, URL_PATH + "9/96/Flag_of_Connecticut.svg/20px-Flag_of_Connecticut.svg.png"),
|
||||
new Device("Delaware", "DE", "Dover", 973764, 6446, URL_PATH + "c/c6/Flag_of_Delaware.svg/23px-Flag_of_Delaware.svg.png"),
|
||||
new Device("Florida", "FL", "Tallahassee", 21477737, 170312, URL_PATH + "f/f7/Flag_of_Florida.svg/23px-Flag_of_Florida.svg.png"),
|
||||
new Device("Georgia", "GA", "Atlanta", 10617423, 153910, URL_PATH + "5/54/Flag_of_Georgia_%28U.S._state%29.svg/23px-Flag_of_Georgia_%28U.S._state%29.svg.png"),
|
||||
new Device("Hawaii", "HI", "Honolulu", 1415872, 28314, URL_PATH + "e/ef/Flag_of_Hawaii.svg/23px-Flag_of_Hawaii.svg.png"),
|
||||
new Device("Idaho", "ID", "Boise", 1787065, 216443, URL_PATH + "a/a4/Flag_of_Idaho.svg/19px-Flag_of_Idaho.svg.png"),
|
||||
new Device("Illinois", "IL", "Springfield", 12671821, 149997, URL_PATH + "0/01/Flag_of_Illinois.svg/23px-Flag_of_Illinois.svg.png")
|
||||
|
||||
);
|
||||
|
||||
public static Image getUSFlag() {
|
||||
return getImage(URL_PATH + "a/a4/Flag_of_the_United_States.svg/320px-Flag_of_the_United_States.svg.png");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will always return the required image.
|
||||
* It will cache the image and return from cache if still there.
|
||||
* @param image: A valid url to retrieve the image
|
||||
* @return an Image
|
||||
*/
|
||||
public static Image getImage(String image) {
|
||||
if (image == null || image.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Image cachedImage = CACHE.get(image);
|
||||
if (cachedImage == null) {
|
||||
cachedImage = new Image(image, true);
|
||||
cachedImage.errorProperty().addListener((obs, ov, nv) -> {
|
||||
if (nv) {
|
||||
CACHE.remove(image);
|
||||
}
|
||||
});
|
||||
CACHE.put(image, cachedImage);
|
||||
}
|
||||
return cachedImage;
|
||||
}
|
||||
|
||||
}
|
79
src/main/java/biz/nellemann/mdexpl/model/NetworkService.java
Normal file
79
src/main/java/biz/nellemann/mdexpl/model/NetworkService.java
Normal file
|
@ -0,0 +1,79 @@
|
|||
package biz.nellemann.mdexpl.model;
|
||||
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
public class NetworkService {
|
||||
|
||||
private String name;
|
||||
private String type;
|
||||
private String app;
|
||||
private String url;
|
||||
private Color color;
|
||||
|
||||
public NetworkService(String name, String type, String app, String url, Color color) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.app = app;
|
||||
this.url = url;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getApp() {
|
||||
return app;
|
||||
}
|
||||
|
||||
public void setApp(String app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + " (" + type + "), app=" + app + ", url=" + url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof NetworkService networkService)) {
|
||||
return false;
|
||||
}
|
||||
return networkService.name.equals(name) && networkService.type.equals(type) && networkService.url.equals(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,18 +1,20 @@
|
|||
package biz.nellemann.mdexpl.service;
|
||||
|
||||
import biz.nellemann.mdexpl.NetworkServiceListener;
|
||||
import biz.nellemann.mdexpl.model.NetworkService;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.paint.Color;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Singleton;
|
||||
import javax.jmdns.JmDNS;
|
||||
import javax.jmdns.ServiceInfo;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Singleton
|
||||
|
@ -20,29 +22,57 @@ public class DiscoveryService {
|
|||
|
||||
private final static Logger log = LoggerFactory.getLogger(DiscoveryService.class);
|
||||
|
||||
// http://www.dns-sd.org/serviceTypes.html
|
||||
private final List<String> services = Arrays.asList(
|
||||
private ObservableList<NetworkService> observableList;
|
||||
|
||||
private JmDNS jmdns;
|
||||
|
||||
/*private final HashMap<String, Color> services = HashMap<>({
|
||||
"http", "https", "upnp", "ssh", "sip", "rdp", "ntp", "rdp", "rtsp",
|
||||
"ntp", "smb", "nfs", "llrp", "ftp", "ep", "daap", "ipp", "ipps",
|
||||
"googlecast", "appletv", "appletv-itunes", "smartenergy", "skype", "bittorrent",
|
||||
"sonos", "airplay"
|
||||
);
|
||||
"googlecast", "sonos", "airplay", "smartenergy", "skype", "bittorrent"
|
||||
);*/
|
||||
|
||||
// From: http://www.dns-sd.org/serviceTypes.html + some guesses
|
||||
private final Map<String, Color> services = new HashMap<>() {{
|
||||
put("http", Color.BLUE);
|
||||
put("https", Color.DARKBLUE);
|
||||
|
||||
put("googlecast", Color.RED);
|
||||
put("airplay", Color.SLATEGRAY);
|
||||
put("sonos", Color.SANDYBROWN);
|
||||
|
||||
put("ipp", Color.LIGHTGRAY);
|
||||
put("ipps", Color.LIGHTGRAY);
|
||||
|
||||
put("nfs", Color.CORAL);
|
||||
put("smb", Color.CORAL);
|
||||
put("cifs", Color.CORAL);
|
||||
|
||||
put("smartenergy", Color.LIGHTGREEN);
|
||||
|
||||
put("sip", Color.YELLOW);
|
||||
put("skype", Color.YELLOW);
|
||||
}};
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void initialize() {
|
||||
log.info("initialize()");
|
||||
try {
|
||||
JmDNS jmdns = JmDNS.create(null, "mdnsExplorer");
|
||||
services.forEach(service -> {
|
||||
String serviceType = String.format("_%s._%s.local.", service, "tcp");
|
||||
NetworkServiceListener networkServiceListener = new NetworkServiceListener(serviceType);
|
||||
jmdns.addServiceListener(serviceType, networkServiceListener);
|
||||
});
|
||||
jmdns = JmDNS.create(null, "mdnsExplorer");
|
||||
} catch (IOException e) {
|
||||
log.error("initialize() - {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setObservableList(ObservableList<NetworkService> list) {
|
||||
this.observableList = list;
|
||||
services.forEach((item, color) -> {
|
||||
String service = String.format("_%s._%s.local.", item, "tcp");
|
||||
NetworkServiceListener networkServiceListener = new NetworkServiceListener(service, observableList, color);
|
||||
jmdns.addServiceListener(service, networkServiceListener);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
package biz.nellemann.mdexpl.view;
|
||||
|
||||
import biz.nellemann.mdexpl.NetworkServiceCell;
|
||||
import biz.nellemann.mdexpl.model.NetworkService;
|
||||
import biz.nellemann.mdexpl.model.MainModel;
|
||||
import biz.nellemann.mdexpl.service.DiscoveryService;
|
||||
import com.gluonhq.charm.glisten.application.AppManager;
|
||||
import com.gluonhq.charm.glisten.control.AppBar;
|
||||
import com.gluonhq.charm.glisten.control.CharmListView;
|
||||
import com.gluonhq.charm.glisten.control.Icon;
|
||||
import com.gluonhq.charm.glisten.control.LifecycleEvent;
|
||||
import com.gluonhq.charm.glisten.mvc.View;
|
||||
import com.gluonhq.charm.glisten.visual.MaterialDesignIcon;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.input.TouchEvent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -41,6 +41,8 @@ public class MainPresenter {
|
|||
@FXML
|
||||
private CharmListView charmListView;
|
||||
|
||||
private ObservableList<NetworkService> devicesList = FXCollections.observableArrayList();
|
||||
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
|
@ -56,19 +58,13 @@ public class MainPresenter {
|
|||
appManager.getDrawer().open()));
|
||||
|
||||
appBar.setTitleText("mDNS Explorer");
|
||||
//appBar.getActionItems().add(progressIndicator);
|
||||
}
|
||||
});
|
||||
|
||||
discoveryService.setObservableList(devicesList);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@FXML
|
||||
protected void onButtonRefresh() {
|
||||
log.info("onButtonRefresh()");
|
||||
|
||||
|
||||
charmListView.setItems(devicesList);
|
||||
charmListView.setCellFactory(p -> new NetworkServiceCell());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<View fx:id="about" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="biz.nellemann.mdexpl.view.AboutPresenter">
|
||||
<View fx:id="about" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="biz.nellemann.mdexpl.view.AboutPresenter">
|
||||
|
||||
<VBox alignment="CENTER">
|
||||
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" text="mDNS Explorer">
|
||||
|
|
|
@ -7,19 +7,8 @@
|
|||
<?import com.gluonhq.charm.glisten.mvc.View?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
|
||||
<View fx:id="main" onHiding="#onEventHiding" onShowing="#onEventShowing" prefHeight="800.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="biz.nellemann.mdexpl.view.MainPresenter">
|
||||
<View fx:id="main" onHiding="#onEventHiding" onShowing="#onEventShowing" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="biz.nellemann.mdexpl.view.MainPresenter">
|
||||
|
||||
<bottom>
|
||||
<BottomNavigation>
|
||||
|
||||
<BottomNavigationButton onAction="#onButtonRefresh" selected="true" text="Refresh">
|
||||
<graphic>
|
||||
<Icon content="REFRESH" />
|
||||
</graphic>
|
||||
</BottomNavigationButton>
|
||||
|
||||
</BottomNavigation>
|
||||
</bottom>
|
||||
<center>
|
||||
<CharmListView fx:id="charmListView" BorderPane.alignment="CENTER" />
|
||||
</center>
|
||||
|
|
Loading…
Reference in a new issue