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

509 lines
21 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 Common.Visual;
import Common.CommonConstants;
import Common.Current_;
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;
import Common.MainModule_;
import Common.Utils.TextLog;
import Common.Utils.Utils_;
import Common.Visual.Menus.DataMenuBar;
import Common.Visual.Menus.TableMenu;
import Common.Visual.Tables.*;
import Common.Visual.Tables.Grid.GridAnchestor;
import javax.swing.*;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Comparator;
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<?, D> dataSource; //источник данных
protected DataMenuBar bar = null; //верхняя панель меню
protected int current_row_i; //индекс текущей строки.
protected boolean events_on = true;
protected String colNamesAndSizes = "";
protected Vector<ColumnInfo> columns = new Vector<>(); //информация о столбцах и их оформлении
//-
protected Vector<DBObjectFilter_<D>> allFilters = new Vector<>();
//---
//фильтры и подсчеты. todo слить с баром (?)
MatchesCounter counter_ui = null;
//--
Object savedCurrentKey = null;
Vector<Object> savedSelectedKeys = new Vector<>();
//--
public DataSetControlForm(DataSet<?, D> dataSource_in, JPanel mountPanel_in) {
super(DataTable.class, mountPanel_in);
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);
//--
counter_ui = (count -> bar.countLabel.setText(String.valueOf(count)));
//--фильтры всегда в конец бара.
bar.add(new JSeparator());
for (FilterFlag filter : getFilters(FilterFlag.class)) {
bar.add(filter.getControl());
}
for (JMenu filter : getFilters(DataSetFiltersMenu.class)) {
bar.addMenus(filter);
}
//------------------------
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public String getPluralDescription() {
return "";
}
public String getSingleDescription() {
return "";
}
<M> Vector<M> getFilters(Class<M> f) {
Vector<M> res = new Vector<>();
for (DBObjectFilter_ filter_ : allFilters) {
//либо М, либо наследует от М
if (filter_.getClass().equals(f) || filter_.getClass().getSuperclass().equals(f)) {
res.add((M) filter_);
}
}
return res;
}
public void AddFilter(DBObjectFilter_<D> filter_in) {
allFilters.add(filter_in);
}
public ColumnInfo getColumnInfo(int i) {
return columns.get(i);
}
//--
protected String[] getUIColumnNames() {
return new String[]{};
}
public Object getFieldAt(D object, int coulmnIndex) {
return null;
}
//-
public void SaveColumns() {
if (MainModule_.instance.getDb() != null) {
try {
if (CurrentName() != null) {
String tableName = CurrentName().toString();
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);
} else {
tableVisualData = new TableVisualData(tableName);
MainModule_.instance.getDb().Insert(tableVisualData);
}
tableVisualData.sizes = packed;
MainModule_.instance.getDb().Update(tableVisualData);
}
} 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();
columns.add(new ColumnInfo(dataSource.getPKName()));
if (hasCheckBox()) {
columns.add(new ColumnInfo("", DBObjectSelectionRenderer.class, DBObjectSelector.class));
columns.get(1).setMinWidth(25);
columns.get(1).setMaxWidth(25);
}
Arrays.stream(getUIColumnNames()).forEach(name -> columns.add(new ColumnInfo(name)));
AdditionalInitColumns();
}
protected void AdditionalInitColumns() {
//уточнение инфы по столбцам.
}
protected Comparator getDefaultComparator() {
return null;
}
public boolean isObjectVisible(D object) {
return ApplyFilters(object);
}
Vector<Object> getVisibleKeys() {
Comparator comparator = getDefaultComparator();
Vector<Object> res_keys = new Vector<>();
if (comparator == null) {
for (D object : dataSource.Data.values()) {
if (isObjectVisible(object))
res_keys.add(object.getPK());
}
} else {
Vector<D> raw = new Vector<>();
for (D object : dataSource.Data.values()) {
if (isObjectVisible(object))
raw.add(object);
}
raw.sort(comparator);
for (D object : raw)
res_keys.add(object.getPK());
}
return res_keys;
}
@SuppressWarnings("unchecked")
@Override
protected void createControl() {
CreateColumnsInfo();
GridAnchestor table_data_model = new GridAnchestor(getHeaders(), getVisibleKeys()) {
@SuppressWarnings("unchecked")
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object key = data.get(rowIndex);
if (columnIndex == 0)
return key;
D object = dataSource.get((key));
if ((columnIndex == 1) && hasCheckBox())
return object.isSelected();
return getFieldAt(object, columnIndex);
}
@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);
return dataSource.get(key);
}
//-----------------------------NEW-------------------------------------
@Override
public void CorrectColumnsSizes() {
if ((MainModule_.instance.getDb() != null)
&& CurrentName() != null
&& MainModule_.instance.getDb().tablesVisualData.containsKey(CurrentName().toString())) {
if (!getColumnsProfile().equalsIgnoreCase(colNamesAndSizes)) {
TableVisualData grid = MainModule_.instance.getDb().tablesVisualData.get(CurrentName().toString());
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()));
if (columnInfo.hasEditor())
getColumnModel().getColumn(i).setCellEditor(MainModule_.instance.getUI().getTableEditor(columnInfo.getEditorClass()));
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();
}
}
});
//------------------------->>
}
};
if (CurrentName() != null) {
current_row_i = CommonConstants.Nan;
ListSelectionModel selModel = control.getSelectionModel();
selModel.addListSelectionListener(e -> {
int row = control.getSelectedRow();
if ((row >= 0)) {
if (row != current_row_i) {
current_row_i = row;
MainModule_.instance.set(CurrentName(), control.getRowObject(row));
if (events_on) {
try {
ShowCurrentObject();
} catch (Exception ex) {
Utils_.MainLog.PrintException(ex);
}
}
}
} else {
current_row_i = CommonConstants.Nan;
dropCurrent();
if (events_on) {
try {
ShowNoCurrentObject();
} catch (Exception ex) {
Utils_.MainLog.PrintException(ex);
}
}
}
});
//двойной клик мыши.------------------------------------------------------
control.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if ((e.getClickCount() == 2) && (getCurrent() != null)) {
try {
MouseAction2();
} catch (Exception ex) {
Utils_.MainLog.PrintException(ex);
}
}
}
});
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;
}
}
}
);
//----------------------------------------------------------------------------
//при переотображении таблицы скидываем текущий объект!!
dropCurrent();
try {
ShowNoCurrentObject();
} catch (Exception e) {
Utils_.MainLog.PrintException(e);
}
}
for (HeaderTextFilter filter : getFilters(HeaderTextFilter.class))
filter.Mount(getControl());
}
protected DataMenuBar createMenuBar() {
return new DataMenuBar(getPluralDescription());
}
protected void createFilters() {
}
protected boolean ApplyFilters(D object) {
for (DBObjectFilter_ filterInterface : allFilters) {
if (!filterInterface.Validate(object))
return false;
}
return true;
}
@Override
protected void redrawControl() {
control.CorrectSizes();
}
@Override
public void Show() {
for (DBObjectFilter_ filter_ : allFilters) filter_.DropMatchesCount();
super.Show();
if (counter_ui != null) counter_ui.ShowMatchesCount(getRowCount());
for (DBObjectFilter_ filter_ : allFilters) filter_.ShowMatchesCount();
}
public void Show(Object pk) {
Show();
SetCurrentByPK(pk);
}
public void SetCurrentByPK(Object pk) {
if (isShown())
control.SelectRowByPK(pk);
}
public void ClearSelection() {
if (isShown()) control.clearSelection(); //строка сбросится сама. благодаря сбросу события выбора
}
public void SelectAll(boolean flag) {
for (D object : dataSource.Data.values()) {
if (isObjectVisible(object))
object.Select(flag);
}
Refresh();
}
@Override
public void Clear() {
super.Clear();
if (counter_ui != null) counter_ui.ShowNoMatches();
}
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();
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();
break;
case PASSIVE:
break;
}
}
}
}
public void MouseAction2() throws Exception {
}
//-
public boolean hasCheckBox() {
return false;
}
public boolean hasMenuBar() {
return true;
}
//-found
public void SaveLastCurrent() {
savedCurrentKey = null;
savedSelectedKeys.clear();
if ((CurrentName() != null) && (getCurrent() != null)) {
savedCurrentKey = getCurrent().getPK();
}
savedSelectedKeys = 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);
}
}
public int getSelectedCount() {
return (int) dataSource.Data.values().stream().filter(d -> isObjectVisible(d) && d.isSelected()).count();
}
public Vector<D> getSelectedItems() {
return dataSource.Data.values().stream().filter(d -> isObjectVisible(d) && d.isSelected()).collect(Collectors.toCollection(Vector::new));
}
public Vector<Object> getSelectedKeys() {
return dataSource.Data.values().stream().filter(DBObject::isSelected).map(d -> d.getPK()).collect(Collectors.toCollection(Vector::new));
}
//--
public Current_ CurrentName() {
return null;
}
public boolean CheckCurrent(TextLog log) {
return MainModule_.instance.Check(log, CurrentName());
}
public boolean CheckSelectedOrCurrent(TextLog log) {
if ((getSelectedCount() == 0) && (CurrentName() == null || (getCurrent() == null))) {
log.Writeln_(getPluralDescription() + ":");
log.Writeln_("Отсутствуют отмеченные объекты, или текущий объект!");
return false;
}
return true;
}
public void dropCurrent() {
MainModule_.instance.set(CurrentName(), null);
}
public D getCurrent() {
return (D) MainModule_.instance.get(CurrentName());
}
public Vector<D> getSelectedOrCurrent() {
Vector<D> res = new Vector<>();
if (getSelectedCount() > 0)
res = getSelectedItems();
else {
if ((CurrentName() != null) && (getCurrent() != null)) {
res.add(getCurrent());
}
}
return res;
}
public Vector<Object> getSelectedOrCurrentKeys() {
Vector<Object> res = new Vector<>();
if (getSelectedCount() > 0)
res = getSelectedKeys();
else {
if ((CurrentName() != null) && (getCurrent() != null)) {
res.add(getCurrent().getPK());
}
}
return res;
}
}