Files
VisualSapfor/src/_VisualDVM/Visual/Windows/ComparisonForm.java
02090095 b37e20e4a4 ++
решение проблемы совместимости с java 1.8._4xx
2025-04-21 15:27:20 +03:00

374 lines
13 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 _VisualDVM.Visual.Windows;
import Common.CommonConstants;
import Common.Database.Objects.DBObject;
import Common.Passes.Pass;
import Common.Utils.Pair;
import Common.Utils.Utils_;
import Common.Visual.Controls.ShortLabel;
import Common.Visual.Editor.BaseEditor;
import Common.Visual.Menus.VisualiserMenuBar;
import Common.Visual.UI;
import _VisualDVM.ProjectData.Files.UI.Editor.SPFEditor;
import _VisualDVM.Utils;
import com.github.difflib.text.DiffRow;
import com.github.difflib.text.DiffRowGenerator;
import org.fife.ui.rtextarea.RTextScrollPane;
import javax.swing.*;
import javax.swing.text.Highlighter;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Vector;
public abstract class ComparisonForm<T> {
final String separator = "\u200B";
final char cseparator = '\u200B';
public Class<T> t; //класс объектов.
//-->>
public Vector<String> lines = new Vector<>(); //строки с учетом/неучетом пробелов. для сравнения
public Vector<String> visible_lines = new Vector<>(); //строки с нетронутыми пробелами. для отображения
protected JToolBar tools;
protected JLabel lObjectName;
protected JButton bApplyObject;
protected JButton bClose;
//-->>
protected T object = null;
//-->>
protected BaseEditor Body;
//невидимый пробел https://translated.turbopages.org/proxy_u/en-ru.ru.898e1daf-67e318c0-3fccff8a-74722d776562/https/stackoverflow.com/questions/17978720/invisible-characters-ascii
//--->>
// protected Object ownScrollModel = null;
protected Vector<Pair<Integer, Integer>> diffs = new Vector<>();
//-->>
ComparisonForm<T> this_ = null; //?
ComparisonForm<T> slave = null;
ComparisonForm<T> master = null;
//-->>
private JPanel content;
private JPanel editorPanel;
private JButton bCompare;
private JButton bPrevious;
private JButton bNext;
private RTextScrollPane Scroll;
//-----
private boolean events_on = false;//относится только к мастеру, отвечает за скроллы.
private int current_diff_num = -1;
public ComparisonForm(Class<T> t_in, ComparisonForm<T> slave_in) {
//-
Body = new BaseEditor();
Scroll = new RTextScrollPane(Body);
editorPanel.add(Scroll);
// ownScrollModel = Scroll.getVerticalScrollBar().getModel();
//-
t = t_in;
this_ = this;
slave = slave_in;
Scroll.setLineNumbersEnabled(true);
bApplyObject.addActionListener(e -> {
ApplyObject();
});
//--->>>
Body.setWhitespaceVisible(true);
Body.setEditable(false);
if (isMaster()) {
//<editor-fold desc="синхронизация скроллов">
slave.Scroll.getVerticalScrollBar().setModel(Scroll.getVerticalScrollBar().getModel());
//бяк быть не должно при условии что строк одинаковое количество. а это должно выполняться.
Body.addCaretListener(e -> {
if (events_on && isReady() && slave.isReady()) {
try {
int master_lineNum = Body.getCaretLineNumber();
slave.Body.setCaretPosition(slave.Body.getLineStartOffset(master_lineNum));
} catch (Exception ex) {
Utils_.MainLog.PrintException(ex);
}
}
});
//</editor-fold>
slave.master = this;
bCompare.addActionListener(e -> {
DoComparePass(isReady() && slave.isReady());
});
} else {
//рабу сравнивать не положено.
bCompare.setVisible(false);
}
//--->>>
bClose.addActionListener(e -> {
onClose();
});
bPrevious.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (current_diff_num != CommonConstants.Nan) {
if (current_diff_num > 0)
current_diff_num--;
else
current_diff_num = diffs.size() - 1;
ShowCurrentDiff();
}
}
});
bNext.addActionListener(e -> {
if (current_diff_num != CommonConstants.Nan) {
if (current_diff_num < diffs.size() - 1)
current_diff_num++;
else
current_diff_num = 0;
ShowCurrentDiff();
}
});
}
//---<<
private void ShowCurrentDiff() {
try {
int diff_line = Body.getLineOfOffset(diffs.get(current_diff_num).getKey());
Body.gotoLine_(diff_line);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public JPanel getContent() {
return content;
}
//--->>
public boolean isMaster() {
return slave != null;
}
public boolean isSlave() {
return master != null;
}
//--->>
//неперегружаемые методы
protected void RemoveObject() {
object = null;
removeObject();
showNoObject();
ClearText();
}
public abstract Object getDefaultCurrentObject();
public void ApplyObject() {
if (getDefaultCurrentObject() != null)
ApplyObject(getDefaultCurrentObject());
else UI.Info("Текущий объект для сравнения не назначен!");
}
public void ApplyObject(Object object_in) {
RemoveObject();
object = (T) object_in;
applyObject();
showObject();
}
private void getLines() {
lines.clear();
visible_lines.clear();
//--
Pair<Vector<String>, Vector<String>> p = Utils.getFortranLines(getText());
lines = p.getKey();
visible_lines = p.getValue();
}
protected void ClearText() {
events_on = false;
Body.setText("объект не назначен");
}
//предполагаем что оба объекта есть и мы можем получить с них текст.
protected void Compare() throws Exception {
events_on = false;
current_diff_num = CommonConstants.Nan;
slave.current_diff_num = CommonConstants.Nan;
//-----------------------------------------------------------------------------------------------
Body.setText("");
slave.Body.setText("");
Body.getHighlighter().removeAllHighlights();
slave.Body.getHighlighter().removeAllHighlights();
getLines();
slave.getLines();
//--------------------------------------------------------------------
Vector<String> t1 = new Vector<>();
Vector<String> t2 = new Vector<>();
//------
DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true)
.inlineDiffByWord(true)
.ignoreWhiteSpaces(true)
.oldTag(f -> separator)
.newTag(f -> separator)
.build();
List<DiffRow> rows = generator.generateDiffRows(
visible_lines,
slave.visible_lines);
for (DiffRow row : rows) {
t1.add(row.getOldLine());
t2.add(row.getNewLine());
}
Body.setText(String.join("\n", t1));
slave.Body.setText(String.join("\n", t2));
Body.setCaretPosition(0);
slave.Body.setCaretPosition(0);
//--
fillDiffs();
slave.fillDiffs();
colorDiffs();
slave.colorDiffs();
events_on = true;
}
public void fillDiffs() {
diffs.clear();
boolean flag = false;
char[] chars = Body.getText().toCharArray();
int dif_start = CommonConstants.Nan;
int dif_end = CommonConstants.Nan;
for (int i = 0; i < chars.length; ++i) {
char c = chars[i];
//--
if (flag) {
//различие
switch (c) {
case cseparator:
//кончилось различие
dif_end = i;
flag = false;
diffs.add(new Pair<>(dif_start, dif_end));
dif_start = CommonConstants.Nan;
dif_end = CommonConstants.Nan;
break;
}
} else {
//поиск
switch (c) {
case cseparator:
//началось различие
dif_start = i;
flag = true;
break;
default:
break;
}
}
}
if (!diffs.isEmpty())
current_diff_num = 0;
}
public void colorDiffs() throws Exception {
Highlighter.HighlightPainter painter = isMaster() ? SPFEditor.RedTextPainter : SPFEditor.GreenTextPainter;
for (Pair<Integer, Integer> diff : diffs) {
Body.getHighlighter().addHighlight(diff.getKey(), diff.getValue(), painter);
}
}
public void Show() throws Exception {
events_on = false;
current_diff_num = CommonConstants.Nan;
slave.current_diff_num = CommonConstants.Nan;
//----------------------------------------------------------------------------------------------
Body.setText("");
slave.Body.setText("");
Body.getHighlighter().removeAllHighlights();
slave.Body.getHighlighter().removeAllHighlights();
int d = 0;
getLines();
slave.getLines();
//--------------------------------------------------------------------
Vector<String> t1 = new Vector<>();
Vector<String> t2 = new Vector<>();
//------
t1.addAll(visible_lines);
t2.addAll(slave.visible_lines);
//просто выясняем кто из них длиннее, и короткий дополняем пустыми строками.]
int delta = Math.abs(t1.size() - t2.size());
if (lines.size() > slave.lines.size()) {
Utils.addEmptyLines(t2, delta);
} else if (lines.size() < slave.lines.size()) {
Utils.addEmptyLines(t1, delta);
}
///----------------
Body.setText(String.join("\n", t1));
slave.Body.setText(String.join("\n", t2));
Body.setCaretPosition(0);
slave.Body.setCaretPosition(0);
events_on = true;
}
//Перегружаемые методы.
//--->>
protected void showNoObject() {
lObjectName.setText("?");
lObjectName.setToolTipText("Объект не назначен.");
}
protected void showObject() {
if (object instanceof DBObject) {
DBObject dbObject = (DBObject) object;
lObjectName.setText(dbObject.toString());
lObjectName.setToolTipText(dbObject.toString());
}
}
protected void removeObject() {
}
protected void applyObject() {
}
protected abstract String getText();
protected boolean fortranWrapsOn() {
return false;
}
//-->>
private void createUIComponents() {
// TODO: place custom component creation code here
lObjectName = new ShortLabel(40);
tools = new VisualiserMenuBar();
}
//для сравнения по кнопке.
public boolean isReady() {
return object != null;
}
public void onClose() {
RemoveObject();
}
public void DoComparePass(boolean startCondition) {
Pass pass = new Pass() {
@Override
public String getDescription() {
return "Сравнение";
}
@Override
protected boolean needsAnimation() {
return true;
}
@Override
public boolean needsConfirmations() {
return false;
}
@Override
protected boolean canStart(Object... args) throws Exception {
return startCondition;
}
@Override
protected void body() throws Exception {
Compare();
}
};
pass.Do();
}
public void DoShowPass(boolean startCondition) {
Pass pass = new Pass() {
@Override
public String getDescription() {
return "Отображение";
}
@Override
protected boolean needsAnimation() {
return false;
}
@Override
public boolean needsConfirmations() {
return false;
}
@Override
protected boolean canStart(Object... args) throws Exception {
return startCondition;
}
@Override
protected void body() throws Exception {
Show();
}
};
pass.Do();
}
}