Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit Selector #4549

Merged
merged 1 commit into from
Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/
package megamek.client.ui.swing.dialog;

import megamek.MMConstants;
import megamek.MegaMek;
import megamek.client.ui.Messages;
import megamek.client.ui.dialogs.BVDisplayDialog;
import megamek.client.ui.models.XTableColumnModel;
Expand All @@ -31,11 +31,9 @@

import javax.swing.*;
import javax.swing.RowSorter.SortKey;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableRowSorter;
import java.awt.*;
Expand Down Expand Up @@ -98,14 +96,14 @@ public abstract class AbstractUnitSelectorDialog extends JDialog implements Runn
protected static MechSummaryCache mscInstance = MechSummaryCache.getInstance();
protected MechSummary[] mechs;

private MechTableModel unitModel = new MechTableModel();
private XTableColumnModel unitColumnModel = new XTableColumnModel();
private final MechTableModel unitModel = new MechTableModel();
private final XTableColumnModel unitColumnModel = new XTableColumnModel();
private TableColumn pvColumn;
private TableColumn bvColumn;
protected MechSearchFilter searchFilter;

protected JFrame frame;
private UnitLoadingDialog unitLoadingDialog;
private final UnitLoadingDialog unitLoadingDialog;
private AdvancedSearchDialog2 advancedSearchDialog2;

protected TableRowSorter<MechTableModel> sorter;
Expand Down Expand Up @@ -195,6 +193,14 @@ private void initComponents() {
tableUnits.addKeyListener(this);
tableUnits.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "");
tableUnits.setDefaultRenderer(Double.class, new TonnageRenderer());
tableUnits.setDefaultRenderer(Long.class, new PriceRenderer());

DefaultTableCellRenderer centeredRenderer = new DefaultTableCellRenderer();
centeredRenderer.setHorizontalAlignment(JLabel.CENTER);
tableUnits.setDefaultRenderer(Integer.class, centeredRenderer);
tableUnits.getColumnModel().getColumn(MechTableModel.COL_LEVEL).setCellRenderer(centeredRenderer);

tableUnits.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
sorter = new TableRowSorter<>(unitModel);
sorter.setComparator(MechTableModel.COL_CHASSIS, new NaturalOrderComparator());
Expand All @@ -208,17 +214,21 @@ private void initComponents() {
}
});


for (int i = 0; i < unitModel.getColumnCount(); i++) {
tableUnits.getColumnModel().getColumn(i).setPreferredWidth(unitModel.getPreferredWidth(i));
}
bvColumn = tableUnits.getColumnModel().getColumn(MechTableModel.COL_BV);
pvColumn = tableUnits.getColumnModel().getColumn(MechTableModel.COL_PV);
tableUnits.setFont(new Font(MMConstants.FONT_MONOSPACED, Font.PLAIN, 12));
togglePV(false);

scrollTableUnits = new JScrollPane(tableUnits);
scrollTableUnits.setName("scrollTableUnits");

unitModel.addTableModelListener((e) -> UIUtil.updateRowHeights(tableUnits));
sorter.addRowSorterListener((e) -> UIUtil.updateRowHeights(tableUnits));
unitColumnModel.addColumnModelListener(columnModelListener);

gridBagConstraints.insets = new Insets(5, 0, 0, 0);
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 2;
Expand Down Expand Up @@ -432,7 +442,7 @@ private void updateTypeCombo() {
if (selectedIndices.length == 0) {
String option = GUIP.getMechSelectorRulesLevels().replaceAll("[\\[\\]]", "");
if (!option.isBlank()) {
String[] strSelections = option.split("[,]");
String[] strSelections = option.split(",");
selectedIndices = new int[strSelections.length];
for (int i = 0; i < strSelections.length; i++) {
selectedIndices[i] = Integer.parseInt(strSelections[i].trim());
Expand Down Expand Up @@ -491,7 +501,6 @@ private void updateTypeCombo() {
}
}
listTechLevel.setModel(techModel);

listTechLevel.setSelectedIndices(selectedIndices);
listTechLevel.addListSelectionListener(this);
}
Expand Down Expand Up @@ -559,11 +568,7 @@ public boolean include(Entry<? extends MechTableModel, ? extends Integer> entry)
/* Advanced Search */
&& ((searchFilter == null) || MechSearchFilter.isMatch(mech, searchFilter))
&& advancedSearchDialog2.getASAdvancedSearch().matches(mech)) {
if (!textFilter.getText().isBlank()) {
String text = textFilter.getText();
return mech.getName().toLowerCase().contains(text.toLowerCase());
}
return true;
return matchesTextFilter(mech);
}
return false;
}
Expand All @@ -576,6 +581,20 @@ public boolean include(Entry<? extends MechTableModel, ? extends Integer> entry)
lblCount.setText(String.format(" %s %d", msg_unitcount, sorter.getViewRowCount()));
}

protected boolean matchesTextFilter(MechSummary unit) {
if (!textFilter.getText().isBlank()) {
String text = textFilter.getText().toLowerCase();
String[] tokens = text.split(" ");
String searchText = unit.getName().toLowerCase() + "###" + unit.getModel().toLowerCase();
for (String token : tokens) {
if (!searchText.contains(token)) {
return false;
}
}
}
return true;
}

/**
* @return the selected entity (required for MekHQ/MegaMek overrides)
*/
Expand Down Expand Up @@ -777,7 +796,6 @@ private void togglePV(boolean showPV) {
* A table model for displaying work items
*/
protected class MechTableModel extends AbstractTableModel {
//region Variable Declarations
private static final long serialVersionUID = -5457068129532709857L;
private static final int COL_CHASSIS = 0;
private static final int COL_MODEL = 1;
Expand All @@ -790,7 +808,6 @@ protected class MechTableModel extends AbstractTableModel {
private static final int N_COL = 8;

private MechSummary[] data = new MechSummary[0];
//endregion Variable Declarations

@Override
public int getRowCount() {
Expand All @@ -802,26 +819,17 @@ public int getColumnCount() {
return N_COL;
}

public int getPreferredWidth(int col) {
switch (col) {
public int getPreferredWidth(int column) {
switch (column) {
case COL_MODEL:
return 75;
case COL_CHASSIS:
return 125;
case COL_COST:
case COL_WEIGHT:
return 50;
case COL_BV:
return 25;
case COL_PV:
return 25;
case COL_YEAR:
return 25;
case COL_COST:
return 25;
case COL_LEVEL:
return 25;
default:
return 0;
return 15;
}
}

Expand Down Expand Up @@ -854,16 +862,10 @@ public Class<?> getColumnClass(int col) {
return getValueAt(0, col).getClass();
}

@Override
public boolean isCellEditable(int row, int col) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is false in the base class?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. (IDEA told me this is equal to the base class)

return false;
}

public MechSummary getMechSummary(int i) {
return data[i];
}

// fill table with values
public void setData(MechSummary[] ms) {
data = ms;
fireTableDataChanged();
Expand Down Expand Up @@ -909,11 +911,79 @@ public Object getValueAt(int row, int col) {
}
}

/** A specialized renderer for the mek table (formats the unit tonnage). */
public static class TonnageRenderer extends DefaultTableCellRenderer {

@Override
public Component getTableCellRendererComponent(final JTable table, final @Nullable Object value,
final boolean isSelected, final boolean hasFocus,
final int row, final int column) {
if (value instanceof Double) {
setHorizontalAlignment(JLabel.RIGHT);
double weight = (Double) value;
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (weight < 2) {
setText(String.format(MegaMek.getMMOptions().getLocale(), "%,d kg ", (int) (weight * 1000)));
} else if (Math.round(weight) == weight) {
setText(String.format(MegaMek.getMMOptions().getLocale(), "%,d t ", Math.round(weight)));
} else {
setText(String.format(MegaMek.getMMOptions().getLocale(), "%.1f t ", weight));
}
return this;
} else {
return null;
}
}
}

/** A specialized renderer for the mek table (formats the unit price). */
public static class PriceRenderer extends DefaultTableCellRenderer {

@Override
public Component getTableCellRendererComponent(final JTable table, final @Nullable Object value,
final boolean isSelected, final boolean hasFocus,
final int row, final int column) {
if (value instanceof Long) {
setHorizontalAlignment(JLabel.RIGHT);
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
setText(String.format(MegaMek.getMMOptions().getLocale(), "%,d ", (Long) value));
return this;
} else {
return null;
}
}
}

private void adaptToGUIScale() {
UIUtil.adjustDialog(this, UIUtil.FONT_SCALE1);
textFilter.setMinimumSize(new Dimension(UIUtil.scaleForGUI(200), UIUtil.scaleForGUI(28)));
textFilter.setPreferredSize(new Dimension(UIUtil.scaleForGUI(200), UIUtil.scaleForGUI(28)));
techLevelScroll.setMinimumSize(new Dimension(UIUtil.scaleForGUI(300), UIUtil.scaleForGUI(100)));
techLevelScroll.setPreferredSize(new Dimension(UIUtil.scaleForGUI(300), UIUtil.scaleForGUI(100)));
setMinimumSize(UIUtil.scaleForGUI(new Dimension(700, 500)));
textFilter.setMinimumSize(UIUtil.scaleForGUI(new Dimension(200, 28)));
textFilter.setPreferredSize(UIUtil.scaleForGUI(new Dimension(200, 28)));
techLevelScroll.setMinimumSize(UIUtil.scaleForGUI(new Dimension(300, 100)));
techLevelScroll.setPreferredSize(UIUtil.scaleForGUI(new Dimension(300, 100)));
}
}

TableColumnModelListener columnModelListener = new TableColumnModelListener() {

@Override
public void columnAdded(TableColumnModelEvent e) { }

@Override
public void columnRemoved(TableColumnModelEvent e) { }

@Override
public void columnMoved(TableColumnModelEvent e) {
UIUtil.updateRowHeights(tableUnits);
}

@Override
public void columnMarginChanged(ChangeEvent e) {
UIUtil.updateRowHeights(tableUnits);
}

@Override
public void columnSelectionChanged(ListSelectionEvent e) {
UIUtil.updateRowHeights(tableUnits);
}
};
}
18 changes: 18 additions & 0 deletions megamek/src/megamek/client/ui/swing/util/UIUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,24 @@ public static boolean isModalDialogDisplayed() {
.anyMatch(w -> w.isShowing() && (w instanceof JDialog) && ((JDialog) w).isModal());
}

/**
* Automatically determines the correct row heights for each row of the given JTable and sets it.
* Note: Just calling this after a data change or after {@link #adjustDialog(JDialog, int)} will
* typically not work well. Instead, it must be called from a {@link javax.swing.event.TableModelListener},
* a {@link javax.swing.event.TableColumnModelListener} and (if a row sorter is used) a
* {@link javax.swing.event.RowSorterListener} to be effective.
*/
public static void updateRowHeights(JTable table) {
for (int row = 0; row < table.getRowCount(); row++) {
int rowHeight = table.getRowHeight();
for (int column = 0; column < table.getColumnCount(); column++) {
Component comp = table.prepareRenderer(table.getCellRenderer(row, column), row, column);
rowHeight = Math.max(rowHeight, comp.getPreferredSize().height);
}
table.setRowHeight(row, rowHeight);
}
}

// PRIVATE

private final static Color LIGHTUI_GREEN = new Color(20, 140, 20);
Expand Down