mirror of
https://codeberg.org/qg-info-unterricht/zpg-graphentester.git
synced 2026-03-25 04:58:24 +01:00
Sync with upstream
This commit is contained in:
parent
39a2f13410
commit
66e8fa72bf
135 changed files with 38902 additions and 37757 deletions
|
|
@ -1,6 +1,11 @@
|
|||
package graph;
|
||||
|
||||
import imp.*;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.geometry.Pos;
|
||||
|
|
@ -12,13 +17,18 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.util.Duration;
|
||||
import javafx.animation.AnimationTimer;
|
||||
import java.awt.image.*;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
/**
|
||||
* Der GraphPlotter ist das Herzstueck der Visualisierung und dient als Schnittstelle zur GUI.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version 09.12.2020 (v6.7)
|
||||
* @version 07.02.2023 (v7.0)
|
||||
* v6.9: Context-Menü schließt, wenn an andere Stelle geklickt wird
|
||||
* v7.0: MouseOver - Infos für Knoten und Kanten, Infos können ausgewählt werden.
|
||||
*
|
||||
*/
|
||||
public class GraphPlotter extends PictureViewer {
|
||||
// Anfang Attribute
|
||||
|
|
@ -38,6 +48,9 @@ public class GraphPlotter extends PictureViewer {
|
|||
private GraphElement restrictTo = null;
|
||||
private Point2D offset = new Point2D(0,0);
|
||||
|
||||
private ObjectProperty<Point2D> mouseLocation = new SimpleObjectProperty<Point2D>(new Point2D(0, 0));
|
||||
private BooleanProperty mouseMoving = new SimpleBooleanProperty();
|
||||
|
||||
// private JTextArea jTAMeldungen = new JTextArea("");
|
||||
// private JScrollPane jTAMeldungenScrollPane = new JScrollPane(jTAMeldungen);
|
||||
|
||||
|
|
@ -51,36 +64,41 @@ public class GraphPlotter extends PictureViewer {
|
|||
* @param String hintergrundBild Gibt den Namen eines Hintergrundbildes an
|
||||
*/
|
||||
public GraphPlotter() {
|
||||
options = new GraphOptions();
|
||||
graph = new Graph();
|
||||
options = new GraphOptions(graph);
|
||||
|
||||
this.setStyle("-fx-background:#FFFFE8");
|
||||
|
||||
// add(jTAMeldungenScrollPane, BorderLayout.SOUTH);
|
||||
setOnMouseClicked(mouseEvent -> mouseClicked(mouseEvent));
|
||||
// setOnMouseMoved(mouseEvent -> { mouseX = mouseEvent.getSceneX(); mouseY = mouseEvent.getSceneY(); t.hide();});
|
||||
this.widthProperty().addListener((value, oldWidth, newWidth) -> updateImage());
|
||||
this.heightProperty().addListener((value, oldWidth, newWidth) -> updateImage());
|
||||
|
||||
// t = new Tooltip();
|
||||
// Tooltip.install(this, t);
|
||||
// t.setPrefWidth(80);
|
||||
// t.setWrapText(true);
|
||||
// t.setHideOnEscape(true);
|
||||
// t.setStyle("-fx-background: rgba(30,30,30); -fx-text-fill: black; -fx-background-color: rgba(230,230,90,0.8);"+
|
||||
// "-fx-background-radius: 6px; -fx-background-insets: 0; -fx-padding: 0.667em 0.75em 0.667em 0.75em; "+
|
||||
// " -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.5) , 10, 0.0 , 0 , 3 ); -fx-font-size: 0.85em;");
|
||||
setOnMouseMoved(e -> mouseLocation.set(new Point2D(e.getSceneX(), e.getSceneY())));
|
||||
mouseMoving.addListener((obs, wasMoving, isNowMoving) -> {
|
||||
updateImage();
|
||||
});
|
||||
|
||||
// t.setShowDelay(Duration.seconds(1));
|
||||
// t.setOnShowing(ev -> {// called just prior to being shown
|
||||
// Point2D local = this.getContent().sceneToLocal(mouseX, mouseY);
|
||||
// Knoten k = getKnotenAt((int) local.getX(), (int) local.getY());
|
||||
// if(k == null) {
|
||||
// t.hide();
|
||||
// } else {
|
||||
// t.setText("Knoten Nr. "+graph.getNummer(k)+"\nWert: "+k.getDoubleWert());
|
||||
// }
|
||||
// });
|
||||
AnimationTimer timer = new AnimationTimer() {
|
||||
private double lastMouseX ;
|
||||
private double lastMouseY ;
|
||||
long lastMouseMovement ;
|
||||
long MIN_STATIONARY_TIME = 2000;
|
||||
@Override
|
||||
public void handle(long timestamp) {
|
||||
double x = mouseLocation.get().getX();
|
||||
double y = mouseLocation.get().getY();
|
||||
if (Math.abs(lastMouseX-x) > 5 || Math.abs(lastMouseY-y)>5) {
|
||||
lastMouseMovement = timestamp ;
|
||||
lastMouseX = x;
|
||||
lastMouseY = y;
|
||||
}
|
||||
|
||||
mouseMoving.set(timestamp - lastMouseMovement < MIN_STATIONARY_TIME);
|
||||
|
||||
}
|
||||
};
|
||||
timer.start();
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -101,10 +119,10 @@ public class GraphPlotter extends PictureViewer {
|
|||
|
||||
public void setRestrictTo(GraphElement k) {
|
||||
if(restrictTo != k) {
|
||||
restrictTo = k;
|
||||
selected.clear();
|
||||
if (k!= null) selected.add(k);
|
||||
updateImage();
|
||||
restrictTo = k;
|
||||
selected.clear();
|
||||
if (k!= null) selected.add(k);
|
||||
updateImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -175,7 +193,9 @@ public class GraphPlotter extends PictureViewer {
|
|||
Point2D local = this.getContent().sceneToLocal(mouseEvent.getSceneX(), mouseEvent.getSceneY());
|
||||
Knoten k = getKnotenAt((int) local.getX(), (int) local.getY());
|
||||
if(dragMode == 3 && k==null && getKanteAt((int) local.getX(), (int) local.getY())==null) { // neuer Knoten
|
||||
graph.neuerKnoten(new Knoten((int)local.getX(), (int) local.getY())) ;
|
||||
if(getContextMenu() == null) {
|
||||
graph.neuerKnoten(new Knoten((int)local.getX(), (int) local.getY())) ;
|
||||
} else { setContextMenu(null); }
|
||||
} else {
|
||||
if(dragMode == 2 && k != null && k != dragKnoten) {
|
||||
graph.neueKante(dragKnoten, k, 0.0);
|
||||
|
|
@ -323,6 +343,9 @@ public class GraphPlotter extends PictureViewer {
|
|||
}
|
||||
|
||||
public Picture updateImage() {
|
||||
Picture p = new Picture(2000,2000,"FFFFE8");
|
||||
Graphics2D g = (Graphics2D) p.getImage().getGraphics();
|
||||
|
||||
Knoten restrictToKnoten = null;
|
||||
Kante restrictToKante = null;
|
||||
if(restrictTo != null && restrictTo instanceof Knoten) restrictToKnoten = (Knoten) restrictTo;
|
||||
|
|
@ -340,8 +363,6 @@ public class GraphPlotter extends PictureViewer {
|
|||
miny = Math.min(miny,k.getY());
|
||||
}
|
||||
|
||||
Picture p = new Picture(2000,2000,"FFFFE8");
|
||||
|
||||
if(restrictToKnoten != null) {
|
||||
knoten = graph.getNachbarknoten(restrictToKnoten);
|
||||
kanten = graph.getAusgehendeKanten(restrictToKnoten);
|
||||
|
|
@ -464,15 +485,28 @@ public class GraphPlotter extends PictureViewer {
|
|||
}
|
||||
|
||||
}
|
||||
if(options.showEdgeWeights && graph.isGewichtet()) {
|
||||
if(options.showEdgeWeights) {
|
||||
|
||||
double my = (startY+startY+endY)/3;
|
||||
double mx = (startX+startX+endX)/3;
|
||||
|
||||
p.fill(255);
|
||||
p.stroke(0);
|
||||
p.strokeWeight(1);
|
||||
p.rect((int) mx-15, (int) my-7, 30, 16);
|
||||
p.fill(0);
|
||||
p.text(format(k.getGewicht()), (int) mx, (int) my);
|
||||
|
||||
int lh = g.getFontMetrics().getAscent();
|
||||
List<String> t = k.getKurztext(options.kanteKurztext);
|
||||
if(t.size() == 1) {
|
||||
p.rect((int) mx-15, (int) my-(lh+4)/2, 30, lh+4);
|
||||
p.fill(0);
|
||||
p.text(t.get(0), (int) mx, (int) my);
|
||||
}
|
||||
if(t.size() > 1) {
|
||||
p.rect((int) mx-15, (int) my-(lh+2), 30, lh*2+4);
|
||||
p.fill(0);
|
||||
p.text(t.get(0), (int) mx, (int) my-lh/2);
|
||||
p.text(t.get(1), (int) mx, (int) my+lh/2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -499,7 +533,14 @@ public class GraphPlotter extends PictureViewer {
|
|||
p.text(""+graph.getNummer(k), k.getX(), k.getY());
|
||||
} else {
|
||||
if (options.showVertexValue) {
|
||||
p.text(format(k.getDoubleWert()), k.getX(), k.getY());
|
||||
List<String> t = k.getKurztext(options.knotenKurztext);
|
||||
if(t.size() == 1) {
|
||||
p.text(t.get(0), k.getX(), k.getY());
|
||||
} else {
|
||||
int lh = g.getFontMetrics().getAscent();
|
||||
p.text(t.get(0), k.getX(), k.getY()-lh/2);
|
||||
p.text(t.get(1), k.getX(), k.getY()+lh/2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -511,6 +552,43 @@ public class GraphPlotter extends PictureViewer {
|
|||
}
|
||||
|
||||
}
|
||||
// Tooltip anzeigen, aber nicht wenn im Editiermodus
|
||||
if(!mouseMoving.get() && !editable) {
|
||||
Point2D local = this.getContent().sceneToLocal(mouseLocation.get().getX(), mouseLocation.get().getY());
|
||||
|
||||
int x = (int) local.getX();
|
||||
int y = (int) local.getY();
|
||||
|
||||
// sowohl bei Kante wie auch Knoten
|
||||
GraphElement k = getKnotenAt(x,y);
|
||||
if(k == null) { k = getKanteAt(x,y);}
|
||||
if(k != null) {
|
||||
p.fill(200);
|
||||
p.stroke(0);
|
||||
p.strokeWeight(2);
|
||||
|
||||
List<String> t;
|
||||
if(k instanceof Knoten) t = k.getLangtext(options.knotenLangtext);
|
||||
else t = k.getLangtext(options.kanteLangtext);
|
||||
|
||||
// Größe des Kastens berechnen
|
||||
int w = 0;
|
||||
int lh = g.getFontMetrics().getAscent();
|
||||
int h = t.size() * lh;
|
||||
for(int i = 0; i<t.size(); i++) {
|
||||
int w2 = g.getFontMetrics().stringWidth(t.get(i));
|
||||
if(w2 > w) w = w2;
|
||||
}
|
||||
|
||||
// Rechteck mit Text ausgeben
|
||||
p.rect(x, y, w+16, h+10);
|
||||
p.fill("303030");
|
||||
for(int i = 0; i<t.size(); i++) {
|
||||
p.text(t.get(i), x+8, y+(i+1)*lh+3);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
this.setImage(p, false);
|
||||
Picture zugeschnitten = new Picture(maxx-minx+2*options.vertexSize,maxy-miny+2*options.vertexSize);
|
||||
|
|
@ -518,7 +596,6 @@ public class GraphPlotter extends PictureViewer {
|
|||
return zugeschnitten;
|
||||
}
|
||||
|
||||
|
||||
public GraphOptions getGraphOptions() {
|
||||
return options;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue