/* * MegaMekLab - Copyright (C) 2008 * * Original author - jtighe (torren@users.sourceforge.net) * * This program 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 2 of the License, or (at your option) * any later version. * * This program 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. */ package megameklab.com.ui.Infantry.views; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Comparator; import java.util.Enumeration; import javax.swing.ButtonGroup; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.RowFilter; import javax.swing.RowSorter; import javax.swing.SortOrder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.table.TableColumn; import javax.swing.table.TableRowSorter; import megamek.common.EquipmentType; import megamek.common.WeaponType; import megamek.common.weapons.infantry.InfantryWeapon; import megameklab.com.ui.EntitySource; import megameklab.com.util.EquipmentTableModel; import megameklab.com.util.IView; import megameklab.com.util.RefreshListener; import megameklab.com.util.UnitUtil; import megameklab.com.util.XTableColumnModel; public class WeaponView extends IView implements ActionListener { /** * */ private static final long serialVersionUID = 3978675469713289404L; private static final int T_ARCHAIC = 0; private static final int T_PERSONAL = 1; private static final int T_SUPPORT = 2; private static final int T_WEAPON = 3; private static final int T_NUM = 4; private RefreshListener refresh; private JButton addPrimaryButton = new JButton("Add Primary"); private JButton addSecondaryButton = new JButton("Add Secondary"); private JComboBox<String> choiceType = new JComboBox<String>(); private JTextField txtFilter = new JTextField(); private JRadioButton rbtnStats = new JRadioButton("Stats"); private JRadioButton rbtnFluff = new JRadioButton("Fluff"); private TableRowSorter<EquipmentTableModel> equipmentSorter; private EquipmentTableModel masterEquipmentList; private JTable masterEquipmentTable = new JTable(); private JScrollPane masterEquipmentScroll = new JScrollPane(); private String ADDP_COMMAND = "ADDPRIMARY"; private String ADDS_COMMAND = "ADDSECONDARY"; public static String getTypeName(int type) { switch(type) { case T_WEAPON: return "All Weapons"; case T_ARCHAIC: return "Archaic Weapons"; case T_PERSONAL: return "Personal Weapons"; case T_SUPPORT: return "Support Weapons"; default: return "?"; } } public WeaponView(EntitySource eSource) { super(eSource); masterEquipmentList = new EquipmentTableModel(eSource.getEntity()); masterEquipmentTable.setModel(masterEquipmentList); masterEquipmentTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); equipmentSorter = new TableRowSorter<EquipmentTableModel>(masterEquipmentList); equipmentSorter.setComparator(EquipmentTableModel.COL_DAMAGE, new WeaponDamageSorter()); equipmentSorter.setComparator(EquipmentTableModel.COL_COST, new FormattedNumberSorter()); masterEquipmentTable.setRowSorter(equipmentSorter); ArrayList<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>(); sortKeys.add(new RowSorter.SortKey(EquipmentTableModel.COL_NAME, SortOrder.ASCENDING)); equipmentSorter.setSortKeys(sortKeys); XTableColumnModel equipColumnModel = new XTableColumnModel(); masterEquipmentTable.setColumnModel(equipColumnModel); masterEquipmentTable.createDefaultColumnsFromModel(); TableColumn column = null; for (int i = 0; i < EquipmentTableModel.N_COL; i++) { column = masterEquipmentTable.getColumnModel().getColumn(i); column.setPreferredWidth(masterEquipmentList.getColumnWidth(i)); column.setCellRenderer(masterEquipmentList.getRenderer()); } masterEquipmentTable.setIntercellSpacing(new Dimension(0, 0)); masterEquipmentTable.setShowGrid(false); masterEquipmentTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); masterEquipmentTable.setDoubleBuffered(true); masterEquipmentScroll.setViewportView(masterEquipmentTable); masterEquipmentTable.getSelectionModel().addListSelectionListener(new javax.swing.event.ListSelectionListener() { public void valueChanged(javax.swing.event.ListSelectionEvent evt) { int view = masterEquipmentTable.getSelectedRow(); if(view < 0) { //selection got filtered away return; } int selected = masterEquipmentTable.convertRowIndexToModel(view); EquipmentType equip = masterEquipmentList.getType(selected); if(equip.hasFlag(WeaponType.F_INF_SUPPORT)) { addPrimaryButton.setEnabled(false); } else { addPrimaryButton.setEnabled(true); } } }); masterEquipmentScroll.setMinimumSize(new Dimension(200,200)); masterEquipmentScroll.setPreferredSize(new Dimension(200,200)); Enumeration<EquipmentType> miscTypes = EquipmentType.getAllTypes(); ArrayList<EquipmentType> allTypes = new ArrayList<EquipmentType>(); while (miscTypes.hasMoreElements()) { EquipmentType eq = miscTypes.nextElement(); if(eq instanceof InfantryWeapon) { allTypes.add(eq); } } masterEquipmentList.setData(allTypes); DefaultComboBoxModel<String> typeModel = new DefaultComboBoxModel<String>(); for (int i = 0; i < T_NUM; i++) { typeModel.addElement(getTypeName(i)); } choiceType.setModel(typeModel); choiceType.setSelectedIndex(1); choiceType.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { filterEquipment(); } }); txtFilter.setText(""); txtFilter.setMinimumSize(new java.awt.Dimension(200, 28)); txtFilter.setPreferredSize(new java.awt.Dimension(200, 28)); txtFilter.getDocument().addDocumentListener(new DocumentListener() { public void changedUpdate(DocumentEvent e) { filterEquipment(); } public void insertUpdate(DocumentEvent e) { filterEquipment(); } public void removeUpdate(DocumentEvent e) { filterEquipment(); } }); ButtonGroup bgroupView = new ButtonGroup(); bgroupView.add(rbtnStats); bgroupView.add(rbtnFluff); rbtnStats.setSelected(true); rbtnStats.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { setEquipmentView(); } }); rbtnFluff.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { setEquipmentView(); } }); JPanel viewPanel = new JPanel(new GridLayout(0,2)); viewPanel.add(rbtnStats); viewPanel.add(rbtnFluff); setEquipmentView(); JPanel btnPanel = new JPanel(new GridLayout(0,2)); btnPanel.add(addPrimaryButton); btnPanel.add(addSecondaryButton); //layout GridBagConstraints gbc; gbc = new GridBagConstraints(); JPanel databasePanel = new JPanel(new GridBagLayout()); gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 3; gbc.anchor = GridBagConstraints.WEST; databasePanel.add(btnPanel, gbc); gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 1; databasePanel.add(choiceType, gbc); gbc.gridx = 1; gbc.gridy = 1; databasePanel.add(txtFilter, gbc); gbc.gridx = 2; gbc.gridy = 1; gbc.weightx = 1.0; databasePanel.add(viewPanel, gbc); gbc.insets = new Insets(2,0,0,0); gbc.gridx = 0; gbc.gridy = 2; gbc.gridwidth = 3; gbc.fill = java.awt.GridBagConstraints.BOTH; gbc.weightx = 1.0; gbc.weighty = 1.0; databasePanel.add(masterEquipmentScroll, gbc); setLayout(new BorderLayout()); this.add(databasePanel, BorderLayout.CENTER); } public void addRefreshedListener(RefreshListener l) { refresh = l; } public void refresh() { removeAllListeners(); filterEquipment(); if(getInfantry().getSecondaryN() > 0) { addSecondaryButton.setEnabled(true); } else { addSecondaryButton.setEnabled(false); } addAllListeners(); } private void removeAllListeners() { addPrimaryButton.removeActionListener(this); addSecondaryButton.removeActionListener(this); } private void addAllListeners() { addPrimaryButton.addActionListener(this); addSecondaryButton.addActionListener(this); addPrimaryButton.setActionCommand(ADDP_COMMAND); addSecondaryButton.setActionCommand(ADDS_COMMAND); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals(ADDP_COMMAND) || e.getActionCommand().equals(ADDS_COMMAND)) { boolean isSecondary = e.getActionCommand().equals(ADDS_COMMAND); int view = masterEquipmentTable.getSelectedRow(); if(view < 0) { //selection got filtered away return; } int selected = masterEquipmentTable.convertRowIndexToModel(view); EquipmentType equip = masterEquipmentList.getType(selected); if(equip instanceof InfantryWeapon) { UnitUtil.replaceMainWeapon(getInfantry(), (InfantryWeapon) equip, isSecondary); } } else { return; } refresh.refreshAll(); } private void filterEquipment() { RowFilter<EquipmentTableModel, Integer> equipmentTypeFilter = null; final int nType = choiceType.getSelectedIndex(); equipmentTypeFilter = new RowFilter<EquipmentTableModel,Integer>() { @Override public boolean include(Entry<? extends EquipmentTableModel, ? extends Integer> entry) { EquipmentTableModel equipModel = entry.getModel(); EquipmentType etype = equipModel.getType(entry.getIdentifier()); if(!(etype instanceof InfantryWeapon)) { return false; } InfantryWeapon weapon = (InfantryWeapon)etype; if(!UnitUtil.isLegal(getInfantry(), etype.getTechLevel(getInfantry().getTechLevelYear()))) { return false; } if(getInfantry().getSquadSize() < (getInfantry().getSecondaryN() * weapon.getCrew())) { return false; } if((getInfantry().getSecondaryN() <= 0) && etype.hasFlag(WeaponType.F_INF_SUPPORT)) { return false; } if ((nType == T_WEAPON) || ((nType == T_ARCHAIC) && etype.hasFlag(WeaponType.F_INF_ARCHAIC)) || ((nType == T_PERSONAL) && !etype.hasFlag(WeaponType.F_INF_ARCHAIC) && !etype.hasFlag(WeaponType.F_INF_SUPPORT)) || ((nType == T_SUPPORT) && etype.hasFlag(WeaponType.F_INF_SUPPORT)) ) { if(txtFilter.getText().length() > 0) { String text = txtFilter.getText(); return etype.getName().toLowerCase().contains(text.toLowerCase()); } else { return true; } } return false; } }; equipmentSorter.setRowFilter(equipmentTypeFilter); } public void setEquipmentView() { XTableColumnModel columnModel = (XTableColumnModel)masterEquipmentTable.getColumnModel(); if(rbtnStats.isSelected()) { columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_NAME), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_DAMAGE), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_DIVISOR), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_SPECIAL), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_HEAT), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_MRANGE), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_RANGE), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_SHOTS), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_TECH), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_TRATING), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_AVSL), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_AVSW), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_AVCL), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_AVDA), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_DINTRO), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_DEXTINCT), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_DREINTRO), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_COST), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_CREW), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_BV), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_TON), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_CRIT), false); } else { columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_NAME), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_DAMAGE), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_DIVISOR), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_SPECIAL), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_HEAT), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_MRANGE), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_RANGE), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_SHOTS), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_TECH), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_TRATING), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_AVSL), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_AVSW), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_AVCL), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_AVDA), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_DINTRO), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_DEXTINCT), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_DREINTRO), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_COST), true); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_CREW), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_BV), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_TON), false); columnModel.setColumnVisible(columnModel.getColumnByModelIndex(EquipmentTableModel.COL_CRIT), false); } } /** * A comparator for integers written as strings with "-" sorted to the bottom always * @author Jay Lawson * */ public class WeaponIntegerSorter implements Comparator<String> { @Override public int compare(String s0, String s1) { if(s0.equals("-") && s1.equals("-")) { return 0; } else if(s0.equals("-")) { return 1; } else if(s1.equals("-")) { return -1; } else { //get the numbers associated with each string int r0 = Integer.parseInt(s0); int r1 = Integer.parseInt(s1); return ((Comparable<Integer>)r1).compareTo(r0); } } } public class WeaponDamageSorter implements Comparator<String> { @Override public int compare(String s0, String s1) { //get the numbers associated with each string double r1 = parseDamage(s1); double r0 = parseDamage(s0); return ((Comparable<Double>)r1).compareTo(r0); } private double parseDamage(String s) { double damage = 0; damage = Double.parseDouble(s); return damage; } } /** * A comparator for numbers that have been formatted with DecimalFormat * @author Jay Lawson * */ public static class FormattedNumberSorter implements Comparator<String> { @Override public int compare(String s0, String s1) { //lets find the weight class integer for each name DecimalFormat format = new DecimalFormat(); int l0 = 0; try { l0 = format.parse(s0).intValue(); } catch (java.text.ParseException e) { e.printStackTrace(); } int l1 = 0; try { l1 = format.parse(s1).intValue(); } catch (java.text.ParseException e) { e.printStackTrace(); } return ((Comparable<Integer>)l0).compareTo(l1); } } }