Java, Как да опреснявам JTable в един кадър от друг кадър

Така че имам клас MainFrame, който има JTable в него, изброявайки всички продукти, съхранявани в DB. JButton с помощта на слушатели ще отвори AddProduct (друг клас и друг прозорец/рамка), в който мога да добавя продукт в DB. За съжаление не съм съвсем сигурен как мога да актуализирам/потвърдя повторно JTable в MainFrame, след като AddProduct добави нов продукт и се затвори автоматично. Може ли някои да ми даде някаква идея как мога лесно да разреша това?

Тъй като програмата е доста голяма, ето съответните части от нея: От 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
Не съм сигурен какво да опитам. Вторият ми ден, в който работя с графичен интерфейс, така че съм някак откачен, защото това е само малка пречка в сравнение с останалата част от програмата, която тепърва ще направя. Потърсих го в Google, но повечето от отговорите не бяха полезни или не знаех как да ги приложа. И така, като попитах откъде да започна. Не търся някой, който да програмира вместо мен, само за да ме насочи по правилния път.   -  person vedran    schedule 20.03.2012


Отговори (3)


може би статичен метод в класа AddProduct, който връща създадения Product, ще реши проблема ви. Разгледайте JOptionPane API например 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 speak, btw) - при условие че моделът е задейства правилните събития, които DefaultTableModel прави - person kleopatra; 20.03.2012
comment
Благодаря, че изясни това. Не мога да използвам суинг твърде често. - person ChadNC; 20.03.2012