package Common.UI; import Common.Constants.Constants; import Common.Current; import Common.Database.DBObject; import Common.Database.DBTable; import Common.Database.DataSet; import Common.Database.FKBehaviour; import Common.Global; import Common.UI.Menus.TableMenu; import Common.UI.Tables.ColumnInfo; import Common.UI.Tables.DataTable; import Common.UI.Tables.Grid.GridAnchestor; import GlobalData.Grid.Grid; import javax.swing.*; import javax.swing.table.TableColumn; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Arrays; import java.util.Vector; import java.util.stream.Collectors; import java.util.stream.IntStream; import static Common.UI.Tables.TableEditors.EditorSelect; import static Common.UI.Tables.TableRenderers.RendererSelect; public class DataSetControlForm extends ControlWithCurrentForm { protected JPanel dataPanel; protected DataSet dataSource; public JPanel getDataPanel() { return dataPanel; } protected int current_row_i; protected boolean events_on = true; protected String colNamesAndSizes = ""; protected Vector columns = new Vector<>(); public DataSetControlForm(DataSet dataSource_in) { this(dataSource_in, DataTable.class); } public DataSetControlForm(DataSet dataSource_in, Class tableClass) { super(tableClass); dataSource = dataSource_in; //--- dataPanel = new JPanel(new BorderLayout()); content.add(dataPanel, BorderLayout.CENTER); } @Override public void Show() { super.Show(); dataPanel.add(scroll); dataPanel.updateUI(); } @Override public void Clear() { super.Clear(); UI.Clear(dataPanel); } public DataSet getDataSource() { return dataSource; } @Override public Current CurrentName() { return getDataSource().CurrentName(); } public void SaveColumns() { if (Global.db != null) { try { if ((CurrentName() != Current.Undefined)) { Vector 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); Grid grid; if (Global.db.grids.containsKey(CurrentName())) { grid = Global.db.grids.get(CurrentName()); } else { grid = new Grid(CurrentName()); Global.db.Insert(grid); } grid.sizes = packed; Global.db.Update(grid); } } catch (Exception ex) { ex.printStackTrace(); } } } public boolean hasCheckBox() { return false; } private Vector getHeaders() { return columns.stream().map(ColumnInfo::getName).collect(Collectors.toCollection(Vector::new)); } protected void CreateColumnsInfo() { columns.clear(); columns.add(new ColumnInfo(getDataSource().getPKName())); if (hasCheckBox()) { columns.add(new ColumnInfo("", RendererSelect, EditorSelect)); columns.get(1).setMinWidth(25); columns.get(1).setMaxWidth(25); } Arrays.stream(getDataSource().getUIColumnNames()).forEach(name -> columns.add(new ColumnInfo(name))); AdditionalInitColumns(); } protected void AdditionalInitColumns() { //уточнение инфы по столбцам. } @SuppressWarnings("unchecked") @Override public void CreateControl() { CreateColumnsInfo(); GridAnchestor table_data_model = new GridAnchestor(getHeaders(), dataSource.getVisibleKeys()) { @SuppressWarnings("unchecked") @Override public Object getValueAt(int rowIndex, int columnIndex) { Object key = data.get(rowIndex); if (columnIndex == 0) return key; DBObject object = getDataSource().get((key)); if ((columnIndex == 1) && hasCheckBox()) return object.isSelected(); return getDataSource().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 getDataSource().get(key); } //-----------------------------NEW------------------------------------- @Override public void CorrectColumnsSizes() { if ((Global.db != null) && CurrentName() != Current.Undefined && Global.db.grids.containsKey(CurrentName())) { //Undefined может оказаться в таблице, например если енум устарел. Поэтому надо проверять. if (!getColumnsProfile().equalsIgnoreCase(colNamesAndSizes)) { Grid grid = Global.db.grids.get(CurrentName()); 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(UI.TableRenderers.get(columnInfo.getRenderer())); if (columnInfo.hasEditor()) getColumnModel().getColumn(i).setCellEditor(UI.TableEditors.get(columnInfo.getEditor())); 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) { System.out.println("Header mouse released"); String new_colNamesAndSizes = getColumnsProfile(); // check if changed, if yes, persist... if (!colNamesAndSizes.equals(new_colNamesAndSizes)) { colNamesAndSizes = new_colNamesAndSizes; SaveColumns(); System.out.println("columns updated"); } } }); //------------------------->> } }; if (CurrentName() != Current.Undefined) { current_row_i = Constants.Nan; ListSelectionModel selModel = control.getSelectionModel(); selModel.addListSelectionListener(e -> { int row = control.getSelectedRow(); if ((row >= 0)) { if (row != current_row_i) { current_row_i = row; // System.out.println("current row_i="+current_row_i); getDataSource().setCurrent(control.getRowObject(row)); if (events_on) { try { ShowCurrentObject(); } catch (Exception ex) { Global.Log.PrintException(ex); } } } } else { current_row_i = Constants.Nan; // System.out.println("no current row_i="+current_row_i); getDataSource().dropCurrent(); if (events_on) { try { ShowNoCurrentObject(); } catch (Exception ex) { Global.Log.PrintException(ex); } } } }); //двойной клик мыши.------------------------------------------------------ control.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if ((e.getClickCount() == 2) && (dataSource.getCurrent() != null)) { try { MouseAction2(); } catch (Exception ex) { Global.Log.PrintException(ex); } } } }); //---------------------------------------------------------------------------- //при переотображении таблицы скидываем текущий объект!! getDataSource().dropCurrent(); try { ShowNoCurrentObject(); } catch (Exception e) { Global.Log.PrintException(e); } } //--- /* if (hasCheckBox()) { TableColumn column = control.getColumnModel().getColumn(1) column.setHeaderRenderer(new TableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { return null; } }); } */ } @Override protected void refresh() { control.CorrectSizes(); } public void Show(Object pk) { Show(); Select(pk); } public void Select(Object pk) { if (isShown()) control.SelectRowByPK(pk); } public void ClearSelection() { if (isShown()) control.clearSelection(); //строка сбросится сама. благодаря сбросу события выбора } public int getRowCount() { return control.getRowCount(); } @Override 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().tables.get(dep).ShowUI(); break; case PASSIVE: break; } } } } @Override 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().tables.get(dep).ClearUI(); break; case PASSIVE: break; } } } } }