0

我正在创建一个基本发票页面,我想在其中输入产品详细信息我将有一个包含四列的 JTable,数量、描述、单位成本和总计

表

当我在我想要的表单中完成输入详细信息时,然后单击保存,详细信息将自动更新到数据库。

有人可以告诉我进行此过程的最佳方法。普通的JTable会这样做还是有其他类型的桌子更合适?

4

1 回答 1

1

我会使用自定义TableModel和 JPA/Hibernate。

您将在下面找到一个非常基本的示例(当然,代码需要拆分)。

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Persistence;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel;

public class TestSwingTableJPA {

    private JPATableModel tableModel;
    private JFrame frame;

    private class JPATableModel extends AbstractTableModel {

        private List<Item> items = new ArrayList<TestSwingTableJPA.Item>();

        private EntityManager entityManager;

        @Override
        public int getRowCount() {
            return items.size();
        }

        @Override
        public int getColumnCount() {
            return 4;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Item item = getValueAt(rowIndex);
            switch (columnIndex) {
            case 0:
                return item.getQuantity();
            case 1:
                return item.getDescription();
            case 2:
                return item.getCostPerUnit();
            case 3:
                if (item.getQuantity() != null && item.getCostPerUnit() != null) {
                    return item.getCostPerUnit().multiply(item.getQuantity());
                } else {
                    return null;
                }
            default:
                break;
            }
            return null;
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            Item item = getValueAt(rowIndex);
            switch (columnIndex) {
            case 0:
                item.setQuantity((BigDecimal) aValue);
                fireTableCellUpdated(rowIndex, 3); // Total may also have changed
                break;
            case 1:
                item.setDescription((String) aValue);
                break;
            case 2:
                item.setCostPerUnit((BigDecimal) aValue);
                fireTableCellUpdated(rowIndex, 3); // Total may also have changed
                break;
            }
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            switch (columnIndex) {
            case 0:
            case 2:
            case 3:
                return BigDecimal.class;
            case 1:
                return String.class;
            }
            return Object.class;
        }

        @Override
        public String getColumnName(int column) {
            switch (column) {
            case 0:
                return "Quantity";
            case 1:
                return "Description";
            case 2:
                return "Cost Per Unit";
            case 3:
                return "Total";
            default:
                break;
            }
            return null;
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return columnIndex == 0 || columnIndex == 1 || columnIndex == 2;
        }

        private Item getValueAt(int row) {
            return items.get(row);
        }

        public void setItems(List<Item> items) {
            this.items = items;
            fireTableDataChanged();
        }

        public void addItem(Item item) {
            getEntityManager().persist(item);
            this.items.add(item);
            fireTableRowsInserted(this.items.size() - 1, this.items.size() - 1);
        }

        public List<Item> reload() {
            return getEntityManager().createNamedQuery("selectAllItems", Item.class).getResultList();
        }

        public void save() {
            getEntityManager().getTransaction().begin();
            getEntityManager().getTransaction().commit();
        }

        public EntityManager getEntityManager() {
            if (entityManager == null) {
                // You need to configure your persistence unit in META-INF/persistence.xml
                EntityManagerFactory factory = Persistence.createEntityManagerFactory("MyPersistenceUnit");
                entityManager = factory.createEntityManager();
            }
            return entityManager;
        }

    }

    public TestSwingTableJPA() {
    }

    @Entity(name = "Item")
    @NamedQueries({ @NamedQuery(name = "selectAllItems", query = "select item from Item as item") })
    public static class Item {

        private Long id;

        private BigDecimal quantity;
        private String description;
        private BigDecimal costPerUnit;

        public BigDecimal getQuantity() {
            return quantity;
        }

        public void setQuantity(BigDecimal quantity) {
            this.quantity = quantity;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public BigDecimal getCostPerUnit() {
            return costPerUnit;
        }

        public void setCostPerUnit(BigDecimal costPerUnit) {
            this.costPerUnit = costPerUnit;
        }

        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }
    }

    protected void initUI() {
        frame = new JFrame(TestSwingTableJPA.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JTable table = new JTable(tableModel = new JPATableModel());
        table.setFillsViewportHeight(true);
        table.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2 && table.rowAtPoint(e.getPoint()) == -1) {
                    tableModel.addItem(new Item());
                }
            }
        });
        frame.add(new JScrollPane(table));
        JPanel panel = new JPanel();
        JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 5));
        JButton save = new JButton("Save");
        save.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                save();
            }
        });
        JButton reload = new JButton("Reload");
        reload.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                reload();
            }
        });
        buttonPanel.add(save);
        buttonPanel.add(reload);
        panel.add(buttonPanel);
        frame.add(panel, BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
        reload();
    }

    protected void save() {
        final JDialog dialog = new JDialog(frame);
        JProgressBar progress = new JProgressBar();
        progress.setIndeterminate(true);
        dialog.add(progress);
        dialog.pack();
        dialog.setLocationRelativeTo(frame);
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {

            @Override
            protected Void doInBackground() throws Exception {
                tableModel.save();
                return null;
            }

            @Override
            protected void done() {
                dialog.dispose();
            }

        };
        worker.execute();
        dialog.setVisible(true);
    }

    protected void reload() {
        final JDialog dialog = new JDialog(frame);
        JProgressBar progress = new JProgressBar();
        progress.setIndeterminate(true);
        dialog.add(progress);
        dialog.pack();
        dialog.setLocationRelativeTo(frame);
        SwingWorker<List<Item>, Void> worker = new SwingWorker<List<Item>, Void>() {

            @Override
            protected List<Item> doInBackground() throws Exception {
                return tableModel.reload();
            }

            @Override
            protected void done() {
                try {
                    tableModel.setItems(get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                    JOptionPane.showMessageDialog(frame, "Could not fetch items from database", "Error while loading items",
                            JOptionPane.ERROR_MESSAGE);
                } finally {
                    dialog.dispose();
                }
            }

        };
        worker.execute();
        dialog.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                final TestSwingTableJPA testSwingTableJPA = new TestSwingTableJPA();
                testSwingTableJPA.initUI();
            }
        });
    }

}

和persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">

    <persistence-unit name="MyPersistenceUnit">

        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
            <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/test"/>
            <property name="javax.persistence.jdbc.user" value="test"/>
            <property name="javax.persistence.jdbc.password" value="test"/>


            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>

    </persistence-unit>

</persistence>

您只需在端口 5432 上使用用户测试(pwd 测试)设置本地 postgresql 数据库“测试”。

这样做的不利方面之一是如果您失去了与数据库的连接。我不确定它的行为方式,但您可能需要重新创建一个新的 EntityManager 并因此丢失所有未保存的更改。我不是 JPA/Hibernate 专家。

如果您使用 Maven,以下是我使用的依赖项:

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>4.2.0.Final</version>
    </dependency>
    <dependency>
        <groupId>postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.1-901-1.jdbc4</version>
    </dependency>
于 2013-04-16T16:19:17.000 回答