zpg-graphentester/control/UnterTabMitController.java
2021-07-12 14:04:20 +02:00

593 lines
18 KiB
Java

package control;
import imp.*;
import graph.*;
import javafx.fxml.*;
import javafx.scene.control.*;
import javafx.event.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.Node;
import javafx.scene.text.*;
import javafx.geometry.Pos;
import javafx.collections.FXCollections;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Optional;
import javafx.collections.ObservableList;
/**
* Die Klasse UnterTabMitController stellt einen Tab inclusive ihres Controllers
* zur händischen Erforschung eines Algorithmus. Es wird immer ein einzelner Knoten
* oder eine Kante fokussiert.
*
* @author Thomas Schaller
* @version v6.7 (9.12.2020)
*/
public class UnterTabMitController extends TabMitController {
@FXML
private VBox infoBox;
@FXML
private Button wertButton;
@FXML
private Button besuchtButton;
@FXML
private Label knotenname;
@FXML
private Label knotenwert;
@FXML
private Label knotenMarkiert;
@FXML
private Label knotenBesucht;
@FXML
private GridPane farben;
@FXML
Button bStatus;
@FXML
Button bGehezu;
@FXML
Button bAnfang;
@FXML
Button bEnde;
@FXML
Button bSortieren;
@FXML
private CheckBox cbFarbeAutomatisch;
@FXML
private ListView<String> lvAuswahl;
private List<GraphElement> auswahl;
private List<String> sicherung;
public UnterTabMitController(Graph graph, GraphOptions options) {
this.graph = graph;
this.options = options;
}
public void initialize() {
if(graph.getAnzahlKnoten()==0) {
getTabPane().getTabs().remove(this);
return;
}
buildAuswahl();
this.bAnfang.managedProperty().bind(bAnfang.visibleProperty());
this.bEnde.managedProperty().bind(bEnde.visibleProperty());
this.bSortieren.managedProperty().bind(bSortieren.visibleProperty());
viewer.setGraph(graph,options);
viewer.setHvalue(0.5);
viewer.setVvalue(0.5);
//auswahl = viewer.getGraph().getAlleKnoten();
for(int x = 0; x< 4; x++) {
for(int y = 0; y <3; y++) {
Label l = new Label();
l.setPrefSize(20,20);
l.setMaxSize(200, 200);
if(options.farbenKnoten.length > y*4+x) {
l.setStyle("-fx-background-color:#"+options.farbenKnoten[y*4+x]);
l.setAlignment(Pos.CENTER);
l.setFont(Font.font("System", FontWeight.BOLD, 12));
}
else
l.setStyle("-fx-background-color:#FFFFFF");
l.setOnMouseClicked(e -> knotenFarbe(e));
farben.add(l, x, y);
}
}
fillLvAuswahl();
lvAuswahl.getSelectionModel().selectedItemProperty().addListener(
(obs, oldValue, newValue) -> showAuswahl());
cbFarbeAutomatisch.selectedProperty().addListener((o, oldValue, newValue) -> {
Knoten k = viewer.getSelectedKnoten();
if (k!=null) {
k.setFarbeAutomatisch(newValue);
viewer.updateImage();
updateInfofeld();
}
});
super.initialize();
}
public void setGraph(Graph graph, GraphOptions options) {
if(graph.getAnzahlKnoten()==0) {
getTabPane().getTabs().remove(this);
return;
}
options.fokusArt = this.options.fokusArt;
options.auswahl = this.options.auswahl;
options.bildAnzeigen = false;
if(options.fokusArt == 0 && this.options.parent!= null) options.parent = graph.getKnoten(0);
if(options.fokusArt == 1 && this.options.parent!= null) options.parent = graph.getKante(0,1);
this.graph = graph;
this.options = options;
viewer.setRestrictTo(null);
buildAuswahl();
super.setGraph(graph,options);
}
public void buildAuswahl() {
auswahl = new ArrayList<GraphElement>();
if(options.auswahl == 0) { // Alle Knoten/Kanten gewählt
if(options.fokusArt == 0) // Knoten
auswahl = new ArrayList<GraphElement>(graph.getAlleKnoten());
else
auswahl = new ArrayList<GraphElement>(graph.getAlleKanten());
} else {
if(options.auswahl == 1) { // Nachbarn
auswahl = new ArrayList<GraphElement>(graph.getNachbarknoten(((Knoten) (options.parent))));
} else { // single
auswahl.add(options.parent);
}
}
if(auswahl.size() == 0) getTabPane().getTabs().remove(this);
}
public void update() {
super.update();
updateInfofeld();
fillLvAuswahl();
}
private void fillLvAuswahl() {
if(auswahl.size()==0 ) {
getTabPane().getTabs().remove(this);
} else {
ObservableList<String> items = FXCollections.observableArrayList ();
for(GraphElement ge : auswahl) {
if(ge instanceof Knoten) {
Knoten k = (Knoten) ge;
String beschreibung="";
if(options.showVertexInfo && !k.getInfotext().isEmpty())
beschreibung = k.getInfotext();
else
beschreibung = "Knoten"+ graph.getNummer(k);
if(options.showVertexValue) {
if(k.getDoubleWert() == k.getIntWert())
beschreibung += " ("+k.getIntWert()+")";
else
beschreibung += " ("+k.getDoubleWert()+")";
}
items.add(beschreibung);
}
if(ge instanceof Kante) {
Kante k = (Kante) ge;
if(options.showEdgeWeights) {
if(k.getGewicht() == (int) k.getGewicht())
items.add("Kante ("+((int)k.getGewicht())+")");
else
items.add("Kante ("+k.getGewicht()+")");
}
else
items.add("Kante Nr."+graph.getNummer(k));
}
}
lvAuswahl.setItems(items);
showAuswahl();
}
}
private void showAuswahl() {
if(lvAuswahl.getSelectionModel().getSelectedIndex()==-1) {
if(auswahl.contains(viewer.getRestrictTo())) {
lvAuswahl.getSelectionModel().select(auswahl.indexOf(viewer.getRestrictTo()));
} else {
lvAuswahl.getSelectionModel().selectFirst();
}
}
viewer.setRestrictTo(auswahl.get(lvAuswahl.getSelectionModel().getSelectedIndex()));
updateInfofeld();
}
public void setAuswahl(List<GraphElement> auswahl) {
this.auswahl = auswahl;
fillLvAuswahl();
}
@FXML
void bAnfang(ActionEvent event) {
if(lvAuswahl.getSelectionModel().getSelectedIndex() > 0) {
lvAuswahl.getSelectionModel().selectFirst();
showAuswahl();
}
}
@FXML
void bBesucht(ActionEvent event) {
Knoten k = viewer.getSelectedKnoten();
if (k!=null) {
k.setBesucht(!k.isBesucht());
viewer.updateImage();
updateInfofeld();
}else {
Kante ka = viewer.getSelectedKante();
if(ka!=null) {
ka.setGeloescht(!ka.isGeloescht());
viewer.updateImage();
updateInfofeld();
}
}
}
@FXML
void bEnde(ActionEvent event) {
if(lvAuswahl.getSelectionModel().getSelectedIndex() < lvAuswahl.getItems().size()-1) {
lvAuswahl.getSelectionModel().selectLast();
showAuswahl();
}
}
@FXML
void knotenFarbe(MouseEvent event) {
Node source = (Node) event.getSource();
Integer colIndex = farben.getColumnIndex(source);
Integer rowIndex = farben.getRowIndex(source);
Knoten k = viewer.getSelectedKnoten();
if (k!=null) {
k.setFarbe(rowIndex*4+colIndex);
ObservableList<Node> ln = farben.getChildren();
for(Node n : ln) {
if(n instanceof Label)
if(n == source){
((Label) n).setText("X");
}
else
((Label) n).setText(" ");
}
viewer.updateImage();
updateInfofeld();
}
}
@FXML
void bMarkieren(ActionEvent event) {
Knoten k = viewer.getSelectedKnoten();
if (k!=null) {
k.setMarkiert(!k.isMarkiert());
viewer.updateImage();
updateInfofeld();
} else {
Kante ka = viewer.getSelectedKante();
if(ka!=null) {
ka.setMarkiert(!ka.isMarkiert());
viewer.updateImage();
updateInfofeld();
}
}
}
public void updateInfofeld() {
GraphElement f = viewer.getRestrictTo();
if( f instanceof Knoten) {
this.setText(viewer.getGraph().getKnoteninfo((Knoten) f, false));
}
Knoten k = viewer.getSelectedKnoten();
Kante ka = viewer.getSelectedKante();
if(k!=null) {
infoBox.setVisible(true);
knotenname.setText("Knoten: "+viewer.getGraph().getNummer(k));
knotenwert.setText("Wert: "+k.getDoubleWert());
knotenMarkiert.setText(k.isMarkiert() ? "markiert" : "unmarkiert");
knotenBesucht.setText(k.isBesucht() ? "besucht" : "nicht besucht");
besuchtButton.setText("Besuchen");
wertButton.setVisible(true);
farben.setVisible(true);
bGehezu.setVisible(k != viewer.getRestrictTo());
bAnfang.setVisible(k != viewer.getRestrictTo());
bEnde.setVisible(k != viewer.getRestrictTo());
bSortieren.setVisible((options.showEdgeWeights && auswahl.get(0) instanceof Kante) || (options.showVertexValue && auswahl.get(0) instanceof Knoten));
cbFarbeAutomatisch.setSelected(k.isFarbeAutomatisch());
ObservableList<Node> ln = farben.getChildren();
for(Node n : ln) {
if(n instanceof Label){
Integer colIndex = farben.getColumnIndex(n);
Integer rowIndex = farben.getRowIndex(n);
if(rowIndex*4+colIndex == k.getFarbe()){
((Label) n).setText("X");
}
else
((Label) n).setText(" ");
}
}
} else {
if(ka != null) {
infoBox.setVisible(true);
knotenname.setText("Kante:");
knotenwert.setText("Gewicht: "+ka.getGewicht());
knotenMarkiert.setText(ka.isMarkiert() ? "markiert" : "unmarkiert");
knotenBesucht.setText(ka.isGeloescht() ? "gelöscht" : "nicht gelöscht");
besuchtButton.setText("Löschen");
wertButton.setVisible(false);
farben.setVisible(false);
}
else
infoBox.setVisible(false);
}
}
@FXML
void graphClicked(MouseEvent event) {
viewer.mouseClicked(event);
updateInfofeld();
if(viewer.getSelectedKnoten() != null && event.isSecondaryButtonDown()) { // Contextmenu
ContextMenu contextMenu = new ContextMenu();
CheckMenuItem item1 = new CheckMenuItem("Markiert");
item1.setSelected(viewer.getSelectedKnoten().isMarkiert());
item1.setOnAction((e) -> this.bMarkieren(e));
CheckMenuItem item2 = new CheckMenuItem("Besucht");
item2.setOnAction((e) -> this.bBesucht(e));
item2.setSelected(viewer.getSelectedKnoten().isBesucht());
MenuItem item3 = new MenuItem("Wert ändern");
item3.setOnAction((e) -> this.bWertAendern(e));
MenuItem item5 = new MenuItem("Füge am Anfang der ToDo-Liste hinzu");
item5.setOnAction((e) -> this.bHinzufuegenAnfang(e));
MenuItem item6 = new MenuItem("Füge am Ende der ToDo-Liste hinzu");
item6.setOnAction((e) -> this.bHinzufuegenEnde(e));
MenuItem item7 = new MenuItem("Loesche aus Liste");
item7.setOnAction((e) -> this.bLoeschenAusListe(e));
SeparatorMenuItem sep = new SeparatorMenuItem();
SeparatorMenuItem sep2 = new SeparatorMenuItem();
MenuItem item4 = new MenuItem("Gehe zu ...");
item4.setOnAction((e) -> this.bGeheZu(e));
// Add MenuItem to ContextMenu
contextMenu.getItems().addAll(item3, item1, item2, sep, item5, item6, item7, sep2, item4);
contextMenu.show(viewer, event.getScreenX(), event.getScreenY());
}
if(viewer.getSelectedKante() != null && event.isSecondaryButtonDown()) { // Contextmenu
ContextMenu contextMenu = new ContextMenu();
CheckMenuItem item1 = new CheckMenuItem("Markiert");
item1.setSelected(viewer.getSelectedKante().isMarkiert());
item1.setOnAction((e) -> this.bMarkieren(e));
CheckMenuItem item2 = new CheckMenuItem("Gelöscht");
item2.setSelected(viewer.getSelectedKante().isGeloescht());
item2.setOnAction((e) -> this.bBesucht(e));
SeparatorMenuItem sep = new SeparatorMenuItem();
MenuItem item4 = new MenuItem("Gehe zu ...");
item4.setOnAction((e) -> this.bGeheZu(e));
// Add MenuItem to ContextMenu
contextMenu.getItems().addAll( item1, item2, sep, item4);
contextMenu.show(viewer, event.getScreenX(), event.getScreenY());
}
}
@FXML
void bHinzufuegenAnfang(ActionEvent event) {
Knoten k = viewer.getSelectedKnoten();
if(k!=null) {
auswahl.add(0,k);
fillLvAuswahl();
}
}
@FXML
void bHinzufuegenEnde(ActionEvent event) {
Knoten k = viewer.getSelectedKnoten();
if(k!=null) {
auswahl.add(k);
fillLvAuswahl();
}
}
@FXML
void bLoeschenAusListe(ActionEvent event) {
Knoten k = viewer.getSelectedKnoten();
if(k!=null && auswahl.contains(k)) {
auswahl.remove(k);
fillLvAuswahl();
}
}
@FXML
void bNaechster(ActionEvent event) {
if(lvAuswahl.getSelectionModel().isSelected(auswahl.size()-1))
lvAuswahl.getSelectionModel().selectFirst();
else
lvAuswahl.getSelectionModel().selectNext();
showAuswahl();
}
// @FXML
// void bListeAnpassen(ActionEvent event) {
// buildAuswahl();
// fillLvAuswahl();
// }
// @FXML
// void bNeuerTab(ActionEvent event) {
// GraphOptions neu = options.copy();
// neu.parent = viewer.getRestrictTo();
// if(neu.parent == null) neu.parent = viewer.getSelectedKnoten();
// neu.bildAnzeigen = false;
// tabOeffnen(neu);
// }
@FXML
void bSort(ActionEvent event) {
Collections.sort(auswahl);
fillLvAuswahl();
}
@FXML
void bVoheriger(ActionEvent event) {
if(lvAuswahl.getSelectionModel().isSelected(0))
lvAuswahl.getSelectionModel().selectLast();
else
lvAuswahl.getSelectionModel().selectPrevious();
showAuswahl();
}
@FXML
void bWertAendern(ActionEvent event) {
Knoten k = viewer.getSelectedKnoten();
if (k!=null) {
TextInputDialog dialog = new TextInputDialog(""+k.getDoubleWert());
dialog.setTitle("Wert ändern");
dialog.setContentText("Bitte geben Sie den neuen Wert ein:");
Optional<String> result = dialog.showAndWait();
if (result.isPresent()){
try{
double v = Double.parseDouble(result.get());
k.setWert(v);
this.fillLvAuswahl();
viewer.updateImage();
updateInfofeld();
} catch (Exception e) {
System.out.println("Keine Zahl eingegeben");
}
}
}
}
@FXML
void bGeheZu(ActionEvent event) {
Knoten k = viewer.getSelectedKnoten();
if (k!=null) {
GraphOptions neu = options.copy();
neu.auswahl = 2; // single
neu.parent = k;
neu.bildAnzeigen = false;
this.tabOeffnen(neu);
}
}
@FXML
void mBeenden(ActionEvent event) {
}
@FXML
void mBesucheKnoten(ActionEvent event) {
}
@FXML
void mBesuchtLoeschen(ActionEvent event) {
}
@FXML
void mFaerbeKnoten(ActionEvent event) {
}
@FXML
void mMarkiereKnoten(ActionEvent event) {
}
@FXML
void mMarkierungenLoeschen(ActionEvent event) {
}
@FXML
void mOeffnen(ActionEvent event) {
}
@FXML
void mSchliessen(ActionEvent event) {
}
@FXML
void mSpeichern(ActionEvent event) {
}
@FXML
void mUeber(ActionEvent event) {
}
@FXML
void mWertSetzen(ActionEvent event) {
}
@FXML
void mZurueck(ActionEvent event) {
}
@FXML
void bStatusRestore(ActionEvent event) {
if(sicherung != null) { graph.setStatus(sicherung); update(); }
}
@FXML
void bStatusSave(ActionEvent event) {
sicherung = graph.getStatus();
bStatus.setDisable(false);
}
}