Java Swing JButton 在表单更新之前必须被点击两次

Jave Swing JButton must be clicked twice before form updates

这个问题(对我来说)太奇怪了,我什至不知道怎么问。我有一个自定义控件 NewOtherPaidOutsEntry,它包含两个文本字段、一个“保存”按钮和一个“取消”按钮。主 window 包含一个表单,在该表单中是一个可选的 OtherPaidOuts 列表。 NewOtherPaidOutsEntry 添加在此列表的底部,以便用户可以将条目添加到列表中。 我使用单一方法 newOtherPaidOutsActionEmitted 创建了一个接口 NewOtherPaidOutsListener,并在 NewOtherPaidOutsEntry 中创建了一个名为 setNewOtherPaidOutsListener 的方法。父表单像这样设置这个新条目(EditAction 只是一个枚举,请注意,为清楚起见,我省略了真正的异常处理):

private void setupNewEntry() {
    this.newEntry = new NewOtherPaidOutsEntry(this.shiftId);
    this.newEntry.setNewOtherPaidOutsListener((EditAction action) -> {
        try {
            handleNewOtherPaidOuts(action);
        } catch (Exception e) { 
           handleException(e);
        }
    });
}

handleNewOtherPaidOuts 是这样的:

private void handleNewOtherPaidOuts(EditAction action) {
    switch (action) {
        case SAVE:
            System.out.println("Save NewOtherPaidOuts");
            OtherPaidOutsController.addShiftOtherPaidOut(newEntry);
            newEntry.reset();
            layoutPanel();
            shiftLeftPane.update();
            break;
        case CANCEL:
            System.out.println("Cancel NewOtherPaidOuts");
            break;
    }
}

我输入了 println 语句,看到它在单击按钮后立即执行。如果我逐步调试,一切都会正常运行。但是,如果我只是 运行 应用程序,则 OtherPaidOuts 列表不会更新,直到我第二次单击新条目的“保存”按钮。第一次单击按钮时,按钮会保持按下状态。

addShiftOtherPaidOut(newEntry) 执行数据库插入。 newEntry.reset() 只是将两个文本字段设置为空文本。 OtherPaidOuts 列表在 JPanel OtherPaidOutsPane 中,作为 layoutPanel() 方法:

protected void layoutPanel() {
    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    add(createTitlePanel());
    add(Box.createVerticalStrut(10));
    getOtherPaidOutsEntries();        
    add(newEntry);
    add(Box.createVerticalGlue());       
}

getOtherPaidOutsEntries 方法只是获取此记录的现有条目列表,并将它们添加到 OtherPaidOutsPane。然后将 OtherPaidOutsPane 嵌入到另一个 JPanel ShiftLeftPane 中。

我想我可以只使用一个对话框来输入新条目,但是......我想我会先在这条路线上尽力而为。

如果我没有提供足够的示例代码,我深表歉意,但项目的这个阶段是如此根深蒂固,很难给出一个 运行 可行的例子。请让我知道我还需要提供什么,我很乐意提供。并且请理解我是靠自己的裤子坐飞机,所以请善待任何解释 ;-) 谢谢!

当您将组件动态添加到可见 GUI 时,基本代码是:

panel.add(....);
panel.revalidate();
panel.repaint();

默认情况下,Swing 组件的大小为 (0, 0),因此 paint() 没有任何内容。您需要 revalidate() 来调用布局管理器,以便根据布局管理器的规则为组件指定大小和位置。

I guess I could just use a dialog box for a new entry,

没有详细阅读你的整个问题,因为很难理解你正在做的事情的背景。

但是如果您有多个条目,那么也许您应该使用 JTable 来显示数据。然后您可以使用 JDialog 来提示输入数据,然后将数据添加到 JTable。这比尝试 add/remove 个面板更容易管理。