admin tools improves (#5388):

* added game ids and created time to tables list;
* added popup hints support to tables list;
* fixed wrong sorting and columns resizing in tables list;
* refactored some modules to share table related code between client and admin console;
This commit is contained in:
Oleg Agafonov 2024-03-22 16:48:34 +04:00
parent 50c75f05bd
commit fef37cdc73
14 changed files with 170 additions and 84 deletions

View file

@ -0,0 +1,41 @@
package mage.components.table;
/**
* @author JayDi85
*/
public class ColumnInfo {
private final Integer index;
private final Integer width;
private final String headerName;
private final String headerHint;
private final Class colClass;
public ColumnInfo(Integer index, Integer width, Class colClass, String headerName, String headerHint) {
this.index = index;
this.width = width;
this.colClass = colClass;
this.headerName = headerName;
this.headerHint = headerHint;
}
public Integer getIndex() {
return index;
}
public Integer getWidth() {
return width;
}
public String getHeaderName() {
return headerName;
}
public String getHeaderHint() {
return headerHint;
}
public Class getColClass() {
return colClass;
}
}

View file

@ -0,0 +1,124 @@
package mage.components.table;
import org.apache.log4j.Logger;
import org.ocpsoft.prettytime.PrettyTime;
import org.ocpsoft.prettytime.TimeFormat;
import org.ocpsoft.prettytime.units.JustNow;
import javax.swing.*;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.Locale;
/**
* GUI: basic mage table for any data like game tables list, players list, etc
*
* @author JayDi85
*/
public class MageTable extends JTable {
private static final Logger logger = Logger.getLogger(MageTable.class);
private TableInfo tableInfo;
public MageTable() {
this(null);
}
public MageTable(TableInfo tableInfo) {
this.tableInfo = tableInfo;
}
public void setTableInfo(TableInfo tableInfo) {
this.tableInfo = tableInfo;
}
@Override
public String getToolTipText(MouseEvent e) {
// default tooltip for cells
java.awt.Point p = e.getPoint();
int viewRow = rowAtPoint(p);
int viewCol = columnAtPoint(p);
int modelRow = getModelRowFromView(this, viewRow);
int modelCol = this.convertColumnIndexToModel(viewCol);
String tip = null;
if (modelRow != -1 && modelCol != -1) {
TableModel model = this.getModel();
if (model instanceof TableModelWithTooltip) {
tip = ((TableModelWithTooltip) model).getTooltipAt(modelRow, modelCol);
} else {
tip = model.getValueAt(modelRow, modelCol).toString();
}
}
return textToHtmlWithSize(tip, this.getFont());
}
@Override
protected JTableHeader createDefaultTableHeader() {
// default tooltip for headers
return new JTableHeader(columnModel) {
@Override
public String getToolTipText(MouseEvent e) {
// html tooltip
java.awt.Point p = e.getPoint();
int colIndex = columnModel.getColumnIndexAtX(p.x);
TableColumn col = columnModel.getColumn(colIndex);
if (colIndex < 0) {
return "";
}
int realIndex = col.getModelIndex();
String tip;
if (tableInfo != null) {
// custom hint from table info
tip = tableInfo.getColumnByIndex(realIndex).getHeaderHint();
if (tip == null) {
tip = tableInfo.getColumnByIndex(realIndex).getHeaderName();
}
} else {
// default hint from header
tip = col.getHeaderValue().toString();
}
return textToHtmlWithSize(tip, MageTable.this.getFont());
}
};
}
public static int getSelectedModelRow(JTable table) {
return getModelRowFromView(table, table.getSelectedRow());
}
public static int getModelRowFromView(JTable table, int viewRow) {
if (viewRow != -1 && viewRow < table.getModel().getRowCount()) {
return table.convertRowIndexToModel(viewRow);
}
return -1;
}
public static int getViewRowFromModel(JTable table, int modelRow) {
if (modelRow != -1 && modelRow < table.getModel().getRowCount()) {
return table.convertRowIndexToView(modelRow);
}
return -1;
}
public static String textToHtmlWithSize(String text, Font font) {
if (text != null && !text.toLowerCase(Locale.ENGLISH).startsWith("<html>")) {
return "<html><p style=\"font-size: " + font.getSize() + ";\">" + text + "</p>";
}
return text;
}
public static void fixTimeFormatter(PrettyTime timeFormatter) {
// TODO: remove after PrettyTime lib upgrade to v5
// change default just now from 60 to 30 secs
// see workaround for 4.0 versions: https://github.com/ocpsoft/prettytime/issues/152
TimeFormat timeFormat = timeFormatter.removeUnit(JustNow.class);
JustNow newJustNow = new JustNow();
newJustNow.setMaxQuantity(1000L * 30L); // 30 seconds gap (show "just now" from 0 to 30 secs)
timeFormatter.registerUnit(newJustNow, timeFormat);
}
}

View file

@ -0,0 +1,44 @@
package mage.components.table;
import java.util.ArrayList;
import java.util.List;
/**
* @author JayDi85
*/
public class TableInfo {
private final List<ColumnInfo> columns = new ArrayList<>();
public TableInfo addColumn(Integer index, Integer width, Class colClass, String headerName, String headerHint) {
this.columns.add(new ColumnInfo(index, width, colClass, headerName, headerHint));
return this;
}
public int[] getColumnsWidth() {
return this.columns.stream().mapToInt(ColumnInfo::getIndex).toArray();
}
public List<ColumnInfo> getColumns() {
return this.columns;
}
public ColumnInfo getColumnByIndex(int index) {
for (ColumnInfo col : this.columns) {
if (col.getIndex().equals(index)) {
return col;
}
}
return null;
}
public ColumnInfo getColumnByName(String name) {
for (ColumnInfo col : this.columns) {
if (col.getHeaderName().equals(name)) {
return col;
}
}
return null;
}
}

View file

@ -0,0 +1,14 @@
package mage.components.table;
/**
* GUI: add support of tooltip/hint for table's cells on mouse move (used by MageTable)
* <p>
* Make sure form and java files uses new MageTable(), not new JTable() code
*
* @author JayDi85
*/
public interface TableModelWithTooltip {
String getTooltipAt(int rowIndex, int columnIndex);
}

View file

@ -0,0 +1,41 @@
package mage.components.table;
import org.ocpsoft.prettytime.PrettyTime;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
import java.util.Date;
import java.util.Locale;
/**
* GUI: create time ago cell renderer for date values in the table's cell
* <p>
* Usage example:
* tableTables.getColumnModel().getColumn(TablesTableModel.COLUMN_CREATED).setCellRenderer(TimeAgoTableCellRenderer.getInstance());
*
* @author JayDi85
*/
public class TimeAgoTableCellRenderer extends DefaultTableCellRenderer {
static final PrettyTime timeFormatter;
static {
timeFormatter = new PrettyTime(Locale.ENGLISH);
MageTable.fixTimeFormatter(timeFormatter);
}
private static final TimeAgoTableCellRenderer instance = new TimeAgoTableCellRenderer();
public static TimeAgoTableCellRenderer getInstance() {
return instance;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Date d = (Date) value;
label.setText(timeFormatter.format(d));
return label;
}
}