public PrepareMaterials(Project proj, int Row) {
    this.row = Row;
    this.proj = proj;

    frame = new JFrame("Подготовить материал");

    panel = new JPanel(new GridBagLayout());
    panel.setBorder(new EmptyBorder(20, 20, 5, 20)); // Настройка отступов

    // добавление лэйблов
    panel.add(
        new JLabel("Название"),
        new GridBagConstraints(
            3,
            0,
            1,
            1,
            0,
            0,
            GridBagConstraints.NORTH,
            GridBagConstraints.HORIZONTAL,
            new Insets(0, 0, 5, 5),
            0,
            0));
    panel.add(
        new JLabel("Папка проекта"),
        new GridBagConstraints(
            3,
            1,
            1,
            1,
            0,
            0,
            GridBagConstraints.NORTH,
            GridBagConstraints.HORIZONTAL,
            new Insets(0, 0, 5, 5),
            0,
            0));
    panel.add(
        new JLabel("Оприходованныые остатки"),
        new GridBagConstraints(
            3,
            2,
            1,
            1,
            0,
            0,
            GridBagConstraints.NORTH,
            GridBagConstraints.HORIZONTAL,
            new Insets(0, 0, 5, 5),
            0,
            0));

    // Добавление текстовых полей
    tfName = addTextField(proj.name, true);
    tfPath = addTextField(proj.path, false);
    tfDebit = addTextField(proj.debitBalances, true);
    panel.add(
        tfName,
        new GridBagConstraints(
            4,
            0,
            1,
            1,
            0,
            0,
            GridBagConstraints.BASELINE,
            GridBagConstraints.NONE,
            new Insets(0, 0, 5, 5),
            0,
            0));
    panel.add(
        tfPath,
        new GridBagConstraints(
            4,
            1,
            1,
            1,
            0,
            0,
            GridBagConstraints.BASELINE,
            GridBagConstraints.NONE,
            new Insets(0, 0, 5, 5),
            0,
            0));
    panel.add(
        tfDebit,
        new GridBagConstraints(
            4,
            2,
            1,
            1,
            0,
            0,
            GridBagConstraints.BASELINE,
            GridBagConstraints.NONE,
            new Insets(0, 0, 5, 5),
            0,
            0));

    // Добавление кнопок
    JButton addMat = addButton("Добавить материал");
    panel.add(
        addMat,
        new GridBagConstraints(
            1,
            5,
            1,
            1,
            0,
            0,
            GridBagConstraints.WEST,
            GridBagConstraints.NONE,
            new Insets(0, 0, 5, 5),
            0,
            0));
    panel.add(
        addButton("Удалить материалы"),
        new GridBagConstraints(
            2,
            5,
            1,
            1,
            0,
            0,
            GridBagConstraints.WEST,
            GridBagConstraints.NONE,
            new Insets(0, 0, 5, 5),
            0,
            0));
    panel.add(
        addButton("Сохранить изменения"),
        new GridBagConstraints(
            4,
            5,
            1,
            1,
            0,
            0,
            GridBagConstraints.WEST,
            GridBagConstraints.NONE,
            new Insets(0, 0, 5, 5),
            0,
            0));

    // Создание модели, таблицы и заполнение значениями
    prepModel = new PrepareTableModel();
    tablePrepare = new JTable(prepModel);
    prepModel.setValue(
        (ArrayList<Material>) proj.listMaterial.clone()); // Клонируем (используется для сохранения)

    // Настройка таблицы
    tablePrepare.setPreferredScrollableViewportSize(new Dimension(900, 150));
    tablePrepare.setFillsViewportHeight(true);

    // Добавление таблицы на Scroll Pane
    paneTable = new JScrollPane(tablePrepare);

    // Добавление панелей на фрейм
    frame.add(panel, BorderLayout.NORTH);
    frame.add(paneTable, BorderLayout.SOUTH);

    // настройка и отображение окна
    // отключаем операцию закрытия
    frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

    // добавляем слушателя событий от окна
    frame.addWindowListener(
        new WindowAdapter() {
          @Override
          public void windowClosing(WindowEvent e) {
            // потверждение выхода
            int res =
                JOptionPane.showConfirmDialog(
                    null,
                    "Все не сохранённые данные будут утеряны!",
                    "Действительно выйти?",
                    JOptionPane.OK_CANCEL_OPTION);
            if (res == JOptionPane.YES_OPTION) {
              frame.setVisible(false);
              MainWindow.frame.setEnabled(true);
              MainWindow.frame.toFront();
            }
          }
        });

    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

    // Если Оприходованные остатки не заполнены, то заполняем в отдельном окне
    if (proj.debitBalances == null) {
      modalDebitTextField = new JTextField(10);
      ((AbstractDocument) modalDebitTextField.getDocument())
          .setDocumentFilter(
              new DocumentFilter() {
                @Override
                public void insertString(FilterBypass fb, int offset, String str, AttributeSet attr)
                    throws BadLocationException {
                  // fb.insertString(offset, str.replaceAll("\\D", ""), attr);
                  try {
                    if (str.equals(",")
                        && !fb.getDocument()
                            .getText(0, fb.getDocument().getLength())
                            .contains(",")) {
                      super.insertString(fb, offset, str, attr);
                      return;
                    }
                    Double.parseDouble(str);
                    super.insertString(fb, offset, str, attr);
                  } catch (Exception e) {
                    System.err.println(e);
                  }
                }

                @Override
                public void replace(
                    FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
                    throws BadLocationException {
                  // fb.replace(offset, length, text.replaceAll("\\D", ""), attrs);
                  try {
                    if (text.equals(",")
                        && !fb.getDocument()
                            .getText(0, fb.getDocument().getLength())
                            .contains(",")) {
                      super.insertString(fb, offset, text, attrs);
                      return;
                    }
                    Double.parseDouble(text);
                    super.replace(fb, offset, length, text, attrs);
                  } catch (Exception e) {
                    System.err.println(e);
                  }
                }
              });

      JPanel p = new JPanel();
      p.setLayout(new GridBagLayout());
      p.setBorder(new EmptyBorder(10, 10, 10, 10));
      p.add(
          new JLabel("Введите оприходованные остатки"),
          new GridBagConstraints(
              0,
              0,
              1,
              1,
              0,
              0,
              GridBagConstraints.EAST,
              GridBagConstraints.HORIZONTAL,
              new Insets(0, 0, 5, 5),
              0,
              0),
          0);
      p.add(
          modalDebitTextField,
          new GridBagConstraints(
              0,
              2,
              1,
              1,
              0,
              0,
              GridBagConstraints.EAST,
              GridBagConstraints.HORIZONTAL,
              new Insets(0, 0, 5, 5),
              0,
              0),
          0);
      modalDebitBtn = new JButton("OK");
      modalDebitBtn.setMinimumSize(new Dimension(30, 30));
      modalDebitBtn.addActionListener(
          new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
              if (!"".equals(modalDebitTextField.getText())) {
                tfDebit.setText(modalDebitTextField.getText());
                tfDebit.setEnabled(false);
                modalDebitDialog.setVisible(false);
              } else {
                System.err.println("Пустое значение");
              }
            }
          });
      p.add(
          modalDebitBtn,
          new GridBagConstraints(
              0,
              4,
              1,
              1,
              0,
              0,
              GridBagConstraints.EAST,
              GridBagConstraints.HORIZONTAL,
              new Insets(0, 0, 5, 5),
              0,
              0),
          0);

      modalDebitDialog = new JDialog(frame, "Введите данные", false);
      modalDebitDialog.setContentPane(p);
      modalDebitDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
      modalDebitDialog.addWindowListener(
          new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent we) {
              // закрываем диалог и окно добавления материалов
              modalDebitDialog.setVisible(false);
              frame.setVisible(false);
              MainWindow.frame.setEnabled(false);
              MainWindow.frame.setEnabled(true);

              System.err.println(we);
              MainWindow.frame.toFront();
            }
          });

      modalDebitDialog.pack();
      modalDebitDialog.setLocationRelativeTo(null);
      modalDebitDialog.setVisible(true);
    }
  }
  // Обработка событий
  @Override
  public void actionPerformed(ActionEvent e) {
    String command = e.getActionCommand();

    switch (command) {
      case "Добавить материал":
        // Открываем новое окно
        int row = prepModel.material.size(); // Номер добавляемой в будущем строки
        frame.setEnabled(false); // Делаем окно неактивным
        AddMaterial addMt = new AddMaterial();
        addMt.setVisible(true);
        System.out.println("Добавлена\n");
        break;
      case "Удалить материалы":
        Iterator<Material> iter = prepModel.material.iterator(); // Итератор
        ArrayList<Material> selectItems = new ArrayList<Material>(); // Список выделенных элементов
        // Есть ли элементы в таблице?
        if (iter.hasNext()) {
          // Кидаем в список выделенные элементы
          while (iter.hasNext()) {
            Material next = iter.next();
            if (next.checkBox == Boolean.TRUE) {
              selectItems.add(next);
            }
          }

          // Есть ли выделенные элементы?
          if (!selectItems.isEmpty()) {
            // подтверждение удаления
            int res =
                JOptionPane.showConfirmDialog(
                    null,
                    "Вы действительно хотите удалить выделенные элементы?",
                    "Question",
                    JOptionPane.YES_NO_OPTION);
            if (res == JOptionPane.YES_OPTION) {
              // Удаление из таблицы
              for (int i = 0; i < selectItems.size(); i++) {
                prepModel.material.remove(selectItems.get(i));
              }
              prepModel.updateData(); // Обновление данных
              System.out.println("Удалены");
              JOptionPane.showMessageDialog(
                  null, "Удаление выполнено успешно! Сохраните результат!");
            }
          } else {
            JOptionPane.showMessageDialog(null, "Нет выделенных элементов для удаления.");
          }

        } else {
          System.out.println("Нет элементов для удаления\n");
        }
        break;
      case "Сохранить изменения":
        // Проверка, добавдлены ли материалы? (Для установки даты)
        Date dMat = null;
        if (!proj.listMaterial.equals(prepModel.material)) {
          dMat = new Date();
        }
        // Обновление записей в модели таблицы родительского окна
        MainWindow.myModel.pr.set(
            this.row,
            new Project(
                tfName.getText(),
                tfPath.getText(),
                tfDebit.getText(),
                proj.date,
                dMat,
                prepModel.material));

        // MessageBox
        JOptionPane.showMessageDialog(
            null, "Сохраненение выполнено успешно!", "Сохранено", JOptionPane.INFORMATION_MESSAGE);
        MainWindow.myModel.updateData(); // обновляем таблицу родительского окна

        // Закрываем окно после сохранения
        frame.setVisible(false);
        MainWindow.frame.setEnabled(true);
        MainWindow.frame.toFront();
        break;
      default:
        System.err.println("Неизвестная команда");
    }
  }