Commit 3dac795e authored by Riegel's avatar Riegel
Browse files

Merge branch 'dev' into 'master'

Version 3.17.0 Release

See merge request !28
1 merge request!28Version 3.17.0 Release
Pipeline #11012 passed with stage
in 1 minute and 10 seconds
Showing with 986 additions and 60 deletions
+986 -60
......@@ -366,6 +366,35 @@ public class Renderer {
return polygons;
}
private Set<ConcretePolygon> setupTransportationObjectPolygons(TransportationObject to) {
Set<ConcretePolygon> polygons = new HashSet<>();
addPolygons(to, polygons);
if (to instanceof TransportationSpace ts) {
if (ts instanceof TopLevelTransportFeature top) {
for (TransportSection sect : top.getSections()) {
polygons.addAll(setupTransportationObjectPolygons(sect));
}
for (TransportSection isect : top.getIntersections()) {
polygons.addAll(setupTransportationObjectPolygons(isect));
}
}
for (TrafficSpaceObject tso : ts.getTrafficSpaces()) {
polygons.addAll(setupTransportationObjectPolygons(tso));
}
for (TrafficSpaceObject atso : ts.getAuxTrafficSpaces()) {
polygons.addAll(setupTransportationObjectPolygons(atso));
}
}
if (to instanceof TrafficSpaceObject tso) {
for (TrafficAreaObject tao : tso.getTrafficAreas()) {
polygons.addAll(setupTransportationObjectPolygons(tao));
}
}
return polygons;
}
public void render(Tunnel tunnel) {
refresher = () -> {
Set<ConcretePolygon> setupTunnelPolygons = setupTunnelPolygons(tunnel);
......@@ -401,7 +430,7 @@ public class Renderer {
addPolygons(bs, polygons);
}
}
for (TunnelFurniture tf : tunnel.getTunnelFurnitureList()) {
for (TunnelFurniture tf : tunnel.getTunnelFurniture()) {
addPolygons(tf, polygons);
for (BoundarySurface bs : tf.getBoundarySurfaceList()) {
addPolygons(bs, polygons);
......@@ -578,6 +607,20 @@ public class Renderer {
return polygons;
}
public void render(TransportationObject to) {
refresher = () -> {
Set<ConcretePolygon> setupTransportationPolygons = setupTransportationObjectPolygons(to);
mainWindow.zoomOutForBoundingBox(BoundingBox.of(setupTransportationPolygons));
render(setupTransportationPolygons);
Platform.runLater(() -> {
errorUpdater = () -> displayErrors(to);
errorUpdater.run();
addGenericAttributesToView(to);
});
};
refresher.run();
}
public void render(BoundarySurface bs) {
refresher = () -> {
Set<ConcretePolygon> setupBoundarySurfacePolygons = setupBoundarySurfacePolygons(bs);
......@@ -827,8 +870,34 @@ public class Renderer {
renderCityObjects(vegetation, Color.LIGHTGREEN);
}
public void renderTransportation(List<TransportationObject> transportation) {
renderCityObjects(transportation, Color.YELLOW);
public void renderTransportation(List<? extends TransportationObject> transportation) {
errorUpdater = null;
refresher = () -> {
Platform.runLater(() -> {
loadingDialog.show();
clearGeometryTrees();
clearAttributes();
});
Thread t = new Thread(() -> {
Set<ConcretePolygon> polygons = new HashSet<>();
for (TransportationObject to : transportation) {
polygons.addAll(setupTransportationObjectPolygons(to));
}
currentTriGeom = TriangulatedGeometry.of(polygons, Color.YELLOW);
errVisitor.setGeometry(currentTriGeom);
Platform.runLater(() -> {
setupRenderState();
mainWindow.zoomOutForBoundingBox(BoundingBox.of(polygons));
loadingDialog.hide();
});
});
t.setUncaughtExceptionHandler((thread, e) -> {
Platform.runLater(() -> loadingDialog.hide());
logger.catching(e);
});
t.start();
};
refresher.run();
}
public void renderBridges(List<BridgeObject> bridges) {
......@@ -1206,5 +1275,4 @@ public class Renderer {
errorUpdater = null;
refresher = null;
}
}
......@@ -78,7 +78,7 @@ public class TriangulatedGeometry {
addPointsFromBuildings(model.getBuildings(), points);
addPointsFromCityObject(model.getBridges(), points);
addPointsFromCityObject(model.getLand(), points);
addPointsFromCityObject(model.getTransportation(), points);
addPointsFromTransportationObjects(model.getTransportation(), points);
addPointsFromCityObject(model.getVegetation(), points);
addPointsFromCityObject(model.getWater(), points);
......@@ -90,7 +90,7 @@ public class TriangulatedGeometry {
addPolygonDataFromBuildings(model.getBuildings(), triGeom, filters);
addPolygonDataFromBridges(model.getBridges(), triGeom, filters);
addPolygonDataFromCityObjects(model.getLand(), triGeom, Color.BROWN, filters);
addPolygonDataFromCityObjects(model.getTransportation(), triGeom, Color.YELLOW, filters);
addPolygonDataFromTransportationObjects(model.getTransportation(), triGeom, filters);
addPolygonDataFromCityObjects(model.getVegetation(), triGeom, Color.LIGHTGREEN, filters);
addPolygonDataFromCityObjects(model.getWater(), triGeom, Color.LIGHTSKYBLUE, filters);
addPolygonDataFromCityObjects(model.getCityFurniture(), triGeom, Color.BLUEVIOLET, filters);
......@@ -132,6 +132,45 @@ public class TriangulatedGeometry {
}
}
private static void addPolygonDataFromTransportationObjects(List<TransportationObject> tos, TriangulatedGeometry triGeom,
List<ViewFilter> filters) {
for (TransportationObject to : tos) {
if (to instanceof TransportationSpace tsp) {
addPolygonDataFromTransportationSpace(tsp, triGeom, filters);
if (tsp instanceof TopLevelTransportFeature top) {
for (TransportSection tse : top.getSections()) {
addPolygonDataFromTransportationSpace(tse, triGeom, filters);
}
for (TransportSection tse : top.getIntersections()) {
addPolygonDataFromTransportationSpace(tse, triGeom, filters);
}
}
} else {
addPolygonData(to, triGeom, Color.YELLOW, filters);
}
}
}
private static void addPolygonDataFromTransportationSpace(TransportationSpace ts, TriangulatedGeometry triGeom,
List<ViewFilter> filters) {
addPolygonData(ts, triGeom, Color.YELLOW, filters);
addPolygonDataFromTrafficSpaces(ts.getTrafficSpaces(), triGeom, filters);
addPolygonDataFromTrafficSpaces(ts.getAuxTrafficSpaces(), triGeom, filters);
}
private static void addPolygonDataFromTrafficSpaces(List<TrafficSpaceObject> spaces, TriangulatedGeometry triGeom,
List<ViewFilter> filters) {
for (TrafficSpaceObject space : spaces) {
addPolygonData(space, triGeom, Color.YELLOW, filters);
for (TrafficAreaObject area : space.getTrafficAreas()) {
addPolygonData(area, triGeom, Color.YELLOW, filters);
}
}
}
private static void addPolygonDataFromBoundarySurfaces(List<BoundarySurface> boundarySurfaces,
TriangulatedGeometry triGeom, List<ViewFilter> filters) {
for (BoundarySurface bs : boundarySurfaces) {
......@@ -187,6 +226,29 @@ public class TriangulatedGeometry {
}
}
private static void addPointsFromTransportationObjects(List<? extends TransportationObject> tos, List<Vector3d> points) {
for (TransportationObject to : tos) {
addPoints(to, points);
if (to instanceof TransportationSpace ts) {
addPointsFromTrafficSpace(ts.getTrafficSpaces(), points);
addPointsFromTrafficSpace(ts.getAuxTrafficSpaces(), points);
if (ts instanceof TopLevelTransportFeature top) {
addPointsFromTransportationObjects(top.getSections(), points);
addPointsFromTransportationObjects(top.getIntersections(), points);
}
}
}
}
private static void addPointsFromTrafficSpace(List<TrafficSpaceObject> tos, List<Vector3d> points) {
for (TrafficSpaceObject to : tos) {
addPoints(to, points);
for (TrafficAreaObject area : to.getTrafficAreas()) {
addPoints(area, points);
}
}
}
private static void addPointsFromCityObject(List<? extends CityObject> cos, List<Vector3d> points) {
for (CityObject co : cos) {
addPoints(co, points);
......
package de.hft.stuttgart.citydoctor2.gui;
import de.hft.stuttgart.citydoctor2.datastructure.*;
import de.hft.stuttgart.citydoctor2.gui.tree.FeatureNode;
import de.hft.stuttgart.citydoctor2.utils.Localization;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import org.locationtech.proj4j.ProjCoordinate;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.gui.tree.Renderable;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import javafx.scene.control.ContextMenu;
......@@ -15,17 +18,21 @@ import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import static javafx.scene.input.Clipboard.getSystemClipboard;
public class VertexClickHandler implements ClickHandler {
private TreeView<Renderable> errorView;
private Renderer renderer;
private Stage stage;
private MainWindow mainWindow;
private ParserConfiguration config;
public VertexClickHandler(TreeView<Renderable> errorView, Renderer renderer, Stage stage) {
public VertexClickHandler(TreeView<Renderable> errorView, Renderer renderer, Stage stage, MainWindow mainWindow) {
this.errorView = errorView;
this.renderer = renderer;
this.stage = stage;
this.mainWindow = mainWindow;
}
public void setConfig(ParserConfiguration config) {
......@@ -38,8 +45,26 @@ public class VertexClickHandler implements ClickHandler {
errorView.getSelectionModel().clearSelection();
renderer.highlight(p);
} else if (me.getButton() == MouseButton.SECONDARY) {
MenuItem mi = new MenuItem(p.getGmlId().getGmlString());
ContextMenu cMenu = new ContextMenu(mi);
ContextMenu cMenu = new ContextMenu();
MenuItem clipMi = new MenuItem(Localization.getText("MainWindow.copyId"));
clipMi.setOnAction(ea -> {
CityObject topLevelCityObject = p.getParent().getParent().getTopLevelCityObject();
Clipboard clipboard = getSystemClipboard();
ClipboardContent content = new ClipboardContent();
content.putString(topLevelCityObject.getGmlId().toString());
clipboard.setContent(content);
});
cMenu.getItems().add(clipMi);
MenuItem detailMi = new MenuItem(Localization.getText("MainWindow.focusCityObject"));
detailMi.setOnAction(ea -> {
CityObject topLevelCityObject = p.getParent().getParent().getTopLevelCityObject();
mainWindow.showCityObjectDetail(topLevelCityObject);
});
cMenu.getItems().add(detailMi);
cMenu.show(stage, me.getScreenX(), me.getScreenY());
}
}
......
package de.hft.stuttgart.citydoctor2.gui;
import de.hft.stuttgart.citydoctor2.gui.tree.ZipEntryListCell;
import de.hft.stuttgart.citydoctor2.gui.tree.ZipEntryNode;
import de.hft.stuttgart.citydoctor2.utils.Localization;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
import de.hft.stuttgart.citydoctor2.zip.ZipEntryErrorType;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Window;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.function.Predicate;
/**
* This class implements a GUI for managing a loaded {@link CityGmlZipArchive} in CityDoctor.
*/
public class ZipEntryManager {
private static final Logger logger = LogManager.getLogger(ZipEntryManager.class);
private Stage stage;
private CityGmlZipArchive archive;
@FXML
private TitledPane entriesPane;
@FXML
private TitledPane metadataPane;
@FXML
private Label subpathLbl;
@FXML
private TextField subpathValueTxt;
@FXML
private Label erroneousLbl;
@FXML
private Label erroneousValue;
@FXML
private Label filesizeLbl;
@FXML
private Label filesizeValue;
@FXML
private Label validatedLbl;
@FXML
private Label validatedValue;
@FXML
private Label objectCountLbl;
@FXML
private Label objectCountValue;
@FXML
private Button cancelBtn;
@FXML
private Button loadBtn;
@FXML
private ImageView loadImageView;
@FXML
private Button decompressBtn;
@FXML
private ImageView decompressImageView;
@FXML
private Button decompressAllBtn;
@FXML
private ImageView decompressAllImageView;
@FXML
private Button checkAllBtn;
@FXML
private ImageView checkAllImageView;
@FXML
private Button showReportBtn;
@FXML
private ImageView showReportImageView;
@FXML
private Button saveBtn;
@FXML
private ImageView saveImageView;
@FXML
private ListView<ZipEntryNode> entryList;
@FXML
private ProgressBar progress;
@FXML
private ProgressBar subProgress;
private CityDoctorController controller;
private int currentlyLoadedEntry = -1;
private CheckDialog dialog;
private final String unknownValueText = Localization.getText("ZipEntryManager.unknownValue");
private static final Predicate<ZipEntryNode> entryDecompressed = node ->
(node.getEntry().isLoaded() || node.getEntry().getErrorType() != null);
private static final Predicate<ZipEntryNode> entryValidated = entryDecompressed.and(node ->
(node.getEntry().getModel() != null && node.getEntry().getModel().isValidated()));
public ZipEntryManager(Window parent, CityDoctorController controller) throws IOException {
FXMLLoader loader = new FXMLLoader(ZipEntryManager.class.getResource("ZipEntryManager.fxml"));
loader.setController(this);
this.controller = controller;
archive = controller.getZipArchive();
VBox box = loader.load();
stage = new Stage();
stage.getIcons().add(new Image(MainWindow.class.getResourceAsStream("icons/CityDoctor-Logo-rot_klein.jpg")));
stage.setScene(new Scene(box));
stage.initOwner(parent);
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle(Localization.getText("ZipEntryManager.title"));
stage.getScene().addEventFilter(KeyEvent.KEY_PRESSED, (KeyEvent event) -> {
if (event.getCode() == KeyCode.ESCAPE) {
stage.close();
}
});
dialog = new CheckDialog(null, parent, controller);
dialog.showZipArchiveOptions(true);
}
public void initialize() {
subProgress.setVisible(false);
entryList.getSelectionModel().selectedItemProperty().addListener((obs, oldI, newI) -> {
if (newI != null) {
showMetadata(newI.getEntry());
}
});
entryList.setCellFactory(param -> new ZipEntryListCell());
setupButtons();
applyLocalization();
populateZipEntryList();
}
private void setupButtons() {
try {
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/decompress_zipEntry.png")) {
Image img = new Image(inStream);
decompressImageView.setImage(img);
}
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/view_model.png")) {
Image img = new Image(inStream);
loadImageView.setImage(img);
}
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/decompress_all_zipEntries.png")) {
Image img = new Image(inStream);
decompressAllImageView.setImage(img);
}
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/check_all_zipEntries.png")) {
Image img = new Image(inStream);
checkAllImageView.setImage(img);
}
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/error_stat32x32.png")) {
Image img = new Image(inStream);
showReportImageView.setImage(img);
}
try (InputStream inStream = MainWindow.class.getResourceAsStream("icons/save.png")) {
Image img = new Image(inStream);
saveImageView.setImage(img);
}
} catch (IOException ignored) {
//ignore exceptions
}
decompressBtn.setOnAction(e -> {
disableTaskButtons();
setEntryListLocked(true);
Thread t = new Thread(() -> {
CityGmlZipEntry entry = entryList.getSelectionModel().getSelectedItem().getEntry();
logger.info("Decompressing entry \"{}\"", entry.getDisplayName());
controller.decompressZipEntry(entry, progressValue ->
Platform.runLater(() -> progress.setProgress(progressValue))
);
Platform.runLater(() -> {
refresh();
progress.setProgress(0);
setEntryListLocked(false);
});
});
t.setDaemon(true);
t.start();
});
loadBtn.setOnAction(e -> {
disableTaskButtons();
setEntryListLocked(true);
try {
int selectedIndex = entryList.getSelectionModel().getSelectedIndex();
if (selectedIndex == currentlyLoadedEntry) {
stage.hide();
return;
}
CityGmlZipEntry entry = entryList.getSelectionModel().getSelectedItem().getEntry();
if (entry.getErrorType() != null) {
logger.debug("IllegalState: loadBtn was pressed while an erroneous entry was selected");
populateZipEntryList(selectedIndex);
return;
}
controller.loadZipEntry(entry);
currentlyLoadedEntry = selectedIndex;
stage.hide();
} finally {
setEntryListLocked(false);
}
});
decompressAllBtn.setOnAction(e -> {
disableTaskButtons();
setEntryListLocked(true);
subProgress.setVisible(true);
subProgress.setProgress(0);
Thread t = new Thread(() -> {
progress.setProgress(0);
int count = 0;
int total = entryList.getItems().size();
for (ZipEntryNode node : entryList.getItems()) {
logger.info("Decompressing entry \"{}\"", node.getEntry().getDisplayName());
controller.decompressZipEntry(node.getEntry(), progressValue ->
Platform.runLater(() -> subProgress.setProgress(progressValue))
);
count++;
double progressValue = count * 1.0 / total;
Platform.runLater(() -> progress.setProgress(progressValue));
}
Platform.runLater(() -> {
subProgress.setVisible(false);
refresh();
progress.setProgress(0);
setEntryListLocked(false);
});
});
t.setDaemon(true);
t.start();
});
checkAllBtn.setOnAction(e -> {
disableTaskButtons();
dialog.show();
refresh();
});
showReportBtn.setOnAction(e -> {
disableTaskButtons();
setEntryListLocked(true);
try {
controller.loadZipEntry(entryList.getSelectionModel().getSelectedItem().getEntry());
if (currentlyLoadedEntry == -1) {
currentlyLoadedEntry = entryList.getSelectionModel().getSelectedIndex();
}
WriteReportDialog writeDialog = new WriteReportDialog(stage, controller, null);
writeDialog.show();
} catch (IOException ex) {
throw new RuntimeException(ex);
} finally {
controller.loadZipEntry(entryList.getItems().get(currentlyLoadedEntry).getEntry());
setEntryListLocked(false);
refresh();
}
});
showReportBtn.setDisable(true);
saveBtn.setOnAction(e -> {
disableTaskButtons();
setEntryListLocked(true);
try {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Export Zip file");
FileChooser.ExtensionFilter zipFilter = new FileChooser.ExtensionFilter("Zip File", "*.zip");
fileChooser.getExtensionFilters().add(zipFilter);
File f = fileChooser.showSaveDialog(stage.getOwner());
if (f != null) {
controller.saveZipArchiveReports(f);
}
} finally {
setEntryListLocked(false);
refresh();
}
});
saveBtn.setDisable(true);
cancelBtn.setOnAction(e -> stage.close());
}
private void applyLocalization() {
entriesPane.setText(Localization.getText("ZipEntryManager.entryListTitle"));
metadataPane.setText(Localization.getText("ZipEntryManager.metadata"));
subpathLbl.setText(Localization.getText("ZipEntryManager.subpathLbl"));
erroneousLbl.setText(Localization.getText("ZipEntryManager.erroneousLbl"));
filesizeLbl.setText(Localization.getText("ZipEntryManager.filesizeLbl"));
validatedLbl.setText(Localization.getText("ZipEntryManager.validatedLbl"));
objectCountLbl.setText(Localization.getText("ZipEntryManager.objectCountLbl"));
subpathValueTxt.setText(unknownValueText);
erroneousValue.setText(unknownValueText);
filesizeValue.setText(unknownValueText);
validatedValue.setText(unknownValueText);
objectCountValue.setText(unknownValueText);
loadBtn.setTooltip(new Tooltip(Localization.getText("ZipEntryManager.loadBtn")));
decompressBtn.setTooltip(new Tooltip(Localization.getText("ZipEntryManager.decompressBtn")));
decompressAllBtn.setTooltip(new Tooltip(Localization.getText("ZipEntryManager.decompressAllBtn")));
checkAllBtn.setTooltip(new Tooltip(Localization.getText("ZipEntryManager.checkAllBtn")));
showReportBtn.setTooltip(new Tooltip(Localization.getText("ZipEntryManager.showReportBtn")));
saveBtn.setTooltip(new Tooltip(Localization.getText("ZipEntryManager.saveBtn")));
cancelBtn.setText(Localization.getText("ZipEntryManager.cancelBtn"));
}
private void populateZipEntryList() {
populateZipEntryList(0);
}
private void populateZipEntryList(int selectionIndex) {
entryList.getItems().clear();
for (CityGmlZipEntry entry : archive.getEntries()) {
entryList.getItems().add(new ZipEntryNode(entry));
}
entryList.getSelectionModel().clearSelection();
entryList.getSelectionModel().select(selectionIndex);
showMetadata(entryList.getSelectionModel().getSelectedItem().getEntry());
decompressAllBtn.setDisable(entryList.getItems().stream().allMatch(entryDecompressed));
saveBtn.setDisable(entryList.getItems().stream().noneMatch(entryValidated));
}
private void showMetadata(CityGmlZipEntry entry) {
subpathValueTxt.setText(entry.getEntrySubPath());
if (entry.getFileSize() != -1L) {
long fileSize = entry.getFileSize();
long kb = 1024L;
long mb = kb * kb;
long gb = mb * kb;
if (fileSize < kb) {
filesizeValue.setText("< 1 KB");
} else if (fileSize < mb) {
filesizeValue.setText(String.format("%s KB", fileSize / kb));
} else if (fileSize < gb) {
filesizeValue.setText(String.format("%s MB", fileSize / mb));
} else {
double gigabytes = (double) fileSize / gb;
filesizeValue.setText(String.format("%.2f GB", gigabytes));
}
} else {
filesizeValue.setText(unknownValueText);
}
if (entry.getErrorType() != null) {
erroneousValue.setText(getErrorText(entry.getErrorType()));
validatedValue.setText(unknownValueText);
objectCountValue.setText(unknownValueText);
loadBtn.setDisable(true);
decompressBtn.setDisable(true);
showReportBtn.setDisable(true);
} else {
erroneousValue.setText(Localization.getText("ZipEntryManager.no"));
loadBtn.setDisable(!entry.isLoaded());
decompressBtn.setDisable(entry.isLoaded());
if (entry.getModel() == null) {
validatedValue.setText(unknownValueText);
objectCountValue.setText(unknownValueText);
return;
}
if (entry.getModel().isValidated()) {
validatedValue.setText(Localization.getText("ZipEntryManager.yes"));
showReportBtn.setDisable(false);
} else {
validatedValue.setText(Localization.getText("ZipEntryManager.no"));
showReportBtn.setDisable(true);
}
objectCountValue.setText(String.valueOf(entry.getModel().getNumberOfFeatures()));
}
}
private void disableTaskButtons() {
decompressBtn.setDisable(true);
loadBtn.setDisable(true);
decompressAllBtn.setDisable(true);
showReportBtn.setDisable(true);
saveBtn.setDisable(true);
}
public void refresh() {
populateZipEntryList(entryList.getSelectionModel().getSelectedIndex());
}
private String getErrorText(ZipEntryErrorType error) {
switch (error) {
case EXCESSIVE_FILESIZE -> {
return Localization.getText("ZipEntryManager.excessiveFileSize");
}
case INVALID_CITY_GML_FILE -> {
return Localization.getText("ZipEntryManager.invalidCityGml");
}
default -> {
return Localization.getText("ZipEntryManager.ioError");
}
}
}
private void setEntryListLocked(boolean locked) {
entryList.setMouseTransparent(locked);
entryList.setFocusTraversable(!locked);
}
public void show() {
Platform.runLater(() -> stage.showAndWait());
refresh();
}
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.TrafficAreaObject;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
import java.util.List;
public class AllTrafficAreaNode extends Renderable {
private final List<TrafficAreaObject> areas;
private final String text;
public AllTrafficAreaNode(List<TrafficAreaObject> areas, TrafficAreaObject.TrafficAreaType type) {
this.areas = areas;
this.text = type.toString();
}
@Override
public void refreshTextColor() {
// no use
}
@Override
public String getText() {
return this.text;
}
@Override
public void visit(Renderer renderer) {
renderer.renderTransportation(areas);
}
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.TrafficSpaceObject;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
import java.util.List;
public class AllTrafficSpacesNode extends Renderable {
private final List<TrafficSpaceObject> spaces;
private final String text;
public AllTrafficSpacesNode(List<TrafficSpaceObject> sections, TrafficSpaceObject.TrafficSpaceType type) {
this.spaces = sections;
this.text = type.toString();
}
@Override
public void refreshTextColor() {
// no use
}
@Override
public String getText() {
return this.text;
}
@Override
public void visit(Renderer renderer) {
renderer.renderTransportation(spaces);
}
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.TransportSection;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
import java.util.List;
public class AllTransportSectionNode extends Renderable {
private final List<TransportSection> sections;
private final String text;
public AllTransportSectionNode(List<TransportSection> sections, TransportSection.SectionType type) {
this.sections = sections;
this.text = type.toString();
}
@Override
public void refreshTextColor() {
// no use
}
@Override
public String getText() {
return this.text;
}
@Override
public void visit(Renderer renderer) {
renderer.renderTransportation(sections);
}
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.TunnelConstructiveElement;
import de.hft.stuttgart.citydoctor2.gui.CheckStatus;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
import java.util.List;
public class AllTunnelConstructiveElementsNode extends Renderable{
private final List<TunnelConstructiveElement> constructiveElements;
public AllTunnelConstructiveElementsNode(List<TunnelConstructiveElement> constructiveElements) {
this.constructiveElements = constructiveElements;
}
@Override
public String getText() {
return "Constructive Elements";
}
@Override
public void visit(Renderer renderer) {
renderer.clearCurrentRender();
}
@Override
public void refreshTextColor() {
boolean isValidated = false;
for (TunnelConstructiveElement bce : constructiveElements) {
if (bce.isValidated()) {
isValidated = true;
}
if (bce.containsAnyError()) {
setStatus(CheckStatus.ERROR);
return;
}
}
if (isValidated) {
setStatus(CheckStatus.OK);
} else {
setStatus(CheckStatus.NOT_CHECKED);
}
}
}
......@@ -19,10 +19,11 @@
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeObject;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.gui.CheckStatus;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
public class BridgeNode extends Renderable {
public class BridgeNode extends Renderable implements FeatureNode {
private final BridgeObject bridge;
......@@ -52,4 +53,8 @@ public class BridgeNode extends Renderable {
}
@Override
public CityObject getFeature() {
return bridge;
}
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.gui.CheckStatus;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
public class BuildingNode extends Renderable {
public class BuildingNode extends Renderable implements FeatureNode {
private final Building building;
......@@ -37,4 +38,8 @@ public class BuildingNode extends Renderable {
}
}
@Override
public CityObject getFeature() {
return building;
}
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractRoom;
import de.hft.stuttgart.citydoctor2.datastructure.CityFurniture;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.gui.CheckStatus;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
public class CityFurnitureNode extends Renderable{
public class CityFurnitureNode extends Renderable implements FeatureNode {
private final CityFurniture cityFurniture;
......@@ -34,4 +34,9 @@ public class CityFurnitureNode extends Renderable{
setStatus(CheckStatus.OK);
}
}
@Override
public CityObject getFeature() {
return cityFurniture;
}
}
......@@ -4,7 +4,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.gui.CheckStatus;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
public class CityObjectNode extends Renderable {
public class CityObjectNode extends Renderable implements FeatureNode{
private final CityObject co;
......@@ -33,4 +33,9 @@ public class CityObjectNode extends Renderable {
renderer.render(co);
}
@Override
public CityObject getFeature() {
return co;
}
}
......@@ -39,16 +39,23 @@ import de.hft.stuttgart.citydoctor2.check.error.SurfaceUnfragmentedError;
import de.hft.stuttgart.citydoctor2.check.error.DegeneratedRingError;
import de.hft.stuttgart.citydoctor2.check.error.TooFewPolygonsError;
import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError;
import de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon;
import de.hft.stuttgart.citydoctor2.datastructure.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.gui.CheckStatus;
import de.hft.stuttgart.citydoctor2.math.Triangle3d;
import de.hft.stuttgart.citydoctor2.utils.Localization;
import de.hft.stuttgart.citydoctor2.utils.PolygonIntersection;
import de.hft.stuttgart.citydoctor2.utils.PolygonIntersection.IntersectionType;
import javafx.scene.control.TreeItem;
public class ErrorItemVisitor implements ErrorVisitor {
private static final String NAME_OF_ATTRIBUTE = "Name of Attribute: ";
private static final String CHILD_ID = "ChildId: ";
private static String nameOfAttribute = Localization.getText("ErrorItemVisitor.nameOfAttribute") + ": ";
private static String childId = Localization.getText("ErrorItemVisitor.childId") + ": ";
private final TreeItem<Renderable> root;
public ErrorItemVisitor(TreeItem<Renderable> root) {
......@@ -74,7 +81,7 @@ public class ErrorItemVisitor implements ErrorVisitor {
@Override
public void visit(MultipleConnectedComponentsError err) {
for (int i = 0; i < err.getComponents().size(); i++) {
TextNode textNode = new TextNode("Component " + i);
TextNode textNode = new TextNode(Localization.getText("ErrorItemVisitor.component") + " " + i);
TreeItem<Renderable> textItem = new TreeItem<>(textNode);
root.getChildren().add(textItem);
List<Polygon> component = err.getComponents().get(i);
......@@ -99,7 +106,7 @@ public class ErrorItemVisitor implements ErrorVisitor {
TreeItem<Renderable> vertexItem = new TreeItem<>(vertexNode);
root.getChildren().add(vertexItem);
for (int i = 0; i < err.getComponents().size(); i++) {
TextNode textNode = new TextNode("Component " + i);
TextNode textNode = new TextNode(Localization.getText("ErrorItemVisitor.component") + " " + i);
TreeItem<Renderable> textItem = new TreeItem<>(textNode);
root.getChildren().add(textItem);
List<Polygon> component = err.getComponents().get(i);
......@@ -144,7 +151,7 @@ public class ErrorItemVisitor implements ErrorVisitor {
@Override
public void visit(UnknownCheckError err) {
// not displayed
}
@Override
......@@ -159,11 +166,11 @@ public class ErrorItemVisitor implements ErrorVisitor {
LinearRingNode ringNode = new LinearRingNode(err.getRing(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> ringItem = new TreeItem<>(ringNode);
root.getChildren().add(ringItem);
VertexNode vertexNode = new VertexNode(err.getVertex1());
TreeItem<Renderable> vertexItem = new TreeItem<>(vertexNode);
root.getChildren().add(vertexItem);
vertexNode = new VertexNode(err.getVertex2());
vertexItem = new TreeItem<>(vertexNode);
root.getChildren().add(vertexItem);
......@@ -193,7 +200,7 @@ public class ErrorItemVisitor implements ErrorVisitor {
LinearRingNode ringNode = new LinearRingNode(err.getRing(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> ringItem = new TreeItem<>(ringNode);
root.getChildren().add(ringItem);
if (err.getRing().getGmlId().isGenerated()) {
PolygonNode polyNode = new PolygonNode(err.getRing().getParent(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> polyItem = new TreeItem<>(polyNode);
......@@ -206,8 +213,9 @@ public class ErrorItemVisitor implements ErrorVisitor {
PolygonNode polyNode = new PolygonNode(err.getPolygon(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> polyItem = new TreeItem<>(polyNode);
root.getChildren().add(polyItem);
TextNode textNode = new TextNode("Deviation: " + err.getDeviation());
TextNode textNode = new TextNode(
Localization.getText("ErrorItemVisitor.deviation") + ": " + err.getDeviation());
TreeItem<Renderable> textItem = new TreeItem<>(textNode);
root.getChildren().add(textItem);
}
......@@ -217,15 +225,16 @@ public class ErrorItemVisitor implements ErrorVisitor {
PolygonNode polyNode = new PolygonNode(err.getPolygon(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> polyItem = new TreeItem<>(polyNode);
root.getChildren().add(polyItem);
VertexNode vertexNode = new VertexNode(err.getVertex());
TreeItem<Renderable> vertexItem = new TreeItem<>(vertexNode);
root.getChildren().add(vertexItem);
TextNode textNode = new TextNode("Distance: " + err.getDistance() + "m");
TextNode textNode = new TextNode(
Localization.getText("ErrorItemVisitor.distance") + ": " + err.getDistance() + "m");
TreeItem<Renderable> textItem = new TreeItem<>(textNode);
root.getChildren().add(textItem);
}
@Override
......@@ -237,18 +246,54 @@ public class ErrorItemVisitor implements ErrorVisitor {
@Override
public void visit(SolidSelfIntError err) {
PolygonNode polyNode1 = new PolygonNode(err.getIntersections().get(0).getP1(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> polyItem1 = new TreeItem<>(polyNode1);
root.getChildren().add(polyItem1);
PolygonNode polyNode2 = new PolygonNode(err.getIntersections().get(0).getP2(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> polyItem2 = new TreeItem<>(polyNode2);
root.getChildren().add(polyItem2);
List<PolygonIntersection> intersections = err.getIntersections();
for (int i = 0; i < intersections.size(); i++) {
PolygonIntersection pi = intersections.get(i);
TextNode intersectionNode = new TextNode(Localization.getText("ErrorItemVisitor.intersection") + " " + i);
TreeItem<Renderable> intersectionItem = new TreeItem<>(intersectionNode);
root.getChildren().add(intersectionItem);
PolygonNode polyNode1 = new PolygonNode(pi.getP1(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> polyItem1 = new TreeItem<>(polyNode1);
intersectionItem.getChildren().add(polyItem1);
PolygonNode polyNode2 = new PolygonNode(pi.getP2(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> polyItem2 = new TreeItem<>(polyNode2);
intersectionItem.getChildren().add(polyItem2);
PolygonIntersection intersection = err.getIntersections().get(0);
if (intersection.getType() == IntersectionType.TRIANGLES) {
TextNode trianglesNode = new TextNode(Localization.getText("ErrorItemVisitor.triangles"));
TreeItem<Renderable> trianglesItem = new TreeItem<>(trianglesNode);
intersectionItem.getChildren().add(trianglesItem);
ConcretePolygon c = createPolygonForTriangle(intersection.getT1());
PolygonNode pN1 = new PolygonNode(c, CheckStatus.NOT_CHECKED);
TreeItem<Renderable> pI1 = new TreeItem<>(pN1);
trianglesItem.getChildren().add(pI1);
ConcretePolygon c2 = createPolygonForTriangle(intersection.getT2());
PolygonNode pN2 = new PolygonNode(c2, CheckStatus.NOT_CHECKED);
TreeItem<Renderable> pI2 = new TreeItem<>(pN2);
trianglesItem.getChildren().add(pI2);
}
}
}
private ConcretePolygon createPolygonForTriangle(Triangle3d t) {
ConcretePolygon c = new ConcretePolygon();
LinearRing extRing = new LinearRing(LinearRingType.EXTERIOR);
Vertex start = new Vertex(t.getP1());
extRing.getVertices().add(start);
extRing.getVertices().add(new Vertex(t.getP2()));
extRing.getVertices().add(new Vertex(t.getP3()));
extRing.getVertices().add(start);
c.setExteriorRing(extRing);
return c;
}
@Override
public void visit(TooFewPolygonsError err) {
// not displayed
}
@Override
......@@ -256,11 +301,11 @@ public class ErrorItemVisitor implements ErrorVisitor {
LinearRingNode ringNode = new LinearRingNode(err.getRing(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> ringItem = new TreeItem<>(ringNode);
root.getChildren().add(ringItem);
VertexNode vertexNode = new VertexNode(err.getVertex1());
TreeItem<Renderable> vertexItem = new TreeItem<>(vertexNode);
root.getChildren().add(vertexItem);
vertexNode = new VertexNode(err.getVertex2());
vertexItem = new TreeItem<>(vertexNode);
root.getChildren().add(vertexItem);
......@@ -272,11 +317,11 @@ public class ErrorItemVisitor implements ErrorVisitor {
LinearRingNode ringNode = new LinearRingNode(err.getRing(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> ringItem = new TreeItem<>(ringNode);
root.getChildren().add(ringItem);
EdgeNode edgeNode = new EdgeNode(err.getEdge1());
TreeItem<Renderable> edgeItem = new TreeItem<>(edgeNode);
root.getChildren().add(edgeItem);
EdgeNode edge2Node = new EdgeNode(err.getEdge2());
TreeItem<Renderable> edge2Item = new TreeItem<>(edge2Node);
root.getChildren().add(edge2Item);
......@@ -288,18 +333,18 @@ public class ErrorItemVisitor implements ErrorVisitor {
@Override
public void visit(PointTouchesEdgeError err) {
TextNode textNode = new TextNode("Point touches edge");
TextNode textNode = new TextNode(Localization.getText("ErrorItemVisitor.pointTouchesEdge"));
TreeItem<Renderable> textItem = new TreeItem<>(textNode);
root.getChildren().add(textItem);
VertexNode vertexNode = new VertexNode(err.getVertex());
TreeItem<Renderable> vertexItem = new TreeItem<>(vertexNode);
root.getChildren().add(vertexItem);
EdgeNode edgeNode = new EdgeNode(err.getEdge());
TreeItem<Renderable> edgeItem = new TreeItem<>(edgeNode);
root.getChildren().add(edgeItem);
LinearRingNode ringNode = new LinearRingNode(err.getRing(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> ringItem = new TreeItem<>(ringNode);
root.getChildren().add(ringItem);
......@@ -337,7 +382,7 @@ public class ErrorItemVisitor implements ErrorVisitor {
public void visit(CheckError err) {
// not used
}
@Override
public void visit(SchematronError err) {
TextNode textNode = new TextNode(err.getErrorIdString());
......@@ -347,17 +392,18 @@ public class ErrorItemVisitor implements ErrorVisitor {
@Override
public void visit(SurfaceUnfragmentedError err) {
TextNode textNode = new TextNode("Deviation: " + err.getAngleDeviation());
TextNode textNode = new TextNode(
Localization.getText("ErrorItemVisitor.deviation") + ": " + err.getAngleDeviation());
TreeItem<Renderable> textItem = new TreeItem<>(textNode);
root.getChildren().add(textItem);
}
@Override
public void visit(DegeneratedRingError err) {
TextNode textNode = new TextNode("Type: degenerated ring");
TextNode textNode = new TextNode(Localization.getText("ErrorItemVisitor.degeneratedRing"));
TreeItem<Renderable> textItem = new TreeItem<>(textNode);
root.getChildren().add(textItem);
LinearRingNode polyNode = new LinearRingNode(err.getRing(), CheckStatus.NOT_CHECKED);
TreeItem<Renderable> polyItem = new TreeItem<>(polyNode);
root.getChildren().add(polyItem);
......@@ -366,11 +412,11 @@ public class ErrorItemVisitor implements ErrorVisitor {
@Override
public void visit(AttributeMissingError err) {
if (!err.getChildId().isEmpty()) {
TextNode textNode = new TextNode(CHILD_ID + err.getChildId());
TextNode textNode = new TextNode(childId + err.getChildId());
TreeItem<Renderable> textItem = new TreeItem<>(textNode);
root.getChildren().add(textItem);
}
TextNode nameNode = new TextNode(NAME_OF_ATTRIBUTE + err.getNameOfAttribute());
TextNode nameNode = new TextNode(nameOfAttribute + err.getNameOfAttribute());
TreeItem<Renderable> nameItem = new TreeItem<>(nameNode);
root.getChildren().add(nameItem);
......@@ -379,23 +425,23 @@ public class ErrorItemVisitor implements ErrorVisitor {
@Override
public void visit(AttributeValueWrongError err) {
if (!err.getChildId().isEmpty()) {
TextNode textNode = new TextNode(CHILD_ID + err.getChildId());
TextNode textNode = new TextNode(childId + err.getChildId());
TreeItem<Renderable> textItem = new TreeItem<>(textNode);
root.getChildren().add(textItem);
}
TextNode nameNode = new TextNode(NAME_OF_ATTRIBUTE + err.getNameOfAttribute());
TextNode nameNode = new TextNode(nameOfAttribute + err.getNameOfAttribute());
TreeItem<Renderable> nameItem = new TreeItem<>(nameNode);
root.getChildren().add(nameItem);
}
@Override
public void visit(AttributeInvalidError err) {
if (!err.getChildId().isEmpty()) {
TextNode textNode = new TextNode(CHILD_ID + err.getChildId());
TextNode textNode = new TextNode(childId + err.getChildId());
TreeItem<Renderable> textItem = new TreeItem<>(textNode);
root.getChildren().add(textItem);
}
TextNode nameNode = new TextNode(NAME_OF_ATTRIBUTE + err.getNameOfAttribute());
TextNode nameNode = new TextNode(nameOfAttribute + err.getNameOfAttribute());
TreeItem<Renderable> nameItem = new TreeItem<>(nameNode);
root.getChildren().add(nameItem);
}
......
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
public interface FeatureNode {
public CityObject getFeature();
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.GenericCityObject;
import de.hft.stuttgart.citydoctor2.gui.CheckStatus;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
public class GenericCityObjectsNode extends Renderable{
public class GenericCityObjectsNode extends Renderable implements FeatureNode {
private final GenericCityObject gcobject;
......@@ -33,4 +34,9 @@ public class GenericCityObjectsNode extends Renderable{
setStatus(CheckStatus.OK);
}
}
@Override
public CityObject getFeature() {
return gcobject;
}
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject;
import de.hft.stuttgart.citydoctor2.gui.CheckStatus;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
public class TransportationObjectNode extends Renderable {
private final TransportationObject to;
public TransportationObjectNode(TransportationObject to) {
this.to = to;
}
@Override
public String getText() {
return to.getGmlId().getGmlString();
}
@Override
public void visit(Renderer renderer) {
renderer.render(to);
}
@Override
public void refreshTextColor() {
if (!to.isValidated()) {
setStatus(CheckStatus.NOT_CHECKED);
} else if (to.containsAnyError()) {
setStatus(CheckStatus.ERROR);
} else {
setStatus(CheckStatus.OK);
}
}
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.TunnelConstructiveElement;
import de.hft.stuttgart.citydoctor2.gui.CheckStatus;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
public class TunnelConstructiveElementNode extends Renderable{
private final TunnelConstructiveElement tce;
public TunnelConstructiveElementNode(TunnelConstructiveElement tce) {
this.tce = tce;
}
@Override
public String getText() {
return tce.getGmlId().getGmlString();
}
@Override
public void visit(Renderer renderer) {
renderer.render(tce);
}
@Override
public void refreshTextColor() {
if (!tce.isValidated()) {
setStatus(CheckStatus.NOT_CHECKED);
} else if (tce.containsAnyError()) {
setStatus(CheckStatus.ERROR);
} else {
setStatus(CheckStatus.OK);
}
}
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.Tunnel;
import de.hft.stuttgart.citydoctor2.gui.CheckStatus;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
public class TunnelNode extends Renderable{
public class TunnelNode extends Renderable implements FeatureNode {
private final Tunnel tunnel;
......@@ -36,4 +37,9 @@ public class TunnelNode extends Renderable{
setStatus(CheckStatus.OK);
}
}
@Override
public CityObject getFeature() {
return tunnel;
}
}
......@@ -18,11 +18,12 @@
*/
package de.hft.stuttgart.citydoctor2.gui.tree;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.Vegetation;
import de.hft.stuttgart.citydoctor2.gui.CheckStatus;
import de.hft.stuttgart.citydoctor2.gui.Renderer;
public class VegetationNode extends Renderable {
public class VegetationNode extends Renderable implements FeatureNode {
private final Vegetation veg;
private final String text;
......@@ -53,4 +54,8 @@ public class VegetationNode extends Renderable {
renderer.render(veg);
}
@Override
public CityObject getFeature() {
return veg;
}
}
package de.hft.stuttgart.citydoctor2.gui.tree;
import javafx.scene.control.ListCell;
public class ZipEntryListCell extends ListCell<ZipEntryNode> {
@Override
protected void updateItem(ZipEntryNode item, boolean empty) {
super.updateItem(item, empty);
if (!empty || item != null) {
setText(item.getText());
updateColor();
} else {
setText(null);
}
}
public void updateColor() {
setTextFill(getItem().getTextColor());
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment