Files
VisualSapfor/src/ProjectData/SapforData/Functions/UI/Graph/FunctionsGraphUI.java

264 lines
14 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package ProjectData.SapforData.Functions.UI.Graph;
import Common_old.Current;
import Common_old.UI.UI;
import Common_old.Utils.Utils;
import ProjectData.SapforData.Functions.FuncCoordinates;
import ProjectData.SapforData.Functions.FuncInfo;
import ProjectData.SapforData.Functions.FunctionType;
import Visual_DVM_2021.Passes.All.SPF_GetGraphFunctionPositions;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
import com.mxgraph.model.mxCell;
import com.mxgraph.model.mxGeometry;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxEvent;
import com.mxgraph.util.mxEventObject;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.view.mxGraph;
import com.mxgraph.view.mxStylesheet;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import static com.mxgraph.util.mxConstants.SHAPE_DOUBLE_ELLIPSE;
import static com.mxgraph.util.mxConstants.SHAPE_ELLIPSE;
public class FunctionsGraphUI extends mxGraph {
//--
public final static Timer ffTimer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Pass_2021.passes.get(PassCode_2021.SPF_GetGraphFunctionPositions).Do();
}
});
//---
private static final int default_width = 80;
private static final int default_height = 30;
//форма узлов?
// https://progi.pro/kak-sdelat-parallelogrammnuyu-vershinu-v-jgraphx-13032580
//мануал
//https://jgraph.github.io/mxgraph/docs/manual_javavis.html
//https://jgraph.github.io/mxgraph/java/docs/com/mxgraph/swing/mxGraphComponent.html
//общий манул
//https://jgraph.github.io/mxgraph/docs/manual_javavis.html#1.3
//манул п кликам?
//https://github.com/jgraph/mxgraph/blob/master/java/examples/com/mxgraph/examples/swing/ClickHandler.java
//все образцы
//https://github.com/jgraph/mxgraph/tree/master/java/examples/com/mxgraph/examples/swing
//https://github.com/jgraph/jgraphx/blob/master/src/com/mxgraph/util/mxConstants.java
//про размеры
//https://stackoverflow.com/questions/51619879/mxgraph-how-to-automatically-resize-mxcell-to-content-width-if-it-exceeds-the
//---------------------
//координаты вершин графа
// public LinkedHashMap<String, Pair<Double, Double>> vertexCoordinates = new LinkedHashMap<>();
protected GraphInfo graph = null; //инфа о вершинах и ребрах.
public FunctionsGraphUI(GraphInfo graph_in) {
graph = graph_in;
//настройки графа
setGridEnabled(true);
//setAllowNegativeCoordinates(false);
setAllowDanglingEdges(false); //запрет на висячие ребра.
setCellsEditable(false); //запрет на редактирование клеток
setCellsResizable(false); //запрет изменения размера клеток
setKeepEdgesInBackground(true); // ребра на задний план. очень важно.
setDropEnabled(false);
setAutoSizeCells(true);
setConnectableEdges(false);
setCellsCloneable(false);
//--------------------
mxStylesheet stylesheet = getStylesheet();
Hashtable<String, Object> style = new Hashtable<String, Object>();
style.put(mxConstants.STYLE_SHAPE, SHAPE_ELLIPSE);
style.put(mxConstants.STYLE_FONTCOLOR, "black");
style.put(mxConstants.STYLE_FILLCOLOR, "yellow");
style.put(mxConstants.STYLE_FONTSIZE, "16");
style.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD);
stylesheet.putCellStyle(FunctionType.Default.toString(), style);
//------------------------------------------
style = new Hashtable<String, Object>();
style.put(mxConstants.STYLE_SHAPE, SHAPE_ELLIPSE);
style.put(mxConstants.STYLE_FONTCOLOR, "black");
style.put(mxConstants.STYLE_FILLCOLOR, "lightgreen");
style.put(mxConstants.STYLE_FONTSIZE, "16");
style.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD);
stylesheet.putCellStyle(FunctionType.Main.toString(), style);
//------------------------------------------
style = new Hashtable<String, Object>();
style.put(mxConstants.STYLE_SHAPE, SHAPE_ELLIPSE);
style.put(mxConstants.STYLE_FONTCOLOR, "black");
style.put(mxConstants.STYLE_FILLCOLOR, "lightgray");
style.put(mxConstants.STYLE_FONTSIZE, "16");
style.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD);
// style.put(mxConstants.STYLE_STROKECOLOR, "lawngreen"); это и есть границы.
// style.put(mxConstants.STYLE_STROKEWIDTH, 5);
stylesheet.putCellStyle(FunctionType.Standard.toString(), style);
//------------------------------------------
style = new Hashtable<String, Object>();
style.put(mxConstants.STYLE_SHAPE, SHAPE_ELLIPSE);
style.put(mxConstants.STYLE_FONTCOLOR, "white");
style.put(mxConstants.STYLE_FILLCOLOR, "darkred");
style.put(mxConstants.STYLE_FONTSIZE, "16");
style.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD);
stylesheet.putCellStyle(FunctionType.NotFound.toString(), style);
//------------------------------------------
style = new Hashtable<String, Object>();
style.put(mxConstants.STYLE_SHAPE, SHAPE_DOUBLE_ELLIPSE);
style.put(mxConstants.STYLE_FONTCOLOR, "black");
style.put(mxConstants.STYLE_FILLCOLOR, "lightblue");
style.put(mxConstants.STYLE_FONTSIZE, "16");
style.put(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD);
// style.put(mxConstants.STYLE_STROKECOLOR, "lawngreen"); это и есть границы.
// style.put(mxConstants.STYLE_STROKEWIDTH, 5);
stylesheet.putCellStyle("current", style);
}
//---
// еще один туториал?
// https://www.47.gbmse.ru/resources/utility/mxgraph/docs/tutorial.html
//
//https://github.com/jgraph/mxgraph/tree/master/java/examples/com/mxgraph/examples/swing
//https://jgraph.github.io/mxgraph/java/docs/com/mxgraph/swing/mxGraphComponent.html
//https://www.47.gbmse.ru/resources/utility/mxgraph/docs/tutorial.html#3.2
public mxGraphComponent Draw() {
FuncInfo funcInfo = null;
//установить координаты вершин.
SetCoordinates(); //пустышка.
Object parent = getDefaultParent();
getModel().beginUpdate();
//непосредственное добавление графики
//------------------------------------
//размеры
//https://stackoverflow.com/questions/51619879/mxgraph-how-to-automatically-resize-mxcell-to-content-width-if-it-exceeds-the
// UI.Info("++");
LinkedHashMap<String, Object> mxVertexes = new LinkedHashMap<>();
for (String name : graph.vertexCoordinates.keySet()) {
funcInfo = Current.getProject().allFunctions.get(name);
String vertexType = funcInfo.type.toString();
if (SPF_GetGraphFunctionPositions.showByCurrentFunction) {
FuncInfo current_fi = (FuncInfo) Current.get(Current.Function);
if ((current_fi != null) && (funcInfo.funcName.equals(current_fi.funcName))) {
vertexType = "current";
}
}
mxVertexes.put(name,
insertVertex(parent,
name, //идентификатор вершины. должен быть уникальным.
name, //объект не стоит делать. какие то мутки при перетаскивании объектов.
//строки-ключа уже достаточно
//координаты вершины
graph.vertexCoordinates.get(name).getKey(),
graph.vertexCoordinates.get(name).getValue(),
default_width, default_height,
vertexType
));
}
for (String name : graph.vertexMap.keySet()) {
mxCell cell = (mxCell) mxVertexes.get(name);
mxRectangle preferred = getPreferredSizeForCell(cell);
mxGeometry current = cell.getGeometry();
current.setWidth((preferred.getWidth() > default_width) ? preferred.getWidth() : default_width);
//updateCellSize(cell, true); это если просто везде выставить авторазмер.
//тут же нам нужно применить его только в случае если ширина меньше чем надо.
for (String neigbor : graph.vertexMap.get(name)) {
insertEdge(parent, null,
//надпись над ребром.
"",
//вершина 1
mxVertexes.get(name),
//вершина 2
mxVertexes.get(neigbor));
}
}
//------------------------------------
//https://java.hotexamples.com/examples/com.mxgraph.view/mxGraph/setAutoSizeCells/java-mxgraph-setautosizecells-method-examples.html
groupCells();
getModel().endUpdate();
//------------------------------------
//обертка графа контролом
mxGraphComponent graphComponent = new mxGraphComponent(this);
graphComponent.setZoomFactor(1.10);
//--
// https://programtalk.com/java-more-examples/com.mxgraph.util.mxEvent.UP/
addListener(mxEvent.CELLS_MOVED, new mxIEventListener() {
@Override
public void invoke(Object o, mxEventObject mxEventObject) {
//Сохранение координат графа при сдвиге узла
if (mxEventObject.getProperties().containsKey("cells")) {
Object[] cells = (Object[]) mxEventObject.getProperties().get("cells");
for (Object cell_ : cells) {
if (cell_ instanceof mxCell) {
mxCell cell = (mxCell) cell_;
if (cell.isVertex()) {
String funcName = (String) cell.getValue();
FuncCoordinates coords = null;
// UI.Info(cell.getGeometry().getPoint().toString());
Point point = cell.getGeometry().getPoint();
try {
if (Current.getProject().db.funcCoordinates.containsKey(funcName)) {
coords = Current.getProject().db.funcCoordinates.get(funcName);
coords.name = funcName;
coords.X = point.getX();
coords.Y = point.getY();
Current.getProject().db.Update(coords);
} else {
coords = new FuncCoordinates();
coords.name = funcName;
coords.X = point.getX();
coords.Y = point.getY();
Current.getProject().db.Insert(coords);
}
} catch (Exception ignored) {
}
}
}
}
}
}
});
graphComponent.getGraphControl().setComponentPopupMenu(new FunctionsGraphMenu());
//обработка клика мышом.
graphComponent.getGraphControl().addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
Object cell = graphComponent.getCellAt(e.getX(), e.getY());
if (cell != null) {
mxCell mx_cell = (mxCell) cell;
if (mx_cell.isVertex()) {
String func_name = (String) mx_cell.getValue();
FuncInfo fi = Current.getProject().allFunctions.get(func_name);
switch (e.getClickCount()) {
case 1:
Current.set(Current.SelectedFunction, fi);
break;
case 2:
switch (fi.type) {
case Default:
case Main:
fi.Show(true);
break;
case Standard:
case NotFound:
UI.Info("процедура " + Utils.Brackets(func_name) + " " + fi.type.getDescription());
break;
}
break;
}
}
}
}
});
graphComponent.getViewport().setBackground(Color.WHITE);
return graphComponent;
}
//по умолчанию ничего не меняем.
public void SetCoordinates() {
}
public void SaveCoords() {
}
}