Files
VisualSapfor/src/Common/Visual/DataSetControlForm.java

435 lines
19 KiB
Java
Raw Normal View History

package Common.Visual;
2024-10-07 14:22:52 +03:00
import Common.CommonConstants;
import Common.Database.Objects.DBObject;
import Common.Database.Objects.Grid.TableVisualData;
import Common.Database.Tables.DBTable;
import Common.Database.Tables.DataSet;
import Common.Database.Tables.FKBehaviour;
2024-10-15 13:35:33 +03:00
import Common.MainModule_;
2024-10-14 15:19:13 +03:00
import Common.Utils.Utils_;
import Common.Visual.Menus.DataMenuBar;
2024-10-09 20:35:18 +03:00
import Common.Visual.Menus.TableMenu;
2024-10-17 22:18:10 +03:00
import Common.Visual.Tables.*;
2024-10-09 20:35:18 +03:00
import Common.Visual.Tables.Grid.GridAnchestor;
2023-09-17 22:13:42 +03:00
import javax.swing.*;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
2023-09-17 22:13:42 +03:00
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
2024-10-20 16:19:43 +03:00
import java.util.Comparator;
2024-10-17 22:18:10 +03:00
import java.util.LinkedHashMap;
2023-09-17 22:13:42 +03:00
import java.util.Vector;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class DataSetControlForm<D extends DBObject> extends ControlForm<DataTable> {
protected DataSet dataSource; //источник данных
protected DataMenuBar bar = null; //верхняя панель меню
protected int current_row_i; //индекс текущей строки.
2023-09-17 22:13:42 +03:00
protected boolean events_on = true;
protected String colNamesAndSizes = "";
protected Vector<ColumnInfo> columns = new Vector<>(); //информация о столбцах и их оформлении
2024-10-17 22:18:10 +03:00
protected Vector<DataSetFiltersMenu> filtersMenus = new Vector<>();
protected LinkedHashMap<Integer, HeaderTextFilter> headersTextFilters = new LinkedHashMap<>(); //текстовые фильтры столбцов
//фильтры и подсчеты. todo слить с баром (?)
MatchesCounter f_ui = null;
//--
Object savedCurrentKey = null;
Vector<Object> savedSelectedKeys = new Vector<>();
//--
2024-10-20 17:44:30 +03:00
public DataSetControlForm(DataSet<?, D> dataSource_in, JPanel mountPanel_in) {
super(DataTable.class, mountPanel_in);
2023-09-17 22:13:42 +03:00
dataSource = dataSource_in;
createFilters();
if (hasMenuBar()) {
try {
if (!MainModule_.instance.getUI().menuBars.containsKey(dataSource.getClass())) {
bar = createMenuBar();
if (hasCheckBox())
bar.createSelectionButtons(dataSource);
MainModule_.instance.getUI().menuBars.put(dataSource.getClass(), bar);
} else {
bar = MainModule_.instance.getUI().menuBars.get(dataSource.getClass());
}
mountPanel.add(bar, BorderLayout.NORTH);
//--
f_ui = (count -> bar.countLabel.setText(String.valueOf(count)));
//--
2024-10-17 22:18:10 +03:00
if (!filtersMenus.isEmpty()) {
for (DataSetFiltersMenu filter : filtersMenus)
bar.addMenus(filter.getMenu());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
2023-09-17 22:13:42 +03:00
}
2024-10-20 17:44:30 +03:00
public ColumnInfo getColumnInfo(int i) {
return columns.get(i);
}
2024-10-17 22:18:10 +03:00
protected String[] getUIColumnNames() {
return new String[]{};
}
2023-09-17 22:13:42 +03:00
public void SaveColumns() {
if (MainModule_.instance.getDb() != null) {
2023-09-17 22:13:42 +03:00
try {
2024-10-17 17:37:59 +03:00
if (dataSource.CurrentName() != null) {
String tableName = dataSource.CurrentName().toString();
2023-09-17 22:13:42 +03:00
Vector<String> widths = IntStream.range(0, columns.size()).mapToObj(i -> String.valueOf(control.getColumnModel().getColumn(i).getWidth())).collect(Collectors.toCollection(Vector::new));
String packed = String.join("|", widths);
TableVisualData tableVisualData;
if (MainModule_.instance.getDb().tablesVisualData.containsKey(tableName)) {
tableVisualData = MainModule_.instance.getDb().tablesVisualData.get(tableName);
2023-09-17 22:13:42 +03:00
} else {
tableVisualData = new TableVisualData(tableName);
MainModule_.instance.getDb().Insert(tableVisualData);
2023-09-17 22:13:42 +03:00
}
tableVisualData.sizes = packed;
MainModule_.instance.getDb().Update(tableVisualData);
2023-09-17 22:13:42 +03:00
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
private Vector<String> getHeaders() {
return columns.stream().map(ColumnInfo::getName).collect(Collectors.toCollection(Vector::new));
}
protected void CreateColumnsInfo() {
columns.clear();
2024-10-17 17:37:59 +03:00
columns.add(new ColumnInfo(dataSource.getPKName()));
2023-09-17 22:13:42 +03:00
if (hasCheckBox()) {
columns.add(new ColumnInfo("", DBObjectSelectionRenderer.class, DBObjectSelector.class));
2023-09-17 22:13:42 +03:00
columns.get(1).setMinWidth(25);
columns.get(1).setMaxWidth(25);
}
2024-10-17 22:09:18 +03:00
Arrays.stream(getUIColumnNames()).forEach(name -> columns.add(new ColumnInfo(name)));
2023-09-17 22:13:42 +03:00
AdditionalInitColumns();
}
protected void AdditionalInitColumns() {
//уточнение инфы по столбцам.
}
2024-10-20 16:19:43 +03:00
Vector<Object> getVisibleKeys() {
Comparator comparator = dataSource.getComparator();
Vector<Object> res = new Vector<>();
if (comparator == null) {
for (Object key : dataSource.Data.keySet())
if (dataSource.get(key).isVisible())
res.add(key);
} else {
Vector<Object> raw = new Vector<>();
for (Object object : dataSource.Data.values()) {
2024-10-20 17:44:30 +03:00
if (((DBObject) object).isVisible())
2024-10-20 16:19:43 +03:00
raw.add(object);
}
raw.sort(comparator);
for (Object object : raw)
2024-10-20 17:44:30 +03:00
res.add(((DBObject) object).getPK());
2024-10-20 16:19:43 +03:00
}
return res;
}
2023-09-17 22:13:42 +03:00
@SuppressWarnings("unchecked")
@Override
protected void createControl() {
2023-09-17 22:13:42 +03:00
CreateColumnsInfo();
2024-10-20 16:19:43 +03:00
GridAnchestor table_data_model = new GridAnchestor(getHeaders(), getVisibleKeys()) {
2023-09-17 22:13:42 +03:00
@SuppressWarnings("unchecked")
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object key = data.get(rowIndex);
if (columnIndex == 0)
return key;
2024-10-17 17:37:59 +03:00
DBObject object = dataSource.get((key));
2023-09-17 22:13:42 +03:00
if ((columnIndex == 1) && hasCheckBox())
return object.isSelected();
return object.getFieldAt(columnIndex); //dataSource.getFieldAt(object, columnIndex);
2023-09-17 22:13:42 +03:00
}
@Override
public boolean isCellEditable(int row, int col) {
return columns.get(col).isEditable();
}
//------------------------------------------------------------------------------------
@Override
public void setValueAt(Object value, int row, int col) {
fireTableCellUpdated(row, col);
}
};
control = new DataTable(table_data_model) {
@Override
public TableMenu CreateMenu() {
return new TableMenu(this);
}
//строго говоря эта штука нужна только для рендереров и едиторов клеток.
@Override
public DBObject getRowObject(int rowIndex) {
//вот так делать НЕЛЬЗЯ. модель только для внутреннего пользования
// Object key = table_data_model.data.get(rowIndex);
//из таблицы можно пользоваться только getValueAt
//иначе сортировка не будет работать.
Object key = getValueAt(rowIndex, 0);
2024-10-17 17:37:59 +03:00
return dataSource.get(key);
2023-09-17 22:13:42 +03:00
}
//-----------------------------NEW-------------------------------------
@Override
public void CorrectColumnsSizes() {
if ((MainModule_.instance.getDb() != null)
2024-10-17 17:37:59 +03:00
&& dataSource.CurrentName() != null
&& MainModule_.instance.getDb().tablesVisualData.containsKey(dataSource.CurrentName().toString())) {
2023-09-17 22:13:42 +03:00
if (!getColumnsProfile().equalsIgnoreCase(colNamesAndSizes)) {
2024-10-17 17:37:59 +03:00
TableVisualData grid = MainModule_.instance.getDb().tablesVisualData.get(dataSource.CurrentName().toString());
2023-09-17 22:13:42 +03:00
String[] data = grid.sizes.split("\\|");
for (int i = 0; i < columns.size(); ++i) {
if (i <= (data.length - 1)) {
int width = Integer.parseInt(data[i]);
getColumnModel().getColumn(i).setPreferredWidth(width);
getColumnModel().getColumn(i).setWidth(width);
}
}
}
} else
super.CorrectColumnsSizes(); //обычный авторазмер.
}
public String getColumnsProfile() {
String res = "";
for (int i = 0; i < getColumnModel().getColumnCount(); i++) {
if (i > 0) res += ",";
TableColumn column = getColumnModel().getColumn(i);
res += column.getHeaderValue();
res += ":";
res += column.getWidth();
}
return res;
}
@Override
public void Init() {
for (int i = 0; i < columns.size(); i++) {
ColumnInfo columnInfo = columns.get(i);
if (columnInfo.isVisible()) {
if (columnInfo.hasRenderer())
getColumnModel().getColumn(i).setCellRenderer(MainModule_.instance.getUI().getTableRenderer(columnInfo.getRendererClass()));
2023-09-17 22:13:42 +03:00
if (columnInfo.hasEditor())
getColumnModel().getColumn(i).setCellEditor(MainModule_.instance.getUI().getTableEditor(columnInfo.getEditorClass()));
2023-09-17 22:13:42 +03:00
if (columnInfo.hasMaxWidth())
getColumnModel().getColumn((i)).setMaxWidth(columnInfo.getMaxWidth());
if (columnInfo.hasMinWidth())
getColumnModel().getColumn((i)).setMinWidth(columnInfo.getMinWidth());
} else {
getColumnModel().getColumn(i).setMinWidth(0);
getColumnModel().getColumn(i).setMaxWidth(0);
}
}
//обновление в БД при ручном изменении размера столбиков.--------->>
getTableHeader().addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent arg0) {
String new_colNamesAndSizes = getColumnsProfile();
// check if changed, if yes, persist...
if (!colNamesAndSizes.equals(new_colNamesAndSizes)) {
colNamesAndSizes = new_colNamesAndSizes;
SaveColumns();
}
}
});
//------------------------->>
}
};
2024-10-17 17:37:59 +03:00
if (dataSource.CurrentName() != null) {
2024-10-07 14:22:52 +03:00
current_row_i = CommonConstants.Nan;
2023-09-17 22:13:42 +03:00
ListSelectionModel selModel = control.getSelectionModel();
selModel.addListSelectionListener(e -> {
int row = control.getSelectedRow();
if ((row >= 0)) {
if (row != current_row_i) {
current_row_i = row;
2024-10-17 17:37:59 +03:00
dataSource.setCurrent(control.getRowObject(row));
2023-09-17 22:13:42 +03:00
if (events_on) {
try {
ShowCurrentObject();
} catch (Exception ex) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(ex);
2023-09-17 22:13:42 +03:00
}
}
}
} else {
2024-10-07 14:22:52 +03:00
current_row_i = CommonConstants.Nan;
2024-10-17 17:37:59 +03:00
dataSource.dropCurrent();
2023-09-17 22:13:42 +03:00
if (events_on) {
try {
ShowNoCurrentObject();
} catch (Exception ex) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(ex);
2023-09-17 22:13:42 +03:00
}
}
}
});
//двойной клик мыши.------------------------------------------------------
control.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if ((e.getClickCount() == 2) && (dataSource.getCurrent() != null)) {
try {
MouseAction2();
} catch (Exception ex) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(ex);
2023-09-17 22:13:42 +03:00
}
}
}
});
control.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_DELETE:
if (dataSource.getDeletePassCode() != null) {
MainModule_.instance.getPass(dataSource.getDeletePassCode()).Do();
}
break;
case KeyEvent.VK_ENTER:
try {
MouseAction2();
} catch (Exception ex) {
Utils_.MainLog.PrintException(ex);
}
break;
}
}
}
);
2023-09-17 22:13:42 +03:00
//----------------------------------------------------------------------------
//при переотображении таблицы скидываем текущий объект!!
2024-10-17 17:37:59 +03:00
dataSource.dropCurrent();
2023-09-17 22:13:42 +03:00
try {
ShowNoCurrentObject();
} catch (Exception e) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(e);
2023-09-17 22:13:42 +03:00
}
}
for (HeaderTextFilter filter : headersTextFilters.values()) {
filter.Mount(getControl());
}
2023-09-17 22:13:42 +03:00
}
protected DataMenuBar createMenuBar() {
return new DataMenuBar(dataSource.getPluralDescription());
}
2024-10-17 22:18:10 +03:00
protected void createFilters() {
}
protected boolean applyFiltersMenus(DBObject object) {
for (DataSetFiltersMenu filterMenu : filtersMenus) {
if (!filterMenu.Validate(object))
return false;
}
return true;
}
public boolean ApplyFilters(DBObject object) {
2024-10-17 22:18:10 +03:00
//могут быть и другие фильтры ( например свои/активные). перенести их сюда и обобщить
return applyFiltersMenus(object);
}
/*
//todo упразднить.
2024-10-17 22:41:43 +03:00
// применить значение фильтра к фильру объекта напирмер Message.filterValue = text;
public void changeHeaderFilterValue(int columnIndex, String text) {
}
public Object getHeaderFilterValue(int columnIndex) {
return "";
}
*/
2023-09-17 22:13:42 +03:00
@Override
protected void redrawControl() {
2023-09-17 22:13:42 +03:00
control.CorrectSizes();
}
@Override
public void Show() {
2024-10-17 22:18:10 +03:00
for (DataSetFiltersMenu filterMenu : filtersMenus) filterMenu.Drop();
super.Show();
if (f_ui != null) f_ui.ShowMatchesCount(getRowCount());
2024-10-17 22:18:10 +03:00
for (DataSetFiltersMenu filterMenu : filtersMenus) filterMenu.Refresh();
}
2023-09-17 22:13:42 +03:00
public void Show(Object pk) {
Show();
SetCurrentByPK(pk);
2023-09-17 22:13:42 +03:00
}
public void SetCurrentByPK(Object pk) {
2023-09-17 22:13:42 +03:00
if (isShown())
control.SelectRowByPK(pk);
}
public void ClearSelection() {
if (isShown()) control.clearSelection(); //строка сбросится сама. благодаря сбросу события выбора
}
@Override
public void Clear() {
super.Clear();
if (f_ui != null) f_ui.ShowNoMatches();
2023-09-17 22:13:42 +03:00
}
public int getRowCount() {
return control.getRowCount();
}
public void ShowCurrentObject() throws Exception {
if (dataSource instanceof DBTable) {
DBTable table = (DBTable) dataSource;
for (Class dep : table.getFKDependencies().keySet()) {
FKBehaviour behaviour = table.getFKDependencies().get(dep);
switch (behaviour.ui) {
case ACTIVE:
table.getDb().getTable(dep).ShowUI();
2023-09-17 22:13:42 +03:00
break;
case PASSIVE:
break;
}
}
}
}
public void ShowNoCurrentObject() throws Exception {
if (dataSource instanceof DBTable) {
DBTable table = (DBTable) dataSource;
for (Class dep : table.getFKDependencies().keySet()) {
FKBehaviour behaviour = table.getFKDependencies().get(dep);
switch (behaviour.ui) {
case ACTIVE:
table.getDb().getTable(dep).ClearUI();
2023-09-17 22:13:42 +03:00
break;
case PASSIVE:
break;
}
}
}
}
public void MouseAction2() throws Exception {
}
//-
public boolean hasCheckBox() {
return false;
}
public boolean hasMenuBar() {
return true;
}
//-
public void SaveLastCurrent() {
savedCurrentKey = null;
savedSelectedKeys.clear();
if ((dataSource.CurrentName() != null) && (dataSource.getCurrent() != null)) {
savedCurrentKey = dataSource.getCurrent().getPK();
}
savedSelectedKeys = dataSource.getSelectedKeys();
}
public void RestoreLastCurrent() {
for (Object key : savedSelectedKeys) {
if (dataSource.containsKey(key))
dataSource.get(key).Select(true);
}
if ((savedCurrentKey != null) && (dataSource.containsKey(savedCurrentKey))) {
SetCurrentByPK(savedCurrentKey);
}
}
/*
List<RowSorter.SortKey> sortKeys = new ArrayList<>();
for (int i = 0; i < 6; ++i)
sorter.setSortable(i, false);
sortKeys.add(new RowSorter.SortKey(6, SortOrder.DESCENDING));
sortKeys.add(new RowSorter.SortKey(7, SortOrder.DESCENDING));
// sorter.setSortKeys(sortKeys);
// sorter.sort();
*/
2023-09-17 22:13:42 +03:00
}