Java, Как обновить JTable в одном кадре из другого кадра

Итак, у меня есть класс MainFrame, в котором есть JTable, в котором перечислены все продукты, хранящиеся в БД. JButton с помощью слушателей откроет AddProduct (другой класс и другое окно/фрейм), в котором я могу добавить продукт в БД. К сожалению, я не совсем уверен, как я могу обновить/перепроверить JTable в MainFrame после того, как AddProduct добавит новый продукт и автоматически закроется. Не могли бы некоторые, пожалуйста, дать мне некоторое представление о том, как я могу легко решить эту проблему?

Поскольку программа довольно большая, вот соответствующие ее части: From MainFrame.java

public JPanel tabProducts() {
    JPanel panel = new JPanel(new MigLayout("","20 [grow, fill] 10 [grow, fill] 20", "20 [] 10 [] 20"));

    /** Labels **/
    JLabel label = new JLabel("List of all available products");

    /** Buttons **/
    JButton add = new JButton("Add product");
    add.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            new AddProduct();
        }
    });
    JButton update = new JButton("Update product");
    update.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            new UpdateProduct(ps.getProductByID(15));
        }
    });

    /** TABLE: Products **/
    String[] tableTitle = new String[] {"ID", "Name", "Type", "Price", "In stock"};
    String[][] tableData = null;
    DefaultTableModel model = new DefaultTableModel(tableData, tableTitle);
    JTable table = null;
    /** Disable editing of the cell **/
    table = new JTable(model){
        public boolean isCellEditable(int r, int c) {
            return false;
        }
    };
    /** Load the products from DB **/
    List<Product> listInv = ps.getProductsByAtt(new ArrayList<String>());
    for (int i = 0; i < listInv.size(); i++) {
        model.insertRow(i, new Object[] {
                listInv.get(i).getID(),
                listInv.get(i).getName(),
                listInv.get(i).getType(),
                listInv.get(i).getPrice(),
                listInv.get(i).getQuantity()
        });
    }
    /** Add scroll pane **/
    JScrollPane scrollpane = new JScrollPane(table);

    /** Add everything to the panel **/
    panel.add(label, "wrap, span");
    panel.add(scrollpane, "wrap, span");
    panel.add(add);
    panel.add(update);

    return panel;
}

И AddProduct.java

public class AddProduct {

    private JFrame frame;
    private JButton add, cancel;
    private JRadioButton food, beverage;
    private JTextField name, price, quantity;
    private IProductService ps = new ProductService();
    private ButtonGroup group = new ButtonGroup();
    private Product p;
    private String type = "";

    public AddProduct() {
        /** Frame options **/
        frame = new JFrame("Add new product");
        frame.setSize(400, 280);
        frame.setMinimumSize(new Dimension(400, 280));
        frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

        /** Default panel **/
        final JPanel panel = new JPanel(new MigLayout("","20 [grow, fill] 10 [grow, fill] 20", "20 [] 10 [] 20"));

        /** Radio Buttons to choose between the food and the beverages **/
        food = new JRadioButton("Food");
        beverage = new JRadioButton("Beverage");
        group.add(food);
        group.add(beverage);
        food.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                type = "Food";
                frame.validate();
            }
        });
        beverage.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                type = "Beverage";
                frame.validate();
            }
        });

        /** Add everything to the panel **/
        panel.add(new JLabel("Product ID"));
        panel.add(new JLabel(Integer.toString(ps.getProductNr()+1)), "wrap, span 2");
        panel.add(new JLabel("Name"));
        panel.add(name = new JTextField(""), "wrap, span 2");
        panel.add(new JLabel("Type"));
        panel.add(food);
        panel.add(beverage, "wrap");
        panel.add(new JLabel("Price"));
        panel.add(price = new JTextField(""), "wrap, span 2");
        panel.add(new JLabel("Quantity"));
        panel.add(quantity = new JTextField(""), "wrap, span 2");


        /** Button: ADD **/
        add = new JButton("Add product");
        add.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                if ( !type.equals("Food") && !type.equals("Beverage")) {
                    JOptionPane.showMessageDialog(panel, "Please choose the type of this product.");
                } else if (name.getText().equals("")) {
                    JOptionPane.showMessageDialog(panel, "Please type a name for this product.");
                } else if (price.getText().equals("")) {
                    JOptionPane.showMessageDialog(panel, "Please enter the price for this product.");
                } else if (quantity.getText().equals("")) {
                    JOptionPane.showMessageDialog(panel, "Please enter the available amount of this product in stock.");
                } else {
                    try {
                        p = new Product(ps.getProductNr()+1, name.getText(), type, Double.parseDouble(price.getText()), Integer.parseInt(quantity.getText()));
                        if (ps.addProduct(p)) {
                            JOptionPane.showMessageDialog(panel, "Product successfully added!");
                            frame.validate();
                            frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
                        }
                    } catch (Exception ex) {
                        addFinalError();
                    }
                }
            }
        });

        /** Button: CANCEL **/
        cancel = new JButton("Cancel");
        cancel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
            }
        });

        /** Add buttons to the panel **/
        panel.add(cancel);
        panel.add(add, "span 2");

        /** Add panel to frame and make it visible **/
        frame.add(panel);
        frame.setVisible(true);

    }

    /**
     * In case more then one error is encountered
     */
    private void addFinalError(){
        JOptionPane.showMessageDialog(frame, "An error occured while adding the product. Please make sure the following is correct:\n\n" +
                " Name  : Can contain letters and numbers\n" +
                " Price  : Must be a number\n" +
                " Quantity  : Must be a whole number\n");
    }
}

person vedran    schedule 20.03.2012    source источник
comment
Не совсем уверен, что попробовать. Я второй день работаю с графическим интерфейсом, поэтому я немного схожу с ума, потому что это всего лишь небольшая неудача по сравнению с остальной частью программы, которую мне еще предстоит сделать. Я погуглил, но большинство ответов не помогли или я не знал, как их реализовать. Итак, как я спросил, с чего мне начать. Я не ищу кого-то, кто будет программировать для меня, просто чтобы указать мне правильный путь.   -  person vedran    schedule 20.03.2012


Ответы (3)


возможно, статический метод в классе AddProduct, который возвращает созданный Product, решит вашу проблему. Ознакомьтесь с API JOptionPane. например static String showInputDialog(Object message)

person Seffel    schedule 20.03.2012
comment
Почему, во имя всего хорошего, вы рекомендуете оператору использовать что-нибудь статическое? Извините, но это ужасный совет. -1 голос. - person Hovercraft Full Of Eels; 21.03.2012

Вам нужно поработать над частью модели JTable, а затем обновить, повторная проверка будет работать. Просто попробуйте несколько примеров динамических обновлений JTable, таких как создание TableModel и динамическое заполнение jTable

person Abhishek Choudhary    schedule 20.03.2012
comment
еще раз: вам не нужно (не перекрашивать, не обновлять, не перепроверять) что-либо делать с JTable, если модель ведет себя... - person kleopatra; 20.03.2012

Простым способом было бы иметь метод в основном классе, который заполняет таблицу данными, и в вашем методе actionPerformed, где вы обрабатываете добавление новой записи, вызывая этот метод после добавления записи. Таким образом, основной класс обрабатывает обновление модели таблицы, а внутренние компоненты JTable будут обрабатывать перерисовку таблицы. Вы даже можете использовать метод из UpdateProducts, чтобы обновлять таблицу только в том случае, если добавление записи прошло успешно.

public void actionPerformed(ActionEvent e) { 
        UpdateProduct up = new UpdateProduct();
        if(up.addRecord(ps.getProductByID(15))){ 
          fillTable();
        }
    }

Надеюсь, это поможет некоторым.

person ChadNC    schedule 20.03.2012
comment
вы, вероятно, имеете в виду правильные вещи, просто основной класс обрабатывает ... перерисовку JTable неправильно: внутренние компоненты таблицы вызовут все необходимые перерисовки (перерисовки в Swing, кстати) - при условии, что модель запуск правильных событий, которые делает DefaultTableModel - person kleopatra; 20.03.2012
comment
Спасибо, что прояснили это. Я не слишком часто использую свинг. - person ChadNC; 20.03.2012