explain it to me line by line /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package inventorymanagementapp;

/**
 *
 * @author l226333
 */
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.util.Random;

public class InventoryManagementApp extends JFrame {
    private JTextField itemNameField;
    private JTextField itemPowerField;
    private JTextField itemWeightField;
    private JComboBox<String> itemTypeComboBox;
    private JButton addItemButton, removeItemButton, clearAllButton, equipRandomButton, createCharacterButton;
    private JTable inventoryTable;
    private DefaultTableModel tableModel;
    private JTextField searchField;
    private TableRowSorter<DefaultTableModel> sorter;

    public InventoryManagementApp() {
        setTitle("Adventure Game Inventory Management");
        setSize(1200, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.getContentPane().setBackground(Color.red);
        setLocationRelativeTo(null);
        setLayout(new BorderLayout());

        initializeUIComponents();
        initializeButtons();
        
        initializeEventHandlers();
        initializeTableDoubleClick();
    }

    private void initializeUIComponents() {
        JPanel topPanel = new JPanel(new BorderLayout());
        

        JPanel formPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5,5,5,5);
        
        gbc.fill =  GridBagConstraints.HORIZONTAL;

        JLabel nameLabel =  new JLabel("Item Name:");
        itemNameField = new JTextField(15);
        
        
        JLabel powerLabel = new JLabel("Item Power:");
        itemPowerField = new JTextField(10);
        
        
        JLabel weightLabel = new JLabel("Item Weight:");
        itemWeightField = new JTextField(10);
        
        
        JLabel typeLabel = new JLabel("Item Type:");
        String[] itemTypes = {"Weapon", "Potion", "Armor"};
        
        itemTypeComboBox = new JComboBox<>(itemTypes);

        gbc.gridx = 0;
        gbc.gridy = 0;
        formPanel.add(nameLabel, gbc);

        gbc.gridx = 1;
        formPanel.add(itemNameField, gbc);

        gbc.gridx = 0;
        gbc.gridy = 2;
        formPanel.add(powerLabel, gbc);

        gbc.gridx = 1;
        formPanel.add(itemPowerField, gbc);

        gbc.gridx = 0;
        gbc.gridy = 1;
        formPanel.add(weightLabel, gbc);

        gbc.gridx = 1;
        formPanel.add(itemWeightField, gbc);

        gbc.gridx = 0;
        gbc.gridy = 3;
        formPanel.add(typeLabel, gbc);

        gbc.gridx = 1;
        formPanel.add(itemTypeComboBox, gbc);

        topPanel.add(formPanel, BorderLayout.CENTER);

        JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 10));
        JLabel searchLabel = new JLabel("Search:");
        searchField = new JTextField(20);
        searchPanel.add(searchLabel);
        searchPanel.add(searchField);

        topPanel.add(searchPanel, BorderLayout.SOUTH);

        add(topPanel, BorderLayout.NORTH);

        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));

        addItemButton = new JButton("Add Item");
        removeItemButton = new JButton("Remove Selected Item");
        clearAllButton = new JButton("Clear All");
        equipRandomButton = new JButton("Equip Random Item");
        createCharacterButton = new JButton("Create Powerful Character");

        buttonPanel.add(addItemButton);
        buttonPanel.add(removeItemButton);
        buttonPanel.add(clearAllButton);
        buttonPanel.add(equipRandomButton);
        buttonPanel.add(createCharacterButton);

        add(buttonPanel, BorderLayout.CENTER);

        String[] columnNames = {"Item Name", "Type", "Power", "Weight"};
        
        tableModel = new DefaultTableModel(columnNames, 0) {
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        inventoryTable = new JTable(tableModel);
        
        
        inventoryTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION);
        sorter = new TableRowSorter<>( tableModel);
        inventoryTable.setRowSorter(sorter);

        JScrollPane scrollPane = new JScrollPane(inventoryTable);
        
        scrollPane.setPreferredSize(new Dimension(780, 250));

        add(scrollPane,  BorderLayout.SOUTH);

        searchField.getDocument().addDocumentListener(new javax.swing.event.DocumentListener() {
            
            public void insertUpdate(javax.swing.event.DocumentEvent e) { filter(); }
            
            public void removeUpdate(javax.swing.event.DocumentEvent e) { filter(); }
            
            public void changedUpdate(javax.swing.event.DocumentEvent e) { filter(); }

            private void filter() {
                
                String text = searchField.getText();
                if(text.trim().length() == 0) {
                    sorter.setRowFilter(null);
                } else {
                    sorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
                }
            }
        });
    }

    private void initializeButtons() {
    }

    private void initializeEventHandlers() {
        addItemButton.addActionListener(e -> addItem());
        
        removeItemButton.addActionListener(e -> removeItem());
        
        clearAllButton.addActionListener(e -> clearAllFields());
        equipRandomButton.addActionListener(e -> equipRandomItem());
        
        createCharacterButton.addActionListener(e -> createPowerfulCharacter());
    }

    private void initializeTableDoubleClick() {
        inventoryTable.addMouseListener(new java.awt.event.MouseAdapter(){
            public void mouseClicked(java.awt.event.MouseEvent evt){
                if(evt.getClickCount() == 2){
                    JTable target = (JTable)evt.getSource();
                    int row = target.getSelectedRow();
                    if(row != -1){
                        int modelRow = target.convertRowIndexToModel(row);
                        String name = (String)tableModel.getValueAt(modelRow,0);
                        String type = (String)tableModel.getValueAt(modelRow,1);
                        
                        int power = (int)tableModel.getValueAt(modelRow,2);
                        double weight = (double)tableModel.getValueAt(modelRow,3);
                        itemNameField.setText(name);
                        
                        itemTypeComboBox.setSelectedItem(type);
                        
                        itemPowerField.setText(String.valueOf(power));
                        itemWeightField.setText(String.valueOf(weight));
                        tableModel.removeRow(modelRow);
                    }
                }
            }
        });
    }

    private void addItem(){
        String name = itemNameField.getText().trim();
        String powerStr = itemPowerField.getText().trim();
        String weightStr = itemWeightField.getText().trim();
        String type = (String)itemTypeComboBox.getSelectedItem();

        if(name.isEmpty() || powerStr.isEmpty() || weightStr.isEmpty() || type.isEmpty()){
            
            JOptionPane.showMessageDialog(this,"All fields must be filled.","Input Error",JOptionPane.ERROR_MESSAGE);
            return;
        }

        int power;
        double weight;

        try{
            power = Integer.parseInt(powerStr);
        } catch(NumberFormatException ex){
            
            JOptionPane.showMessageDialog(this,"Item Power must be an integer.","Input Error",JOptionPane.ERROR_MESSAGE);
            return;
        }

        try{
            weight = Double.parseDouble(weightStr);
            
        } catch(NumberFormatException ex){
            
            JOptionPane.showMessageDialog(this,"Item Weight must be a decimal number.","Input Error",JOptionPane.ERROR_MESSAGE);
            return;
        }

        tableModel.addRow(new Object[]{name, type, power, weight});
        
        JOptionPane.showMessageDialog(this,"Item added successfully!","Success",JOptionPane.INFORMATION_MESSAGE);
        clearAllFields();
    }

    private void removeItem(){
        
        int selectedRow = inventoryTable.getSelectedRow();
        if(selectedRow == -1){
            
            JOptionPane.showMessageDialog(this,"No item selected to remove.","Warning",JOptionPane.WARNING_MESSAGE);
        } else {
            int modelRow = inventoryTable.convertRowIndexToModel(selectedRow);
            int confirm = JOptionPane.showConfirmDialog(this,"Are you sure you want to remove the selected item?","Confirm Removal",JOptionPane.YES_NO_OPTION);
            if(confirm == JOptionPane.YES_OPTION){
                tableModel.removeRow(modelRow);
            }
        }
    }

    private void clearAllFields(){
        
        itemNameField.setText("");
        itemPowerField.setText("");
        
        itemWeightField.setText("");
        itemTypeComboBox.setSelectedIndex(0);
    }

    private void equipRandomItem(){
        int rowCount = tableModel.getRowCount();
        
        if(rowCount == 0){
            JOptionPane.showMessageDialog(this,"Inventory is empty.","Info",JOptionPane.INFORMATION_MESSAGE);
            return;
        }

        Random rand = new Random();
        int randomIndex = rand.nextInt(rowCount);
        String itemName = (String)tableModel.getValueAt(randomIndex,0);
        JOptionPane.showMessageDialog(this,"You have equipped  " + itemName + ".","Item Equipped",JOptionPane.INFORMATION_MESSAGE);
    }

    private void createPowerfulCharacter(){
        String topWeapon = null;
        String topArmor = null;
        String topPotion = null;
        
        
        int maxWeaponPower = Integer.MIN_VALUE;
        int maxArmorPower = Integer.MIN_VALUE;
        int maxPotionPower = Integer.MIN_VALUE;

        for(int i=0;i<tableModel.getRowCount();i++){
            String type = (String)tableModel.getValueAt(i,1);
            int power = (int)tableModel.getValueAt(i,2);
            String name = (String)tableModel.getValueAt(i,0);

            switch(type){
                case "Weapon":
                    if(power > maxWeaponPower){
                        maxWeaponPower = power;
                        topWeapon = name;
                    }
                    break;
                case "Armor":
                    if(power > maxArmorPower){
                        maxArmorPower = power;
                        topArmor = name;
                    }
                    break;
                case "Potion":
                    if(power > maxPotionPower){
                        maxPotionPower = power;
                        topPotion = name;
                    }
                    break;
            }
        }

        if(topWeapon != null && topArmor != null && topPotion != null){
            String message = "Your character is equipped with:\nWeapon: " + topWeapon +
                    "\nArmor: " + topArmor + "\nPotion: " + topPotion + ".";
            JOptionPane.showMessageDialog(this, message, "Powerful Character", JOptionPane.INFORMATION_MESSAGE);
        }
        else{
            JOptionPane.showMessageDialog(this,"Unable to create a fully equipped character.","Insufficient Items",JOptionPane.WARNING_MESSAGE);
        }
    }

   
    public static void main(String[] args){
        SwingUtilities.invokeLater(() -> {
            new InventoryManagementApp().setVisible(true);
        });
    }
}