diff --git a/megamek/i18n/megamek/client/messages.properties b/megamek/i18n/megamek/client/messages.properties
index d11b943ffd..2753c8c183 100644
--- a/megamek/i18n/megamek/client/messages.properties
+++ b/megamek/i18n/megamek/client/messages.properties
@@ -2174,15 +2174,15 @@ MekSelectorDialog.Search.Armor25=25% of maximum
MekSelectorDialog.Search.Armor50=50% of maximum
MekSelectorDialog.Search.Armor75=75% of maximum
MekSelectorDialog.Search.Armor90=90% of maximum
-MekSelectorDialog.Search.WeaponClass=Has Weapon Type:
-MekSelectorDialog.Search.Weapons=Has weapons:
-MekSelectorDialog.Search.WeaponsAtLeast=At least
-MekSelectorDialog.Search.Equipment=Has equipment:
+MekSelectorDialog.Search.WeaponClass=Weapon Type
+MekSelectorDialog.Search.Weapons=Weapons
+MekSelectorDialog.Search.Equipment=Equipment
MekSelectorDialog.Search.Year=Design year:
MekSelectorDialog.Search.TableFilters=Table filters:
MekSelectorDialog.Search.UnitType=Unit Type:
MekSelectorDialog.Search.TechClass=Tech Class:
MekSelectorDialog.Search.TechLevel=Tech Level:
+MekSelectorDialog.Search.TableFilter=Filter Text:
MekSelectorDialog.Search.Quirk=Quirk:
MekSelectorDialog.Search.Quirks=Quirks
MekSelectorDialog.Search.WeaponQuirk=Weapon Quirk:
diff --git a/megamek/src/megamek/client/ui/advancedsearch/AndFilterToken.java b/megamek/src/megamek/client/ui/advancedsearch/AndFilterToken.java
new file mode 100644
index 0000000000..428cb81d70
--- /dev/null
+++ b/megamek/src/megamek/client/ui/advancedsearch/AndFilterToken.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.client.ui.advancedsearch;
+
+import megamek.common.MekSearchFilter;
+
+public class AndFilterToken extends OperatorFT {
+
+ public AndFilterToken() {
+ super(MekSearchFilter.BoolOp.AND);
+ }
+}
diff --git a/megamek/src/megamek/client/ui/advancedsearch/EquipmentFilterToken.java b/megamek/src/megamek/client/ui/advancedsearch/EquipmentFilterToken.java
new file mode 100644
index 0000000000..b40b767108
--- /dev/null
+++ b/megamek/src/megamek/client/ui/advancedsearch/EquipmentFilterToken.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+
+package megamek.client.ui.advancedsearch;
+
+public class EquipmentFilterToken implements FilterToken {
+
+
+}
diff --git a/megamek/src/megamek/client/ui/advancedsearch/EquipmentTableModel.java b/megamek/src/megamek/client/ui/advancedsearch/EquipmentTableModel.java
index 693acbbbfd..f94005fd3f 100644
--- a/megamek/src/megamek/client/ui/advancedsearch/EquipmentTableModel.java
+++ b/megamek/src/megamek/client/ui/advancedsearch/EquipmentTableModel.java
@@ -22,11 +22,12 @@
import megamek.common.TechConstants;
import javax.swing.table.AbstractTableModel;
+import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Vector;
+import java.util.List;
/**
- * A table model for displaying equipment
+ * A table model for the advanced search weapon tab's equipment list
*/
public class EquipmentTableModel extends AbstractTableModel {
@@ -40,7 +41,7 @@ public class EquipmentTableModel extends AbstractTableModel {
private final TWAdvancedSearchPanel twAdvancedSearchPanel;
private int[] qty;
- private Vector equipment = new Vector<>();
+ private List equipment = new ArrayList<>();
public EquipmentTableModel(TWAdvancedSearchPanel twAdvancedSearchPanel) {
this.twAdvancedSearchPanel = twAdvancedSearchPanel;
@@ -57,38 +58,26 @@ public int getColumnCount() {
}
public int getPreferredWidth(int col) {
- switch (col) {
- case COL_QTY:
- return 40;
- case COL_NAME:
- return 400;
- case COL_IS_CLAN:
- return 75;
- case COL_COST:
- return 175;
- case COL_LEVEL:
- return 100;
- default:
- return 0;
- }
+ return switch (col) {
+ case COL_QTY -> 40;
+ case COL_NAME -> 400;
+ case COL_IS_CLAN -> 75;
+ case COL_COST -> 175;
+ case COL_LEVEL -> 100;
+ default -> 0;
+ };
}
@Override
public String getColumnName(int column) {
- switch (column) {
- case COL_QTY:
- return "Qty";
- case COL_NAME:
- return "Name";
- case COL_IS_CLAN:
- return "IS/Clan";
- case COL_COST:
- return "Cost";
- case COL_LEVEL:
- return "Lvl";
- default:
- return "?";
- }
+ return switch (column) {
+ case COL_QTY -> "Qty";
+ case COL_NAME -> "Name";
+ case COL_IS_CLAN -> "IS/Clan";
+ case COL_COST -> "Cost";
+ case COL_LEVEL -> "Lvl";
+ default -> "?";
+ };
}
@Override
@@ -98,16 +87,10 @@ public Class> getColumnClass(int c) {
@Override
public boolean isCellEditable(int row, int col) {
- switch (col) {
- case COL_QTY:
- return true;
- default:
- return false;
- }
+ return col == COL_QTY;
}
- // fill table with values
- public void setData(Vector eq) {
+ public void setData(List eq) {
equipment = eq;
qty = new int[eq.size()];
Arrays.fill(qty, 1);
@@ -115,7 +98,7 @@ public void setData(Vector eq) {
}
public EquipmentType getEquipmentTypeAt(int row) {
- return equipment.elementAt(row);
+ return equipment.get(row);
}
@Override
@@ -123,36 +106,24 @@ public Object getValueAt(int row, int col) {
if (row >= equipment.size()) {
return null;
}
- EquipmentType eq = equipment.elementAt(row);
- switch (col) {
- case COL_QTY:
- return qty[row] + "";
- case COL_NAME:
- return eq.getName();
- case COL_IS_CLAN:
- return TechConstants.getTechName(eq.getTechLevel(twAdvancedSearchPanel.gameYear));
- case COL_COST:
- return eq.getRawCost();
- case COL_LEVEL:
- return TechConstants.getSimpleLevelName(TechConstants
- .convertFromNormalToSimple(eq
- .getTechLevel(twAdvancedSearchPanel.gameYear)));
- case COL_INTERNAL_NAME:
- return eq.getInternalName();
- default:
- return "?";
- }
+ EquipmentType eq = equipment.get(row);
+ return switch (col) {
+ case COL_QTY -> qty[row] + "";
+ case COL_NAME -> eq.getName();
+ case COL_IS_CLAN -> TechConstants.getTechName(eq.getTechLevel(twAdvancedSearchPanel.gameYear));
+ case COL_COST -> eq.getRawCost();
+ case COL_LEVEL -> TechConstants.getSimpleLevelName(
+ TechConstants.convertFromNormalToSimple(eq.getTechLevel(twAdvancedSearchPanel.gameYear)));
+ case COL_INTERNAL_NAME -> eq.getInternalName();
+ default -> "?";
+ };
}
@Override
public void setValueAt(Object value, int row, int col) {
- switch (col) {
- case COL_QTY:
- qty[row] = Integer.parseInt((String) value);
- fireTableCellUpdated(row, col);
- break;
- default:
- break;
+ if (col == COL_QTY) {
+ qty[row] = Integer.parseInt((String) value);
+ fireTableCellUpdated(row, col);
}
}
}
diff --git a/megamek/src/megamek/client/ui/advancedsearch/EquipmentFT.java b/megamek/src/megamek/client/ui/advancedsearch/EquipmentTypeFT.java
similarity index 76%
rename from megamek/src/megamek/client/ui/advancedsearch/EquipmentFT.java
rename to megamek/src/megamek/client/ui/advancedsearch/EquipmentTypeFT.java
index 9529cb411e..7f7f8294e9 100644
--- a/megamek/src/megamek/client/ui/advancedsearch/EquipmentFT.java
+++ b/megamek/src/megamek/client/ui/advancedsearch/EquipmentTypeFT.java
@@ -5,12 +5,13 @@
*
* @author Arlith
*/
-public class EquipmentFT extends FilterTokens {
+public class EquipmentTypeFT extends EquipmentFilterToken {
+
public String internalName;
public String fullName;
public int qty;
- public EquipmentFT(String in, String fn, int q) {
+ public EquipmentTypeFT(String in, String fn, int q) {
internalName = in;
fullName = fn;
qty = q;
diff --git a/megamek/src/megamek/client/ui/advancedsearch/FilterToken.java b/megamek/src/megamek/client/ui/advancedsearch/FilterToken.java
new file mode 100644
index 0000000000..17ece989cc
--- /dev/null
+++ b/megamek/src/megamek/client/ui/advancedsearch/FilterToken.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.client.ui.advancedsearch;
+
+/**
+ * Marker interface for different tokens that can be in a filter expression.
+ *
+ * @author Arlith
+ */
+public interface FilterToken {
+
+}
diff --git a/megamek/src/megamek/client/ui/advancedsearch/FilterTokens.java b/megamek/src/megamek/client/ui/advancedsearch/FilterTokens.java
deleted file mode 100644
index f786d86784..0000000000
--- a/megamek/src/megamek/client/ui/advancedsearch/FilterTokens.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package megamek.client.ui.advancedsearch;
-
-/**
- * Base class for different tokens that can be in a filter expression.
- *
- * @author Arlith
- */
-public class FilterTokens {
-
-}
diff --git a/megamek/src/megamek/client/ui/advancedsearch/LeftParensFilterToken.java b/megamek/src/megamek/client/ui/advancedsearch/LeftParensFilterToken.java
new file mode 100644
index 0000000000..da69edea0e
--- /dev/null
+++ b/megamek/src/megamek/client/ui/advancedsearch/LeftParensFilterToken.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.client.ui.advancedsearch;
+
+public class LeftParensFilterToken extends ParensFT {
+
+ public LeftParensFilterToken() {
+ super("(");
+ }
+}
diff --git a/megamek/src/megamek/client/ui/advancedsearch/MiscSearchTab.java b/megamek/src/megamek/client/ui/advancedsearch/MiscSearchTab.java
index 7df03516eb..071b9177cf 100644
--- a/megamek/src/megamek/client/ui/advancedsearch/MiscSearchTab.java
+++ b/megamek/src/megamek/client/ui/advancedsearch/MiscSearchTab.java
@@ -24,7 +24,6 @@
import javax.swing.*;
import java.awt.*;
-import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
@@ -76,25 +75,25 @@ public class MiscSearchTab extends JPanel {
JTextField tStartBV = new JTextField(4);
JTextField tEndBV = new JTextField(4);
JLabel lblCockpitType = new JLabel(Messages.getString("MekSelectorDialog.Search.CockpitType"));
- JList listCockpitType = new JList<>(new DefaultListModel());
+ JList listCockpitType = new JList<>(new DefaultListModel<>());
JScrollPane spCockpitType = new JScrollPane(listCockpitType);
JLabel lblArmorType = new JLabel(Messages.getString("MekSelectorDialog.Search.ArmorType"));
- JList listArmorType = new JList<>(new DefaultListModel());
+ JList listArmorType = new JList<>(new DefaultListModel<>());
JScrollPane spArmorType = new JScrollPane(listArmorType);
JLabel lblInternalsType = new JLabel(Messages.getString("MekSelectorDialog.Search.InternalsType"));
- JList listInternalsType = new JList<>(new DefaultListModel());
+ JList listInternalsType = new JList<>(new DefaultListModel<>());
JScrollPane spInternalsType = new JScrollPane(listInternalsType);
JLabel lblEngineType = new JLabel(Messages.getString("MekSelectorDialog.Search.Engine"));
- JList listEngineType = new JList<>(new DefaultListModel());
+ JList listEngineType = new JList<>(new DefaultListModel<>());
JScrollPane spEngineType = new JScrollPane(listEngineType);
JLabel lblGyroType = new JLabel(Messages.getString("MekSelectorDialog.Search.Gyro"));
- JList listGyroType = new JList<>(new DefaultListModel());
+ JList listGyroType = new JList<>(new DefaultListModel<>());
JScrollPane spGyroType = new JScrollPane(listGyroType);
JLabel lblTechLevel = new JLabel(Messages.getString("MekSelectorDialog.Search.TechLevel"));
- JList listTechLevel = new JList<>(new DefaultListModel());
+ JList listTechLevel = new JList<>(new DefaultListModel<>());
JScrollPane spTechLevel = new JScrollPane(listTechLevel);
JLabel lblTechBase = new JLabel(Messages.getString("MekSelectorDialog.Search.TechBase"));
- JList listTechBase = new JList<>(new DefaultListModel());
+ JList listTechBase = new JList<>(new DefaultListModel<>());
JScrollPane spTechBase = new JScrollPane(listTechBase);
private JPanel createBaseAttributes() {
@@ -267,7 +266,7 @@ private JPanel createBaseComboBoxes() {
gyroPanel.add(spGyroType, BorderLayout.CENTER);
baseComboBoxesPanel.add(gyroPanel, c);
- c.gridx = 0; c.gridy++;;
+ c.gridx = 0; c.gridy++;
JPanel armorTypePanel = new JPanel(new BorderLayout());
armorTypePanel.add(lblArmorType, BorderLayout.NORTH);
armorTypePanel.add(spArmorType, BorderLayout.CENTER);
@@ -282,7 +281,7 @@ private JPanel createBaseComboBoxes() {
internalsPanel.add(spInternalsType, BorderLayout.CENTER);
baseComboBoxesPanel.add(internalsPanel, c);
- c.gridx = 0; c.gridy++;;
+ c.gridx = 0; c.gridy++;
JPanel techLevelPanel = new JPanel(new BorderLayout());
techLevelPanel.add(lblTechLevel, BorderLayout.NORTH);
techLevelPanel.add(spTechLevel, BorderLayout.CENTER);
@@ -296,8 +295,8 @@ private JPanel createBaseComboBoxes() {
return baseComboBoxesPanel;
}
- MiscSearchTab(ActionListener listener) {
- btnBaseClear.addActionListener(listener);
+ MiscSearchTab() {
+ btnBaseClear.addActionListener(e -> clear());
GridBagConstraints c = new GridBagConstraints();
setLayout(new GridBagLayout());
@@ -310,12 +309,12 @@ private JPanel createBaseComboBoxes() {
c.gridx = 0; c.gridy = 0;
add(createBaseAttributes(), c);
- c.gridx = 0; c.gridy++;;
+ c.gridx = 0; c.gridy++;
add(createBaseComboBoxes(), c);
c.weighty = 1;
JPanel clearPanel = new JPanel();
- c.gridx = 0; c.gridy++;;
+ c.gridx = 0; c.gridy++;
clearPanel.add(btnBaseClear, c);
add(clearPanel, c);
}
@@ -380,4 +379,52 @@ private void toggleText(JList list, int index) {
list.setModel(m);
list.repaint();
}
+
+ void clear() {
+ tStartWalk.setText("");
+ tEndWalk.setText("");
+ tStartJump.setText("");
+ tEndJump.setText("");
+ cArmor.setSelectedIndex(0);
+ cOfficial.setSelectedIndex(0);
+ cCanon.setSelectedIndex(0);
+ cPatchwork.setSelectedIndex(0);
+ cInvalid.setSelectedIndex(0);
+ cFailedToLoadEquipment.setSelectedIndex(0);
+ cClanEngine.setSelectedIndex(0);
+ tStartTankTurrets.setText("");
+ tEndTankTurrets.setText("");
+ tStartLowerArms.setText("");
+ tEndLowerArms.setText("");
+ tStartHands.setText("");
+ tEndHands.setText("");
+ tStartYear.setText("");
+ tEndYear.setText("");
+ tStartTons.setText("");
+ tEndTons.setText("");
+ tStartBV.setText("");
+ tEndBV.setText("");
+ tSource.setText("");
+ tMULId.setText("");
+
+ clearTriStateItem(listArmorType);
+ clearTriStateItem(listCockpitType);
+ clearTriStateItem(listEngineType);
+ clearTriStateItem(listGyroType);
+ clearTriStateItem(listInternalsType);
+ clearTriStateItem(listTechLevel);
+ clearTriStateItem(listTechBase);
+ }
+
+ void clearTriStateItem(JList l) {
+ ListModel m = l.getModel();
+
+ for (int i = 0; i < m.getSize(); i++) {
+ TriStateItem ms = m.getElementAt(i);
+ ms.state = "\u2610";
+ }
+
+ l.setModel(m);
+ l.repaint();
+ }
}
diff --git a/megamek/src/megamek/client/ui/advancedsearch/OperationFT.java b/megamek/src/megamek/client/ui/advancedsearch/OperatorFT.java
similarity index 81%
rename from megamek/src/megamek/client/ui/advancedsearch/OperationFT.java
rename to megamek/src/megamek/client/ui/advancedsearch/OperatorFT.java
index 1aea114fd6..769b3e6283 100644
--- a/megamek/src/megamek/client/ui/advancedsearch/OperationFT.java
+++ b/megamek/src/megamek/client/ui/advancedsearch/OperatorFT.java
@@ -7,10 +7,10 @@
*
* @author Arlith
*/
-public class OperationFT extends FilterTokens {
+public abstract class OperatorFT implements FilterToken {
public MekSearchFilter.BoolOp op;
- public OperationFT(MekSearchFilter.BoolOp o) {
+ protected OperatorFT(MekSearchFilter.BoolOp o) {
op = o;
}
diff --git a/megamek/src/megamek/client/ui/advancedsearch/OrFilterToken.java b/megamek/src/megamek/client/ui/advancedsearch/OrFilterToken.java
new file mode 100644
index 0000000000..93c304fd00
--- /dev/null
+++ b/megamek/src/megamek/client/ui/advancedsearch/OrFilterToken.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.client.ui.advancedsearch;
+
+import megamek.common.MekSearchFilter;
+
+public class OrFilterToken extends OperatorFT {
+
+ public OrFilterToken() {
+ super(MekSearchFilter.BoolOp.OR);
+ }
+}
diff --git a/megamek/src/megamek/client/ui/advancedsearch/ParensFT.java b/megamek/src/megamek/client/ui/advancedsearch/ParensFT.java
index f5ec7906a5..b31558a22c 100644
--- a/megamek/src/megamek/client/ui/advancedsearch/ParensFT.java
+++ b/megamek/src/megamek/client/ui/advancedsearch/ParensFT.java
@@ -5,7 +5,7 @@
*
* @author Arlith
*/
-public class ParensFT extends FilterTokens {
+public abstract class ParensFT implements FilterToken {
public String parens;
public ParensFT(String p) {
diff --git a/megamek/src/megamek/client/ui/advancedsearch/QuirksSearchTab.java b/megamek/src/megamek/client/ui/advancedsearch/QuirksSearchTab.java
index 4b51dcef08..f117d6e654 100644
--- a/megamek/src/megamek/client/ui/advancedsearch/QuirksSearchTab.java
+++ b/megamek/src/megamek/client/ui/advancedsearch/QuirksSearchTab.java
@@ -23,7 +23,6 @@
import javax.swing.*;
import java.awt.*;
-import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
@@ -40,18 +39,18 @@ class QuirksSearchTab extends JPanel {
JLabel lblQuirkExclude = new JLabel("\u2612");
JComboBox cQuirkExclude = new JComboBox<>();
JLabel lblQuirkType = new JLabel(Messages.getString("MekSelectorDialog.Search.Quirk"));
- JList listQuirkType = new JList<>(new DefaultListModel());
+ JList listQuirkType = new JList<>(new DefaultListModel<>());
JScrollPane spQuirkType = new JScrollPane(listQuirkType);
JLabel lblWeaponQuirkInclude = new JLabel("\u2611");
JComboBox cWeaponQuirkInclue = new JComboBox<>();
JLabel lblWeaponQuirkExclude = new JLabel("\u2612");
JComboBox cWeaponQuirkExclude = new JComboBox<>();
JLabel lblWeaponQuirkType = new JLabel(Messages.getString("MekSelectorDialog.Search.WeaponQuirk"));
- JList listWeaponQuirkType = new JList<>(new DefaultListModel());
+ JList listWeaponQuirkType = new JList<>(new DefaultListModel<>());
JScrollPane spWeaponQuirkType = new JScrollPane(listWeaponQuirkType);
- QuirksSearchTab(ActionListener listener) {
- btnQuirksClear.addActionListener(listener);
+ QuirksSearchTab() {
+ btnQuirksClear.addActionListener(e -> clear());
loadAndOr(cQuirkInclue, 0);
loadAndOr(cQuirkExclude, 1);
@@ -70,7 +69,7 @@ class QuirksSearchTab extends JPanel {
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.NONE;
c.insets = new Insets(20, 10, 0, 0);
- c.gridx = 0; c.gridy++;;
+ c.gridx = 0; c.gridy++;
JPanel quirkPanel = new JPanel(new BorderLayout());
JPanel quirkIEPanel = new JPanel(new FlowLayout());
quirkIEPanel.add(lblQuirkType);
@@ -96,7 +95,7 @@ class QuirksSearchTab extends JPanel {
add(weaponQuirkPanel, c);
c.weighty = 1;
JPanel blankPanel = new JPanel();
- c.gridx = 0; c.gridy++;;
+ c.gridx = 0; c.gridy++;
blankPanel.add(btnQuirksClear, c);
add(blankPanel, c);
}
@@ -167,4 +166,26 @@ private void toggleText(JList list, int index) {
list.setModel(m);
list.repaint();
}
+
+ void clear() {
+ cQuirkInclue.setSelectedIndex(0);
+ cQuirkExclude.setSelectedIndex(1);
+ clearTriStateItem(listQuirkType);
+
+ cWeaponQuirkInclue.setSelectedIndex(0);
+ cWeaponQuirkExclude.setSelectedIndex(1);
+ clearTriStateItem(listWeaponQuirkType);
+ }
+
+ void clearTriStateItem(JList l) {
+ ListModel m = l.getModel();
+
+ for (int i = 0; i < m.getSize(); i++) {
+ TriStateItem ms = m.getElementAt(i);
+ ms.state = "\u2610";
+ }
+
+ l.setModel(m);
+ l.repaint();
+ }
}
diff --git a/megamek/src/megamek/client/ui/advancedsearch/RightParensFilterToken.java b/megamek/src/megamek/client/ui/advancedsearch/RightParensFilterToken.java
new file mode 100644
index 0000000000..73c48c889b
--- /dev/null
+++ b/megamek/src/megamek/client/ui/advancedsearch/RightParensFilterToken.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.client.ui.advancedsearch;
+
+public class RightParensFilterToken extends ParensFT {
+
+ public RightParensFilterToken() {
+ super(")");
+ }
+}
diff --git a/megamek/src/megamek/client/ui/advancedsearch/TWAdvancedSearchPanel.java b/megamek/src/megamek/client/ui/advancedsearch/TWAdvancedSearchPanel.java
index f6465f8e27..66ff10426e 100644
--- a/megamek/src/megamek/client/ui/advancedsearch/TWAdvancedSearchPanel.java
+++ b/megamek/src/megamek/client/ui/advancedsearch/TWAdvancedSearchPanel.java
@@ -20,8 +20,6 @@
package megamek.client.ui.advancedsearch;
import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.*;
@@ -37,7 +35,7 @@
* @author Jay Lawson
* @author Simon (Juliez)
*/
-public class TWAdvancedSearchPanel extends JTabbedPane implements ActionListener {
+public class TWAdvancedSearchPanel extends JTabbedPane {
public MekSearchFilter mekFilter = new MekSearchFilter();
@@ -57,11 +55,11 @@ public class TWAdvancedSearchPanel extends JTabbedPane implements ActionListener
public TWAdvancedSearchPanel(int year) {
gameYear = year;
- basePanel = new MiscSearchTab(this);
+ basePanel = new MiscSearchTab();
weaponEqPanel = new WeaponSearchTab(this);
unitTypePanel = new UnitTypeSearchTab();
- quirkPanel = new QuirksSearchTab(this);
- transportsPanel = new TransportsSearchTab(this);
+ quirkPanel = new QuirksSearchTab();
+ transportsPanel = new TransportsSearchTab();
String msg_base = Messages.getString("MekSelectorDialog.Search.Base");
String msg_weaponEq = Messages.getString("MekSelectorDialog.Search.WeaponEq");
@@ -71,7 +69,8 @@ public TWAdvancedSearchPanel(int year) {
addTab(msg_unitType, new StandardScrollPane(unitTypePanel));
addTab(msg_base, new StandardScrollPane(basePanel));
- addTab(msg_weaponEq, new StandardScrollPane(weaponEqPanel));
+ // The weapon panel must manage its own scrollpane!
+ addTab(msg_weaponEq, weaponEqPanel);
addTab(msg_transports, new StandardScrollPane(transportsPanel));
addTab(msg_quirkType, new StandardScrollPane(quirkPanel));
}
@@ -88,14 +87,7 @@ public MekSearchFilter showDialog() {
MekSearchFilter currFilter = mekFilter;
mekFilter = new MekSearchFilter(currFilter);
weaponEqPanel.txtWEEqExp.setText(mekFilter.getEquipmentExpression());
- if ((weaponEqPanel.filterToks == null) || weaponEqPanel.filterToks.isEmpty()
- || (weaponEqPanel.filterToks.get(weaponEqPanel.filterToks.size() - 1) instanceof OperationFT)) {
- weaponEqPanel.disableOperationButtons();
- weaponEqPanel.enableSelectionButtons();
- } else {
- weaponEqPanel.enableOperationButtons();
- weaponEqPanel.disableSelectionButtons();
- }
+ weaponEqPanel.adaptTokenButtons();
setVisible(true);
if (isCanceled) {
mekFilter = currFilter;
@@ -108,7 +100,7 @@ public MekSearchFilter showDialog() {
public void prepareFilter() {
try {
mekFilter = new MekSearchFilter(mekFilter);
- mekFilter.createFilterExpressionFromTokens(weaponEqPanel.filterToks);
+ mekFilter.createFilterExpressionFromTokens(weaponEqPanel.filterTokens);
updateMekSearchFilter();
} catch (MekSearchFilter.FilterParsingException e) {
JOptionPane.showMessageDialog(this,
@@ -118,190 +110,13 @@ public void prepareFilter() {
}
}
- /**
- * Listener for button presses.
- */
- @Override
- public void actionPerformed(ActionEvent ev) {
- if (ev.getSource().equals(weaponEqPanel.cboUnitType)
- || ev.getSource().equals(weaponEqPanel.cboTechLevel)
- || ev.getSource().equals(weaponEqPanel.cboTechClass)) {
- weaponEqPanel.filterTables();
- } else if (ev.getSource().equals(weaponEqPanel.btnWEAdd)) {
- int row = weaponEqPanel.tblEquipment.getSelectedRow();
- if (row >= 0) {
- String internalName = (String)
- weaponEqPanel.tblEquipment.getModel().getValueAt(
- weaponEqPanel.tblEquipment.convertRowIndexToModel(row),
- EquipmentTableModel.COL_INTERNAL_NAME);
- String fullName = (String) weaponEqPanel.tblEquipment.getValueAt(row, EquipmentTableModel.COL_NAME);
- int qty = Integer.parseInt((String)
- weaponEqPanel.tblEquipment.getValueAt(row, EquipmentTableModel.COL_QTY));
- weaponEqPanel.filterToks.add(new EquipmentFT(internalName, fullName, qty));
- weaponEqPanel.txtWEEqExp.setText(weaponEqPanel.filterExpressionString());
- weaponEqPanel.btnWEBack.setEnabled(true);
- weaponEqPanel.enableOperationButtons();
- weaponEqPanel.disableSelectionButtons();
- }
- row = weaponEqPanel.tblWeapons.getSelectedRow();
- if (row >= 0) {
- String internalName = (String)
- weaponEqPanel.tblWeapons.getModel().getValueAt(
- weaponEqPanel.tblWeapons.convertRowIndexToModel(row),
- WeaponsTableModel.COL_INTERNAL_NAME);
- String fullName = (String) weaponEqPanel.tblWeapons.getValueAt(row, WeaponsTableModel.COL_NAME);
- int qty = Integer.parseInt((String)
- weaponEqPanel.tblWeapons.getValueAt(row, WeaponsTableModel.COL_QTY));
- weaponEqPanel.filterToks.add(new EquipmentFT(internalName, fullName, qty));
- weaponEqPanel.txtWEEqExp.setText(weaponEqPanel.filterExpressionString());
- weaponEqPanel.btnWEBack.setEnabled(true);
- weaponEqPanel.enableOperationButtons();
- weaponEqPanel.disableSelectionButtons();
- }
- row = weaponEqPanel.tblWeaponType.getSelectedRow();
- if (row >= 0) {
- int qty = Integer.parseInt((String)weaponEqPanel.tblWeaponType.getValueAt(row, WeaponClassTableModel.COL_QTY));
- weaponEqPanel.filterToks.add(new WeaponClassFT((WeaponClass)weaponEqPanel.tblWeaponType.getModel().getValueAt(weaponEqPanel.tblWeaponType.convertRowIndexToModel(row), WeaponClassTableModel.COL_VAL), qty));
- weaponEqPanel.txtWEEqExp.setText(weaponEqPanel.filterExpressionString());
- weaponEqPanel.btnWEBack.setEnabled(true);
- weaponEqPanel.enableOperationButtons();
- weaponEqPanel.disableSelectionButtons();
- }
- } else if (ev.getSource().equals(weaponEqPanel.btnWELeftParen)) {
- weaponEqPanel.filterToks.add(new ParensFT("("));
- weaponEqPanel.txtWEEqExp.setText(weaponEqPanel.filterExpressionString());
- weaponEqPanel.btnWEBack.setEnabled(true);
- weaponEqPanel.disableOperationButtons();
- weaponEqPanel.enableSelectionButtons();
- weaponEqPanel.btnWELeftParen.setEnabled(false);
- weaponEqPanel.btnWERightParen.setEnabled(false);
- } else if (ev.getSource().equals(weaponEqPanel.btnWERightParen)) {
- weaponEqPanel.filterToks.add(new ParensFT(")"));
- weaponEqPanel.txtWEEqExp.setText(weaponEqPanel.filterExpressionString());
- weaponEqPanel.btnWEBack.setEnabled(true);
- weaponEqPanel.enableOperationButtons();
- weaponEqPanel.disableSelectionButtons();
- weaponEqPanel.btnWELeftParen.setEnabled(false);
- weaponEqPanel.btnWERightParen.setEnabled(false);
- } else if (ev.getSource().equals(weaponEqPanel.btnWEAnd)) {
- weaponEqPanel.filterToks.add(new OperationFT(MekSearchFilter.BoolOp.AND));
- weaponEqPanel.txtWEEqExp.setText(weaponEqPanel.filterExpressionString());
- weaponEqPanel.btnWEBack.setEnabled(true);
- weaponEqPanel.disableOperationButtons();
- weaponEqPanel.enableSelectionButtons();
- } else if (ev.getSource().equals(weaponEqPanel.btnWEOr)) {
- weaponEqPanel.filterToks.add(new OperationFT(MekSearchFilter.BoolOp.OR));
- weaponEqPanel.txtWEEqExp.setText(weaponEqPanel.filterExpressionString());
- weaponEqPanel.btnWEBack.setEnabled(true);
- weaponEqPanel.disableOperationButtons();
- weaponEqPanel.enableSelectionButtons();
- } else if (ev.getSource().equals(weaponEqPanel.btnWEBack)) {
- if (!weaponEqPanel.filterToks.isEmpty()) {
- weaponEqPanel.filterToks.remove(weaponEqPanel.filterToks.size() - 1);
- weaponEqPanel.txtWEEqExp.setText(weaponEqPanel.filterExpressionString());
- if (weaponEqPanel.filterToks.isEmpty()) {
- weaponEqPanel.btnWEBack.setEnabled(false);
- }
-
- if ((weaponEqPanel.filterToks.isEmpty()) || (weaponEqPanel.filterToks.get(weaponEqPanel.filterToks.size() - 1) instanceof OperationFT)) {
- weaponEqPanel.disableOperationButtons();
- weaponEqPanel.enableSelectionButtons();
- } else {
- weaponEqPanel.enableOperationButtons();
- weaponEqPanel.disableSelectionButtons();
- }
- }
- } else if (ev.getSource().equals(weaponEqPanel.btnWEClear)) {
- weaponEqPanel.clearWeaponsEquipment();
- } else if (ev.getSource().equals(basePanel.btnBaseClear)) {
- clearBase();
- } else if (ev.getSource().equals(transportsPanel.btnTransportsClear)) {
- transportsPanel.clearTransports();
- } else if (ev.getSource().equals(quirkPanel.btnQuirksClear)) {
- clearQuirks();
- }
- }
-
- private void toggleText(JButton b) {
- if (b.getText().equals("\u2610")) {
- b.setText("\u2611");
- } else if (b.getText().equals("\u2611")) {
- b.setText("\u2612");
- } else if (b.getText().equals("\u2612")) {
- b.setText("\u2610");
- } else {
- b.setText("\u2610");
- }
- }
-
- private void clearTriStateItem(JList l) {
- ListModel m = l.getModel();
-
- for (int i = 0; i < m.getSize(); i++) {
- TriStateItem ms = m.getElementAt(i);
- ms.state = "\u2610";
- }
-
- l.setModel(m);
- l.repaint();
- }
-
- private void clearBase() {
- basePanel.tStartWalk.setText("");
- basePanel.tEndWalk.setText("");
- basePanel.tStartJump.setText("");
- basePanel.tEndJump.setText("");
- basePanel.cArmor.setSelectedIndex(0);
- basePanel.cOfficial.setSelectedIndex(0);
- basePanel.cCanon.setSelectedIndex(0);
- basePanel.cPatchwork.setSelectedIndex(0);
- basePanel.cInvalid.setSelectedIndex(0);
- basePanel.cFailedToLoadEquipment.setSelectedIndex(0);
- basePanel.cClanEngine.setSelectedIndex(0);
- basePanel.tStartTankTurrets.setText("");
- basePanel.tEndTankTurrets.setText("");
- basePanel.tStartLowerArms.setText("");
- basePanel.tEndLowerArms.setText("");
- basePanel.tStartHands.setText("");
- basePanel.tEndHands.setText("");
- basePanel.tStartYear.setText("");
- basePanel.tEndYear.setText("");
- basePanel.tStartTons.setText("");
- basePanel.tEndTons.setText("");
- basePanel.tStartBV.setText("");
- basePanel.tEndBV.setText("");
- basePanel.tSource.setText("");
- basePanel.tMULId.setText("");
-
- clearTriStateItem(basePanel.listArmorType);
- clearTriStateItem(basePanel.listCockpitType);
- clearTriStateItem(basePanel.listEngineType);
- clearTriStateItem(basePanel.listGyroType);
- clearTriStateItem(basePanel.listInternalsType);
- clearTriStateItem(basePanel.listTechLevel);
- clearTriStateItem(basePanel.listTechBase);
- }
-
- private void clearQuirks() {
- quirkPanel.cQuirkInclue.setSelectedIndex(0);
- quirkPanel.cQuirkExclude.setSelectedIndex(1);
- clearTriStateItem(quirkPanel.listQuirkType);
-
- quirkPanel.cWeaponQuirkInclue.setSelectedIndex(0);
- quirkPanel.cWeaponQuirkExclude.setSelectedIndex(1);
- clearTriStateItem(quirkPanel.listWeaponQuirkType);
- }
-
- /**
- * Clear the filter.
- */
public void clearValues() {
mekFilter = null;
unitTypePanel.clear();
- clearBase();
- transportsPanel.clearTransports();
- clearQuirks();
- weaponEqPanel.clearWeaponsEquipment();
+ basePanel.clear();
+ transportsPanel.clear();
+ quirkPanel.clear();
+ weaponEqPanel.clear();
}
public MekSearchFilter getMekSearchFilter() {
diff --git a/megamek/src/megamek/client/ui/advancedsearch/TransportsSearchTab.java b/megamek/src/megamek/client/ui/advancedsearch/TransportsSearchTab.java
index 1f9de13742..3b64d76aa6 100644
--- a/megamek/src/megamek/client/ui/advancedsearch/TransportsSearchTab.java
+++ b/megamek/src/megamek/client/ui/advancedsearch/TransportsSearchTab.java
@@ -22,7 +22,6 @@
import javax.swing.*;
import java.awt.*;
-import java.awt.event.ActionListener;
class TransportsSearchTab extends JPanel {
@@ -133,8 +132,8 @@ class TransportsSearchTab extends JPanel {
JTextField tStartNavalRepairFacilities = new JTextField(4);
JTextField tEndNavalRepairFacilities = new JTextField(4);
- TransportsSearchTab(ActionListener listener) {
- btnTransportsClear.addActionListener(listener);
+ TransportsSearchTab() {
+ btnTransportsClear.addActionListener(e -> clear());
GridBagConstraints c = new GridBagConstraints();
setLayout(new GridBagLayout());
@@ -339,7 +338,7 @@ class TransportsSearchTab extends JPanel {
add(blankPanel, c);
}
- void clearTransports() {
+ void clear() {
tStartTroopSpace.setText("");
tEndTroopSpace.setText("");
tStartASFBays.setText("");
diff --git a/megamek/src/megamek/client/ui/advancedsearch/WeaponClass.java b/megamek/src/megamek/client/ui/advancedsearch/WeaponClass.java
index 815f49d41b..37fe092897 100644
--- a/megamek/src/megamek/client/ui/advancedsearch/WeaponClass.java
+++ b/megamek/src/megamek/client/ui/advancedsearch/WeaponClass.java
@@ -1,3 +1,22 @@
+
+/*
+ * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
package megamek.client.ui.advancedsearch;
public enum WeaponClass {
@@ -156,7 +175,6 @@ public boolean matches(String name) {
} else if (this == BALLISTIC) {
return WeaponClass.AUTOCANNON.matches(name) ||
WeaponClass.GAUSS.matches(name) ||
- WeaponClass.MISSILE.matches(name) ||
WeaponClass.MACHINE_GUN.matches(name);
} else if (this == RAC) {
if (name.toLowerCase().contains("rotary")) {
diff --git a/megamek/src/megamek/client/ui/advancedsearch/WeaponClassFT.java b/megamek/src/megamek/client/ui/advancedsearch/WeaponClassFT.java
index 1e0ace9e48..5eaa09152a 100644
--- a/megamek/src/megamek/client/ui/advancedsearch/WeaponClassFT.java
+++ b/megamek/src/megamek/client/ui/advancedsearch/WeaponClassFT.java
@@ -1,6 +1,6 @@
package megamek.client.ui.advancedsearch;
-public class WeaponClassFT extends FilterTokens {
+public class WeaponClassFT extends EquipmentFilterToken {
public WeaponClass weaponClass;
public int qty;
diff --git a/megamek/src/megamek/client/ui/advancedsearch/WeaponSearchTab.java b/megamek/src/megamek/client/ui/advancedsearch/WeaponSearchTab.java
index fa60c28e05..f9cf4324db 100644
--- a/megamek/src/megamek/client/ui/advancedsearch/WeaponSearchTab.java
+++ b/megamek/src/megamek/client/ui/advancedsearch/WeaponSearchTab.java
@@ -18,52 +18,53 @@
*/
package megamek.client.ui.advancedsearch;
-import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.table.MegaMekTable;
import megamek.common.*;
+import megamek.common.annotations.Nullable;
import javax.swing.*;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
import javax.swing.table.TableColumn;
import javax.swing.table.TableRowSorter;
import java.awt.*;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
-import java.util.ArrayList;
-import java.util.Enumeration;
+import java.util.*;
import java.util.List;
-import java.util.Vector;
+import java.util.regex.PatternSyntaxException;
-public class WeaponSearchTab extends JPanel implements KeyListener, ListSelectionListener {
+public class WeaponSearchTab extends JPanel implements KeyListener, DocumentListener, FocusListener {
- final List filterToks = new ArrayList<>();
+ final List filterTokens = new ArrayList<>();
- final JLabel lblTableFilters = new JLabel(Messages.getString("MekSelectorDialog.Search.TableFilters"));
- final JButton btnWELeftParen = new JButton("(");
- final JButton btnWERightParen = new JButton(")");
- final JButton btnWEAdd = new JButton(Messages.getString("MekSelectorDialog.Search.add"));
- final JButton btnWEAnd = new JButton(Messages.getString("MekSelectorDialog.Search.and"));
- final JButton btnWEOr = new JButton(Messages.getString("MekSelectorDialog.Search.or"));
- final JButton btnWEClear = new JButton(Messages.getString("MekSelectorDialog.Reset"));
- final JButton btnWEBack = new JButton("Back");
- final JLabel lblWEEqExpTxt = new JLabel(Messages.getString("MekSelectorDialog.Search.FilterExpression"));
- final JTextArea txtWEEqExp = new JTextArea("");
+ final JButton btnLeftParen = new JButton("(");
+ final JButton btnRightParen = new JButton(")");
+ final JButton btnAdd = new JButton(Messages.getString("MekSelectorDialog.Search.add"));
+ final JButton btnAnd = new JButton(Messages.getString("MekSelectorDialog.Search.and"));
+ final JButton btnOr = new JButton(Messages.getString("MekSelectorDialog.Search.or"));
+ final JButton btnClear = new JButton(Messages.getString("MekSelectorDialog.Reset"));
+ final JButton btnBack = new JButton("Back");
+ final JLabel lblWEEqExpTxt = new JLabel(Messages.getString("MekSelectorDialog.Search.FilterExpression"));
+ final JTextArea txtWEEqExp = new JTextArea("", 2, 40);
final JScrollPane expWEScroller = new JScrollPane(txtWEEqExp,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+
+ final JLabel lblTableFilters = new JLabel(Messages.getString("MekSelectorDialog.Search.TableFilters"));
final JLabel lblUnitType = new JLabel(Messages.getString("MekSelectorDialog.Search.UnitType"));
final JLabel lblTechClass = new JLabel(Messages.getString("MekSelectorDialog.Search.TechClass"));
final JLabel lblTechLevelBase = new JLabel(Messages.getString("MekSelectorDialog.Search.TechLevel"));
final JComboBox cboUnitType = new JComboBox<>();
final JComboBox cboTechClass = new JComboBox<>();
final JComboBox cboTechLevel = new JComboBox<>();
- final JLabel lblWeaponClass = new JLabel(Messages.getString("MekSelectorDialog.Search.WeaponClass"));
- final JScrollPane scrTableWeaponType = new JScrollPane();
- final MegaMekTable tblWeaponType;
- final WeaponClassTableModel weaponTypesModel;
- final TableRowSorter weaponTypesSorter;
+ final JLabel tableFilterTextLabel = new JLabel(Messages.getString("MekSelectorDialog.Search.TableFilter"));
+ final JTextField tableFilterText = new JTextField(20);
+
final JLabel lblWeapons = new JLabel(Messages.getString("MekSelectorDialog.Search.Weapons"));
final JScrollPane scrTableWeapons = new JScrollPane();
final MegaMekTable tblWeapons;
@@ -76,21 +77,25 @@ public class WeaponSearchTab extends JPanel implements KeyListener, ListSelectio
final TableRowSorter equipmentSorter;
final JComboBox cboQty = new JComboBox<>();
+ final JLabel lblWeaponClass = new JLabel(Messages.getString("MekSelectorDialog.Search.WeaponClass"));
+ final JSpinner weaponClassCount;
+ final JComboBox weaponClassChooser;
+
+ JComponent focusedSelector = null;
+
private final TWAdvancedSearchPanel parentPanel;
WeaponSearchTab(TWAdvancedSearchPanel parentPanel) {
this.parentPanel = parentPanel;
- // Initialize Items
- btnWEAnd.addActionListener(parentPanel);
- btnWEAdd.addActionListener(parentPanel);
- btnWELeftParen.addActionListener(parentPanel);
- btnWERightParen.addActionListener(parentPanel);
- btnWEOr.addActionListener(parentPanel);
- btnWEClear.addActionListener(parentPanel);
- btnWEBack.addActionListener(parentPanel);
-
- btnWEBack.setEnabled(false);
- btnWEAdd.setEnabled(false);
+
+ btnAnd.addActionListener(e -> addFilterToken(new AndFilterToken()));
+ btnAdd.addActionListener(e -> addButtonPressed());
+ btnLeftParen.addActionListener(e -> addFilterToken(new LeftParensFilterToken()));
+ btnRightParen.addActionListener(e -> addFilterToken(new RightParensFilterToken()));
+ btnOr.addActionListener(e -> addFilterToken(new OrFilterToken()));
+ btnClear.addActionListener(e -> clear());
+ btnBack.addActionListener(e -> backOperation());
+ adaptTokenButtons();
for (int i = 1; i <= 20; i++) {
cboQty.addItem(Integer.toString(i));
@@ -109,7 +114,7 @@ public class WeaponSearchTab extends JPanel implements KeyListener, ListSelectio
unitTypeModel.setSelectedItem(Messages.getString("MekSelectorDialog.All"));
cboUnitType.setModel(unitTypeModel);
- cboUnitType.addActionListener(parentPanel);
+ cboUnitType.addActionListener(e -> filterTables());
DefaultComboBoxModel techLevelModel = new DefaultComboBoxModel<>();
@@ -119,7 +124,7 @@ public class WeaponSearchTab extends JPanel implements KeyListener, ListSelectio
techLevelModel.setSelectedItem(TechConstants.getLevelDisplayableName(TechConstants.SIZE - 1));
cboTechLevel.setModel(techLevelModel);
- cboTechLevel.addActionListener(parentPanel);
+ cboTechLevel.addActionListener(e -> filterTables());
DefaultComboBoxModel techClassModel = new DefaultComboBoxModel<>();
techClassModel.addElement("All");
@@ -129,37 +134,30 @@ public class WeaponSearchTab extends JPanel implements KeyListener, ListSelectio
techClassModel.addElement("(Unknown Technology Base)");
techClassModel.setSelectedItem("All");
cboTechClass.setModel(techClassModel);
- cboTechClass.addActionListener(parentPanel);
-
- // Set up Weapon Class table
- weaponTypesModel = new WeaponClassTableModel();
- tblWeaponType = new MegaMekTable(weaponTypesModel, WeaponClassTableModel.COL_NAME);
- TableColumn wpsTypeCol = tblWeaponType.getColumnModel().getColumn(WeaponClassTableModel.COL_QTY);
- wpsTypeCol.setCellEditor(new DefaultCellEditor(cboQty));
- tblWeaponType.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- weaponTypesSorter = new TableRowSorter<>(weaponTypesModel);
- tblWeaponType.setRowSorter(weaponTypesSorter);
- tblWeaponType.addKeyListener(this);
- tblWeaponType.setFont(new Font(MMConstants.FONT_MONOSPACED, Font.PLAIN, 12));
- tblWeaponType.getSelectionModel().addListSelectionListener(this);
-
- for (int i = 0; i < weaponTypesModel.getColumnCount(); i++) {
- tblWeaponType.getColumnModel().getColumn(i).setPreferredWidth(weaponTypesModel.getPreferredWidth(i));
- }
+ cboTechClass.addActionListener(e -> filterTables());
- scrTableWeaponType.setViewportView(tblWeaponType);
+ // Set up Weapon Class chooser
+ weaponClassCount = new JSpinner(new SpinnerNumberModel(1, 1, 20, 1));
+ weaponClassCount.addChangeListener(e->spinnerChange());
+ weaponClassChooser = new JComboBox<>(WeaponClass.values());
+ weaponClassChooser.addFocusListener(this);
// Setup Weapons Table
weaponsModel = new WeaponsTableModel(parentPanel);
- tblWeapons = new MegaMekTable(weaponsModel, WeaponsTableModel.COL_NAME);
+ tblWeapons = new MegaMekTable(weaponsModel, WeaponsTableModel.COL_NAME) {
+ @Override
+ public Dimension getPreferredScrollableViewportSize() {
+ Dimension standardSize = super.getPreferredScrollableViewportSize();
+ return new Dimension(standardSize.width, getRowHeight() * 6);
+ }
+ };
TableColumn wpsCol = tblWeapons.getColumnModel().getColumn(WeaponsTableModel.COL_QTY);
wpsCol.setCellEditor(new DefaultCellEditor(cboQty));
tblWeapons.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
weaponsSorter = new TableRowSorter<>(weaponsModel);
tblWeapons.setRowSorter(weaponsSorter);
tblWeapons.addKeyListener(this);
- tblWeapons.setFont(new Font(MMConstants.FONT_MONOSPACED, Font.PLAIN, 12));
- tblWeapons.getSelectionModel().addListSelectionListener(this);
+ tblWeapons.addFocusListener(this);
for (int i = 0; i < weaponsModel.getColumnCount(); i++) {
tblWeapons.getColumnModel().getColumn(i).setPreferredWidth(weaponsModel.getPreferredWidth(i));
@@ -169,15 +167,20 @@ public class WeaponSearchTab extends JPanel implements KeyListener, ListSelectio
// Setup Equipment Table
equipmentModel = new EquipmentTableModel(parentPanel);
- tblEquipment = new MegaMekTable(equipmentModel, EquipmentTableModel.COL_NAME);
+ tblEquipment = new MegaMekTable(equipmentModel, EquipmentTableModel.COL_NAME) {
+ @Override
+ public Dimension getPreferredScrollableViewportSize() {
+ Dimension standardSize = super.getPreferredScrollableViewportSize();
+ return new Dimension(standardSize.width, getRowHeight() * 6);
+ }
+ };
TableColumn eqCol = tblEquipment.getColumnModel().getColumn(EquipmentTableModel.COL_QTY);
eqCol.setCellEditor(new DefaultCellEditor(cboQty));
tblEquipment.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
equipmentSorter = new TableRowSorter<>(equipmentModel);
tblEquipment.setRowSorter(equipmentSorter);
tblEquipment.addKeyListener(this);
- tblEquipment.setFont(new Font(MMConstants.FONT_MONOSPACED, Font.PLAIN, 12));
- tblEquipment.getSelectionModel().addListSelectionListener(this);
+ tblEquipment.addFocusListener(this);
for (int i = 0; i < equipmentModel.getColumnCount(); i++) {
tblEquipment.getColumnModel().getColumn(i).setPreferredWidth(equipmentModel.getPreferredWidth(i));
@@ -206,98 +209,104 @@ public class WeaponSearchTab extends JPanel implements KeyListener, ListSelectio
txtWEEqExp.setLineWrap(true);
txtWEEqExp.setWrapStyleWord(true);
- setLayout(new GridBagLayout());
- GridBagConstraints c = new GridBagConstraints();
-
- c.weighty = 0;
- c.anchor = GridBagConstraints.NORTHWEST;
- c.fill = GridBagConstraints.NONE;
- c.insets = new Insets(0, 0, 0, 0);
- c.gridx = 0; c.gridy++;
- add(lblTableFilters, c);
- c.gridx = 0; c.gridy++;
- c.gridwidth = 4;
- c.anchor = GridBagConstraints.CENTER;
- c.insets = new Insets(0, 40, 0, 0);
- JPanel cboPanel = new JPanel();
- cboPanel.add(lblUnitType);
- cboPanel.add(cboUnitType);
- cboPanel.add(lblTechClass);
- cboPanel.add(cboTechClass);
- cboPanel.add(lblTechLevelBase, c);
- cboPanel.add(cboTechLevel, c);
- add(cboPanel, c);
- c.gridwidth = 1;
-
- c.gridx = 0; c.gridy++;
- c.anchor = GridBagConstraints.WEST;
- c.insets = new Insets(0, 0, 0, 0);
- add(lblWeaponClass, c);
-
- c.fill = GridBagConstraints.HORIZONTAL;
- c.anchor = GridBagConstraints.CENTER;
- c.gridwidth = 5;
- c.gridx = 0; c.gridy++;
- add(scrTableWeaponType, c);
- c.gridwidth = 1;
-
- c.fill = GridBagConstraints.NONE;
- c.gridx = 0; c.gridy++;
- c.anchor = GridBagConstraints.WEST;
- add(lblWeapons, c);
-
- c.fill = GridBagConstraints.HORIZONTAL;
- c.anchor = GridBagConstraints.CENTER;
- c.gridwidth = 5;
- c.gridx = 0; c.gridy++;
- add(scrTableWeapons, c);
-
- c.fill = GridBagConstraints.NONE;
- c.gridwidth = 1;
- c.gridx = 0; c.gridy++;
- c.anchor = GridBagConstraints.WEST;
- add(lblEquipment, c);
-
- c.fill = GridBagConstraints.HORIZONTAL;
- c.anchor = GridBagConstraints.CENTER;
- c.gridwidth = 5;
- c.gridx = 0; c.gridy++;
- add(scrTableEquipment, c);
-
- c.insets = new Insets(0, 50, 0, 0);
- c.fill = GridBagConstraints.NONE;
- c.gridx = 0; c.gridy++;
- c.gridwidth = 4;
+ tableFilterText.getDocument().addDocumentListener(this);
+
+ JPanel upperPanel = new JPanel();
+ upperPanel.setLayout(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ gbc.weighty = 0;
+ gbc.anchor = GridBagConstraints.NORTHWEST;
+ gbc.fill = GridBagConstraints.NONE;
+ gbc.insets = new Insets(0, 0, 0, 0);
+ gbc.gridy = 0;
+ upperPanel.add(lblTableFilters, gbc);
+ gbc.gridy++;
+ gbc.gridwidth = 4;
+ gbc.anchor = GridBagConstraints.CENTER;
+ JPanel tableTechFilterPanel = new JPanel();
+ tableTechFilterPanel.add(lblUnitType);
+ tableTechFilterPanel.add(cboUnitType);
+ tableTechFilterPanel.add(lblTechClass);
+ tableTechFilterPanel.add(cboTechClass);
+ tableTechFilterPanel.add(lblTechLevelBase);
+ tableTechFilterPanel.add(cboTechLevel);
+ upperPanel.add(tableTechFilterPanel, gbc);
+
+ gbc.gridy++;
+ JPanel tableTextFilterPanel = new JPanel();
+ tableTextFilterPanel.add(tableFilterTextLabel);
+ tableTextFilterPanel.add(tableFilterText);
+ upperPanel.add(tableTextFilterPanel, gbc);
+
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(0, 0, 0, 0);
+ gbc.fill = GridBagConstraints.NONE;
+ gbc.gridy++;
+ gbc.anchor = GridBagConstraints.WEST;
+ upperPanel.add(lblWeapons, gbc);
+
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ gbc.anchor = GridBagConstraints.CENTER;
+ gbc.gridwidth = 5;
+ gbc.gridy++;
+ upperPanel.add(scrTableWeapons, gbc);
+
+ gbc.gridy++;
+ upperPanel.add(Box.createVerticalStrut(20), gbc);
+
+ gbc.fill = GridBagConstraints.NONE;
+ gbc.gridwidth = 1;
+ gbc.gridy++;
+ gbc.anchor = GridBagConstraints.WEST;
+ upperPanel.add(lblEquipment, gbc);
+
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ gbc.anchor = GridBagConstraints.CENTER;
+ gbc.gridwidth = 5;
+ gbc.gridy++;
+ upperPanel.add(scrTableEquipment, gbc);
+
+ gbc.gridy++;
+ upperPanel.add(Box.createVerticalStrut(20), gbc);
+
+ gbc.gridwidth = 1;
+ gbc.gridy++;
+ gbc.anchor = GridBagConstraints.WEST;
+ gbc.insets = new Insets(0, 0, 0, 20);
+ upperPanel.add(lblWeaponClass, gbc);
+ gbc.gridy++;
+ upperPanel.add(weaponClassCount, gbc);
+ upperPanel.add(weaponClassChooser, gbc);
+
JPanel btnPanel = new JPanel();
- btnPanel.add(btnWEAdd, c);
- btnPanel.add(btnWELeftParen, c);
- btnPanel.add(btnWERightParen, c);
- btnPanel.add(btnWEAnd, c);
- btnPanel.add(btnWEOr, c);
- btnPanel.add(btnWEBack, c);
- btnPanel.add(btnWEClear, c);
- add(btnPanel, c);
-
- // Filter Expression
- c.insets = new Insets(0, 0, 0, 0);
- c.gridx = 0; c.gridy++;
- c.gridwidth = 1;
- c.anchor = GridBagConstraints.WEST;
- c.fill = GridBagConstraints.NONE;
- add(lblWEEqExpTxt, c);
- c.anchor = GridBagConstraints.CENTER;
- c.fill = GridBagConstraints.HORIZONTAL;
- c.gridx = 1;
- c.gridwidth = 3;
- add(expWEScroller, c);
- c.weighty = 1;
- JPanel blankPanel = new JPanel();
- add(blankPanel, c);
+ btnPanel.add(btnAdd);
+ btnPanel.add(btnLeftParen);
+ btnPanel.add(btnRightParen);
+ btnPanel.add(btnAnd);
+ btnPanel.add(btnOr);
+ btnPanel.add(btnBack);
+ btnPanel.add(btnClear);
+
+ Box filterExpressionPanel = Box.createHorizontalBox();
+ filterExpressionPanel.setBorder(new EmptyBorder(0, 20, 0, 20));
+ filterExpressionPanel.add(lblWEEqExpTxt);
+ filterExpressionPanel.add(Box.createHorizontalStrut(20));
+ filterExpressionPanel.add(expWEScroller);
+
+ Box filterAssemblyPanel = Box.createVerticalBox();
+ filterAssemblyPanel.add(Box.createVerticalStrut(10));
+ filterAssemblyPanel.add(btnPanel);
+ filterAssemblyPanel.add(filterExpressionPanel);
+ filterAssemblyPanel.add(Box.createVerticalStrut(10));
+
+ setLayout(new BorderLayout());
+ add(new TWAdvancedSearchPanel.StandardScrollPane(upperPanel), BorderLayout.CENTER);
+ add(filterAssemblyPanel, BorderLayout.PAGE_END);
}
void filterTables() {
RowFilter weaponFilter;
- RowFilter equipmentFilter;
final int techLevel = cboTechLevel.getSelectedIndex();
final String techClass = (String) cboTechClass.getSelectedItem();
final int unitType = cboUnitType.getSelectedIndex() - 1;
@@ -313,14 +322,17 @@ public boolean include(Entry extends WeaponsTableModel, ? extends Integer> ent
boolean techLvlMatch = matchTechLvl(techLevel, wp.getTechLevel(parentPanel.gameYear));
boolean techClassMatch = matchTechClass(techClass, currTechClass);
boolean unitTypeMatch = matchUnitType(unitType, wp);
- return techLvlMatch && techClassMatch && unitTypeMatch;
+ boolean textFilterMatch = (tableFilterText.getText() == null) || (tableFilterText.getText().length() < 2)
+ || matchWeaponTextFilter(entry, WeaponsTableModel.COL_NAME);
+ return techLvlMatch && techClassMatch && unitTypeMatch && textFilterMatch;
}
};
- } catch (java.util.regex.PatternSyntaxException ignored) {
+ } catch (PatternSyntaxException ignored) {
return;
}
weaponsSorter.setRowFilter(weaponFilter);
+ RowFilter equipmentFilter;
try {
equipmentFilter = new RowFilter<>() {
@Override
@@ -331,24 +343,23 @@ public boolean include(Entry extends EquipmentTableModel, ? extends Integer> e
boolean techLvlMatch = matchTechLvl(techLevel, eq.getTechLevel(parentPanel.gameYear));
boolean techClassMatch = matchTechClass(techClass, currTechClass);
boolean unitTypeMatch = matchUnitType(unitType, eq);
- return techLvlMatch && techClassMatch && unitTypeMatch;
+ boolean textFilterMatch = (tableFilterText.getText() == null) || (tableFilterText.getText().length() < 2)
+ || matchEquipmentTextFilter(entry, EquipmentTableModel.COL_NAME);
+ return techLvlMatch && techClassMatch && unitTypeMatch && textFilterMatch;
}
};
- } catch (java.util.regex.PatternSyntaxException ignored) {
+ } catch (PatternSyntaxException ignored) {
return;
}
equipmentSorter.setRowFilter(equipmentFilter);
}
-
- void clearWeaponsEquipment() {
- filterToks.clear();
+ void clear() {
+ filterTokens.clear();
tblWeapons.clearSelection();
tblEquipment.clearSelection();
txtWEEqExp.setText("");
- btnWEBack.setEnabled(false);
- disableOperationButtons();
- enableSelectionButtons();
+ adaptTokenButtons();
}
/**
@@ -357,8 +368,8 @@ void clearWeaponsEquipment() {
* and equipment tables.
*/
private void populateWeaponsAndEquipmentChoices() {
- Vector weapons = new Vector<>();
- Vector equipment = new Vector<>();
+ List weapons = new ArrayList<>();
+ List equipment = new ArrayList<>();
for (Enumeration e = EquipmentType.getAllTypes(); e.hasMoreElements();) {
EquipmentType et = e.nextElement();
@@ -388,7 +399,7 @@ public void keyTyped(KeyEvent evt) {
char keyChar = evt.getKeyChar();
// Ensure we've got a number or letter pressed
if (!(((keyChar >= '0') && (keyChar <= '9')) ||
- ((keyChar >= 'a') && (keyChar <='z')) || (keyChar == ' '))) {
+ ((keyChar >= 'a') && (keyChar <= 'z')) || (keyChar == ' '))) {
return;
}
@@ -399,7 +410,6 @@ public void keyTyped(KeyEvent evt) {
}
}
-
private boolean matchTechClass(String t1, String t2) {
if (t1.equals("All")) {
return true;
@@ -418,14 +428,12 @@ private boolean matchUnitType(int unitTypeFilter, EquipmentType eq) {
switch (unitTypeFilter) {
case 5:
- if (eq.hasFlag(WeaponType.F_AERO_WEAPON)
- || eq.hasFlag(MiscType.F_FIGHTER_EQUIPMENT)) {
+ if (eq.hasFlag(WeaponType.F_AERO_WEAPON) || eq.hasFlag(MiscType.F_FIGHTER_EQUIPMENT)) {
return true;
}
break;
case UnitType.BATTLE_ARMOR:
- if (eq.hasFlag(WeaponType.F_BA_WEAPON)
- || eq.hasFlag(MiscType.F_BA_EQUIPMENT)) {
+ if (eq.hasFlag(WeaponType.F_BA_WEAPON) || eq.hasFlag(MiscType.F_BA_EQUIPMENT)) {
return true;
}
break;
@@ -435,20 +443,17 @@ private boolean matchUnitType(int unitTypeFilter, EquipmentType eq) {
}
break;
case UnitType.MEK:
- if (eq.hasFlag(WeaponType.F_MEK_WEAPON)
- || eq.hasFlag(MiscType.F_MEK_EQUIPMENT)) {
+ if (eq.hasFlag(WeaponType.F_MEK_WEAPON) || eq.hasFlag(MiscType.F_MEK_EQUIPMENT)) {
return true;
}
break;
case UnitType.TANK:
- if (eq.hasFlag(WeaponType.F_TANK_WEAPON)
- || eq.hasFlag(MiscType.F_TANK_EQUIPMENT)) {
+ if (eq.hasFlag(WeaponType.F_TANK_WEAPON) || eq.hasFlag(MiscType.F_TANK_EQUIPMENT)) {
return true;
}
break;
case UnitType.PROTOMEK:
- if (eq.hasFlag(WeaponType.F_PROTO_WEAPON)
- || eq.hasFlag(MiscType.F_PROTOMEK_EQUIPMENT)) {
+ if (eq.hasFlag(WeaponType.F_PROTO_WEAPON) || eq.hasFlag(MiscType.F_PROTOMEK_EQUIPMENT)) {
return true;
}
break;
@@ -458,93 +463,15 @@ private boolean matchUnitType(int unitTypeFilter, EquipmentType eq) {
return false;
}
- @Override
- public void valueChanged(ListSelectionEvent evt) {
- boolean lastTokIsOperation;
- int tokSize = filterToks.size();
- lastTokIsOperation = ((tokSize == 0) ||
- (filterToks.get(tokSize - 1) instanceof OperationFT));
- if (evt.getSource().equals(tblWeapons.getSelectionModel())) {
- if ((tblWeapons.getSelectedRow() >= 0) && lastTokIsOperation) {
- tblEquipment.clearSelection();
- tblWeaponType.clearSelection();
- btnWEAdd.setEnabled(true);
- } else if (tblWeapons.getSelectedRow() >= 0) {
- tblEquipment.clearSelection();
- tblWeaponType.clearSelection();
- }
- } else if (evt.getSource().equals(tblEquipment.getSelectionModel())) {
- if ((tblEquipment.getSelectedRow() >= 0) && lastTokIsOperation) {
- tblWeapons.clearSelection();
- tblWeaponType.clearSelection();
- btnWEAdd.setEnabled(true);
- } else if (tblEquipment.getSelectedRow() >= 0) {
- tblWeapons.clearSelection();
- tblWeaponType.clearSelection();
- }
- } else if (evt.getSource().equals(tblWeaponType.getSelectionModel())) {
- if ((tblWeaponType.getSelectedRow() >= 0) && lastTokIsOperation) {
- tblWeapons.clearSelection();
- tblEquipment.clearSelection();
- btnWEAdd.setEnabled(true);
- } else if (tblWeaponType.getSelectedRow() >= 0) {
- tblWeapons.clearSelection();
- tblEquipment.clearSelection();
- }
- }
- }
-
+ // Build the string representation of the new expression
String filterExpressionString() {
- // Build the string representation of the new expression
StringBuilder filterExp = new StringBuilder();
- for (int i = 0; i < filterToks.size(); i++) {
- filterExp.append(" ").append(filterToks.get(i).toString()).append(" ");
+ for (FilterToken filterTok : filterTokens) {
+ filterExp.append(" ").append(filterTok.toString()).append(" ");
}
return filterExp.toString();
}
- /**
- * Convenience method for enabling the buttons related to weapon/equipment
- * selection for filtering (btnAddEquipment, btnAddWeapon, etc)
- */
- void enableSelectionButtons() {
- if ((tblWeapons.getSelectedRow() != -1) ||
- (tblEquipment.getSelectedRow() != -1) ||
- (tblWeaponType.getSelectedRow() != -1)) {
- btnWEAdd.setEnabled(true);
- }
- btnWELeftParen.setEnabled(true);
- }
-
- /**
- * Convenience method for disabling the buttons related to weapon/equipment
- * selection for filtering (btnAddEquipment, btnAddWeapon, etc)
- */
- void disableSelectionButtons() {
- btnWEAdd.setEnabled(false);
- btnWELeftParen.setEnabled(false);
- }
-
- /**
- * Convenience method for enabling the buttons related to filter operations
- * for filtering (btnAnd, btnOr, etc)
- */
- void enableOperationButtons() {
- btnWEOr.setEnabled(true);
- btnWEAnd.setEnabled(true);
- btnWERightParen.setEnabled(true);
- }
-
- /**
- * Convenience method for disabling the buttons related to filter operations
- * for filtering (btnAnd, btnOr, etc)
- */
- void disableOperationButtons() {
- btnWEOr.setEnabled(false);
- btnWEAnd.setEnabled(false);
- btnWERightParen.setEnabled(false);
- }
-
private boolean matchTechLvl(int t1, int t2) {
return ((t1 == TechConstants.T_ALL) || (t1 == t2)
|| ((t1 == TechConstants.T_IS_TW_ALL) && (t2 <= TechConstants.T_IS_TW_NON_BOX)))
@@ -562,4 +489,125 @@ private boolean matchTechLvl(int t1, int t2) {
|| (t2 == TechConstants.T_CLAN_EXPERIMENTAL)
|| (t2 == TechConstants.T_CLAN_UNOFFICIAL)));
}
+
+ private void addButtonPressed() {
+ if ((focusedSelector == tblEquipment) && (tblEquipment.getSelectedRow() != -1)) {
+ int row = tblEquipment.getSelectedRow();
+ String internalName = (String) tblEquipment.getModel().getValueAt(
+ tblEquipment.convertRowIndexToModel(row),
+ EquipmentTableModel.COL_INTERNAL_NAME);
+ String fullName = (String) tblEquipment.getValueAt(row, EquipmentTableModel.COL_NAME);
+ int qty = Integer.parseInt((String) tblEquipment.getValueAt(row, EquipmentTableModel.COL_QTY));
+ filterTokens.add(new EquipmentTypeFT(internalName, fullName, qty));
+
+ } else if ((focusedSelector == tblWeapons) && (tblWeapons.getSelectedRow() != -1)) {
+ int row = tblWeapons.getSelectedRow();
+ String internalName = (String) tblWeapons.getModel().getValueAt(
+ tblWeapons.convertRowIndexToModel(row),
+ WeaponsTableModel.COL_INTERNAL_NAME);
+ String fullName = (String) tblWeapons.getValueAt(row, WeaponsTableModel.COL_NAME);
+ int qty = Integer.parseInt((String) tblWeapons.getValueAt(row, WeaponsTableModel.COL_QTY));
+ filterTokens.add(new EquipmentTypeFT(internalName, fullName, qty));
+
+ } else if ((focusedSelector == weaponClassChooser) && (weaponClassChooser.getSelectedItem() != null)) {
+ int qty = (int) weaponClassCount.getValue();
+ filterTokens.add(new WeaponClassFT((WeaponClass) weaponClassChooser.getSelectedItem(), qty));
+
+ } else {
+ // if something else is focused, do nothing
+ return;
+ }
+ txtWEEqExp.setText(filterExpressionString());
+ adaptTokenButtons();
+ }
+
+ private boolean matchWeaponTextFilter(RowFilter.Entry extends WeaponsTableModel, ? extends Integer> entry, int column) {
+ String wp = entry.getModel().getValueAt(entry.getIdentifier(), column).toString();
+ return matchTextFilter(wp);
+ }
+
+ private boolean matchEquipmentTextFilter(RowFilter.Entry extends EquipmentTableModel, ? extends Integer> entry, int column) {
+ String wp = entry.getModel().getValueAt(entry.getIdentifier(), column).toString();
+ return matchTextFilter(wp);
+ }
+
+ private boolean matchTextFilter(String tableText) {
+ return tableText.toLowerCase(Locale.ROOT).contains(tableFilterText.getText().toLowerCase(Locale.ROOT));
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ filterTables();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ filterTables();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ filterTables();
+ }
+
+ @Override
+ public void focusGained(FocusEvent e) {
+ if ((e.getSource() == tblEquipment) || (e.getSource() == tblWeapons)) {
+ focusedSelector = (JComponent) e.getSource();
+ adaptTokenButtons();
+ } else if (e.getSource() == weaponClassChooser) {
+ focusWeaponClasschooser();
+ }
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) { }
+
+ private void spinnerChange() {
+ focusWeaponClasschooser();
+ }
+
+ private void focusWeaponClasschooser() {
+ focusedSelector = weaponClassChooser;
+ tblWeapons.clearSelection();
+ tblEquipment.clearSelection();
+ adaptTokenButtons();
+ }
+
+ private @Nullable FilterToken lastToken() {
+ return filterTokens.isEmpty() ? null : filterTokens.get(filterTokens.size() - 1);
+ }
+
+ private boolean hasFocusedSelector() {
+ return (focusedSelector == weaponClassChooser) || (focusedSelector == tblEquipment) || (focusedSelector == tblWeapons);
+ }
+
+ void adaptTokenButtons() {
+ btnBack.setEnabled(!filterTokens.isEmpty());
+ btnClear.setEnabled(!filterTokens.isEmpty());
+
+ boolean canAddEquipment = filterTokens.isEmpty() || (lastToken() instanceof OperatorFT)
+ || (lastToken() instanceof LeftParensFilterToken);
+ btnAdd.setEnabled(hasFocusedSelector() && canAddEquipment);
+ btnLeftParen.setEnabled(canAddEquipment);
+
+ boolean canAddOperator = (lastToken() instanceof EquipmentFilterToken) || (lastToken() instanceof RightParensFilterToken);
+ btnAnd.setEnabled(canAddOperator);
+ btnOr.setEnabled(canAddOperator);
+ btnRightParen.setEnabled(canAddOperator);
+ }
+
+ private void addFilterToken(FilterToken token) {
+ filterTokens.add(token);
+ txtWEEqExp.setText(filterExpressionString());
+ adaptTokenButtons();
+ }
+
+ private void backOperation() {
+ if (!filterTokens.isEmpty()) {
+ filterTokens.remove(filterTokens.size() - 1);
+ txtWEEqExp.setText(filterExpressionString());
+ adaptTokenButtons();
+ }
+ }
}
diff --git a/megamek/src/megamek/client/ui/advancedsearch/WeaponsTableModel.java b/megamek/src/megamek/client/ui/advancedsearch/WeaponsTableModel.java
index 7e6e79a297..04bfe77469 100644
--- a/megamek/src/megamek/client/ui/advancedsearch/WeaponsTableModel.java
+++ b/megamek/src/megamek/client/ui/advancedsearch/WeaponsTableModel.java
@@ -22,8 +22,9 @@
import megamek.common.WeaponType;
import javax.swing.table.AbstractTableModel;
+import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Vector;
+import java.util.List;
/**
* A table model for displaying weapons
@@ -45,7 +46,7 @@ public class WeaponsTableModel extends AbstractTableModel {
private final TWAdvancedSearchPanel twAdvancedSearchPanel;
private int[] qty;
- private Vector weapons = new Vector<>();
+ private List weapons = new ArrayList<>();
public WeaponsTableModel(TWAdvancedSearchPanel twAdvancedSearchPanel) {
this.twAdvancedSearchPanel = twAdvancedSearchPanel;
@@ -98,8 +99,7 @@ public boolean isCellEditable(int row, int col) {
return col == COL_QTY;
}
- // fill table with values
- public void setData(Vector wps) {
+ public void setData(List wps) {
weapons = wps;
qty = new int[wps.size()];
Arrays.fill(qty, 1);
@@ -107,7 +107,7 @@ public void setData(Vector wps) {
}
public WeaponType getWeaponTypeAt(int row) {
- return weapons.elementAt(row);
+ return weapons.get(row);
}
@Override
@@ -115,7 +115,7 @@ public Object getValueAt(int row, int col) {
if (row >= weapons.size()) {
return null;
}
- WeaponType wp = weapons.elementAt(row);
+ WeaponType wp = weapons.get(row);
return switch (col) {
case COL_QTY -> qty[row] + "";
case COL_NAME -> wp.getName();
diff --git a/megamek/src/megamek/common/MekSearchFilter.java b/megamek/src/megamek/common/MekSearchFilter.java
index b3c86d9e5e..073ac85774 100644
--- a/megamek/src/megamek/common/MekSearchFilter.java
+++ b/megamek/src/megamek/common/MekSearchFilter.java
@@ -21,7 +21,6 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Vector;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -232,7 +231,7 @@ public MekSearchFilter(MekSearchFilter sf) {
/**
* Creates an Expressiontree from a collection of tokens.
*/
- public void createFilterExpressionFromTokens(List toks) throws FilterParsingException {
+ public void createFilterExpressionFromTokens(List toks) throws FilterParsingException {
equipmentCriteria = new ExpressionTree();
if (!toks.isEmpty()) {
equipmentCriteria.root = createFTFromTokensRecursively(toks.iterator(), null);
@@ -242,14 +241,14 @@ public void createFilterExpressionFromTokens(List toks) throws Fil
}
}
- private ExpNode createFTFromTokensRecursively(Iterator toks,
+ private ExpNode createFTFromTokensRecursively(Iterator toks,
ExpNode currNode) {
// Base case. We're out of tokens, so we're done.
if (!toks.hasNext()) {
return currNode;
}
- FilterTokens filterTok = toks.next();
+ FilterToken filterTok = toks.next();
// Parsing Parenthesis
if (filterTok instanceof ParensFT) {
@@ -273,8 +272,8 @@ private ExpNode createFTFromTokensRecursively(Iterator toks,
}
// Parsing an Operation
- if (filterTok instanceof OperationFT) {
- OperationFT ft = (OperationFT) filterTok;
+ if (filterTok instanceof OperatorFT) {
+ OperatorFT ft = (OperatorFT) filterTok;
ExpNode newNode = new ExpNode();
// If currNode is null, we came from a right paren
if (currNode == null) {
@@ -317,11 +316,11 @@ private ExpNode createFTFromTokensRecursively(Iterator toks,
}
// Parsing an Operand
- if (filterTok instanceof EquipmentFT) {
+ if (filterTok instanceof EquipmentTypeFT) {
if (currNode == null) {
currNode = new ExpNode();
}
- EquipmentFT ft = (EquipmentFT) filterTok;
+ EquipmentTypeFT ft = (EquipmentTypeFT) filterTok;
ExpNode newChild = new ExpNode(ft.internalName, ft.qty);
currNode.children.add(newChild);
return createFTFromTokensRecursively(toks, currNode);