mirror of
https://codeberg.org/qg-info-unterricht/zpg-graphentester.git
synced 2026-03-25 04:58:24 +01:00
593 lines
18 KiB
Java
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);
|
|
}
|
|
}
|