java swing jtable 在单个 table 中从数据库中添加两个 table

java swing jtable add two table from database in single table

我有 table 名为 tbl_income 和 tbl_expenses... tbl_income包含四列四行,tbl_expenses包含四列三行link如下图。

我想在下面的 java swing JTable link 图片中 mank single table

我怎么能做出这样的……对不起,英语不好……

这是我试过的:

 DefaultTableModel model = (DefaultTableModel) tbldailybook.getModel();
        try {
            Statement stmt = db.cn.createStatement();
            ResultSet rs = stmt.executeQuery("select * from tblincome,tblexpenses");
            while (rs.next()) {
                model.addRow(new Object[]{rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(6), rs.getString(7), rs.getString(8)});
            }
        } catch (Exception e) {
        }

tblincome 有单行但有行回复

这是一个单独提取两个表并将其集成到公共表中的解决方案TableModel

public class MyTableModel extends AbstractTableModel implements TableModel {
    private List<Data> inclomeList;
    private List<Data> expenseList;

    private void setData(List<Data> list, Data data) {
        int rows = getRowCount();
        int row = list.size();
        list.add(data);

        if(row < rows) {
            fireTableRowsUpdated(row, row);
        }
        else {
            fireTableRowsInserted(row, row);
        }
    }

    public void setIncomeData(Data data) {
        if(inclomeList == null) {
            inclomeList = new ArrayList<>();
        }

        setData(inclomeList, data);
    }

    public void setExpenseData(Data data) {
        if(expenseList == null) {
            expenseList = new ArrayList<>();
        }

        setData(expenseList, data);
    }

    @Override
    public String getColumnName(int column) {
        switch (column) {
            case 0:
            case 3:
                return "Date";

            case 1: return "Income";
            case 4: return "Expenses";


            case 2:
            case 5:
                return "Amount";

            default:
                return super.getColumnName(column);
        }
    }

    @Override
    public int getRowCount() {
        if(inclomeList == null || expenseList == null) {
            if(inclomeList != null) {
                return inclomeList.size();
            }
            else if(expenseList != null) {
                return expenseList.size();
            }

            return 0;
        }

        return Math.max(inclomeList.size(), expenseList.size());
    }

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

    @Override
    public Object getValueAt(int row, int column) {
        Data inclome = null;
        Data expense = null;

        if(inclomeList != null && inclomeList.size() > row) {
            inclome = inclomeList.get(row);
        }

        if(expenseList != null && expenseList.size() > row) {
            expense = expenseList.get(row);
        }

        switch (column) {
            case 0: return inclome != null ? inclome.getDate() : "";
            case 1: return inclome != null ? inclome.getName() : "";
            case 2: return inclome != null ? inclome.getAmount() : "";
            case 3: return expense != null ? expense.getDate() : "";
            case 4: return expense != null ? expense.getName() : "";
            case 5: return expense != null ? expense.getAmount() : "";
        }

        return null;
    }

    public void update() {
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
            @Override
            protected Void doInBackground() throws Exception {
                Database database = new Database();
                inclomeList = database.getData(Database.TBL_INCOME);
                expenseList = database.getData(Database.TBL_EXPENSES);

                return null;
            }

            @Override
            protected void done() {
                try {
                    get();
                    fireTableDataChanged();
                }
                catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
        };

        worker.execute();
    }
}

使用数据库的接口:

public class Database {
    public static final String TBL_INCOME = "tbl_income";
    public static final String TBL_EXPENSES = "tbl_expenses";

    private Connection getConnection() throws SQLException {
        return DriverManager.getConnection("jdbc:mysql://192.168.40.5/test", "root", "");
    }

    public List<Data> getData(String tbl_name) throws SQLException {
        try (Connection connection = getConnection()) {
            String query = "select * from " + tbl_name;

            try(ResultSet rs = connection.createStatement().executeQuery(query)) {
                List<Data> list = new ArrayList<>();
                while (rs.next()) {
                    Data data = new Data();
                    data.setDate(rs.getDate("date"));
                    data.setName(rs.getString("particular"));
                    data.setAmount(rs.getDouble("amount"));

                    list.add(data);
                }

                return list;
            }
        }
    }
}

MainFrame.java

public class MainFrame extends JFrame {

    private JTable table = new JTable(new MyTableModel());

    public MainFrame() throws HeadlessException {
        super("MainFrame");
        createGUI();
    }

    private void createGUI() {
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setPreferredSize(new Dimension(600, 400));

        JButton addI = new JButton("+");
        addI.addActionListener(e -> ((MyTableModel)table.getModel()).setIncomeData(new Data()));

        JButton addE = new JButton("+");
        addE.addActionListener(e -> ((MyTableModel)table.getModel()).setExpenseData(new Data()));

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
        panel.add(addI);
        panel.add(addE);

        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane, BorderLayout.CENTER);
        add(panel, BorderLayout.PAGE_END);

        pack();
        setLocationRelativeTo(null);

        ((MyTableModel)table.getModel()).update();
    }

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

+----+------------+----------------+--------+
| id | dateValue  |   particular   | amount |
+----+------------+----------------+--------+
|  1 | 2017-02-02 | Cash Deposit   |      1 |
|  2 | 2017-02-03 | Cheque Deposit |      2 |
|  3 | 2017-02-08 | Cash Deposit   |      3 |
|  4 | 2017-02-07 | Product Sales  |      4 |
+----+------------+----------------+--------+

+----+------------+------------+--------+
| id | dateValue  | particular | amount |
+----+------------+------------+--------+
|  1 | 2017-05-07 | Factory    |      6 |
|  2 | 2017-06-02 | Staff      |      7 |
|  3 | 2017-06-03 | Travel     |      8 |
+----+------------+------------+--------+

然后我用select * from income left join expenses on income.id = expenses.id查询数据库得到:

+----+------------+----------------+--------+----+------------+------------+--------+--+
| id | dateValue  |   particular   | amount | id | dateValue  | particular | amount |  |
+----+------------+----------------+--------+----+------------+------------+--------+--+
|  1 | 2017-02-02 | Cash Deposit   |      1 |  1 | 2017-05-07 | Factory    |      6 |  |
|  2 | 2017-02-03 | Cheque Deposit |      2 |  2 | 2017-06-02 | Staff      |      7 |  |
|  3 | 2017-02-08 | Cash Deposit   |      3 |  3 | 2017-06-03 | Travel     |      8 |  |
|  4 | 2017-02-07 | Product Sales  |      4 |    |            |            |        |  |
+----+------------+----------------+--------+----+------------+------------+--------+--+

根据目前可用的信息,这可能是我能做的最好的

您可以使用 Most simple code to populate JTable from ResultSet or 之类的东西来构建 JTable ... 作为可用示例

if second table have more row than table one .. record will not display which are more id in second table – raman dangol 8 hours ago

Also, if there are inconsistent IDs, the records will be lost. That's why I said this was not a trivial question

那么在那些情况下,FULL OUTER JOIN would be more useful. However, based on the information I have, full outer join is not supported in MySQL, because that would be useful. However, based on How to do a FULL OUTER JOIN in MySQL? 我们可以做...

select * from income left join expenses on income.id = expenses.id union select * from income right join expenses on income.id = expenses.id where income.id is null

可以生成类似

的东西
+----+------------+----------------+--------+----+------------+------------+--------+
| id | datevalue  |   particular   | amount | id | datevalue  | particular | amount |
+----+------------+----------------+--------+----+------------+------------+--------+
|  1 | 2017-02-02 | Cash Deposit   |    1.0 |  1 | 2017-05-07 | Factory    |    6.0 |
|  2 | 2017-02-03 | Cheque Deposit |    2.0 |  2 | 2017-06-02 | Staff      |    7.0 |
|  3 | 2017-02-03 | Cash Deposit   |    3.0 |  3 | 2017-06-03 | Travel     |    8.0 |
|  4 | 2017-02-03 | Product Sales  |    4.0 |  4 | 2017-10-01 | Test 1     |   10.0 |
|  5 | 2017-10-02 | Test 2         |   20.0 |    |            |            |        |
+----+------------+----------------+--------+----+------------+------------+--------+

或者,如果您希望让内容与他们的 "selected sides" 保持一致,例如

select income.id, income.datevalue, income.PARTICULAR, income.AMOUNT, 
       expenses.id, expenses.datevalue, expenses.PARTICULAR, expenses.AMOUNT 
       from income join expenses on income.id = expenses.id
union all
select income.id, income.datevalue, income.PARTICULAR, income.AMOUNT, 
       null, null, null, null 
       from INCOME where not exists (select expenses.id from expenses where expenses.id = income.id)
union all
select null, null, null, null, 
       expenses.id, expenses.datevalue, expenses.PARTICULAR, expenses.AMOUNT 
       from expenses where not exists (select income.id from income where income.id = expenses.id)

可以生成类似...

+----+------------+----------------+--------+----+------------+------------+--------+
| id | datevalue  |   particular   | amount | id | datevalue  | particular | amount |
+----+------------+----------------+--------+----+------------+------------+--------+
|  1 | 2017-02-02 | Cash Deposit   |    1.0 |  1 | 2017-05-07 | Factory    |    6.0 |
|  2 | 2017-02-03 | Cheque Deposit |    2.0 |  2 | 2017-06-02 | Staff      |    7.0 |
|  3 | 2017-02-03 | Cash Deposit   |    3.0 |  3 | 2017-06-03 | Travel     |    8.0 |
|  4 | 2017-02-03 | Product Sales  |    4.0 |  4 | 2017-10-01 | Test 1     |   10.0 |
|    |            |                |        |  5 | 2017-10-02 | Test 2     |   20.0 |
+----+------------+----------------+--------+----+------------+------------+--------+

归根结底,还是数据库的问题。

为简单起见,您可以创建一个或多个数据库views以简化查询