Jave Swing JButton необходимо дважды щелкнуть перед обновлением формы - PullRequest
0 голосов
/ 06 сентября 2018

Это такая странная проблема (для меня), что я даже не знаю, как ее задать. У меня есть пользовательский элемент управления NewOtherPaidOutsEntry, который содержит два текстовых поля, кнопку Сохранить и кнопку Отмена. Главное окно содержит форму, и в этой форме находится список необязательных OtherPaidOuts. NewOtherPaidOutsEntry добавляется внизу этого списка, чтобы пользователь мог добавлять записи в список. Я создал интерфейс NewOtherPaidOutsListener с одним методом newOtherPaidOutsActionEmitted и методом в 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 находится в JPPanel 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.

Полагаю, я мог бы просто использовать диалоговое окно для новой записи, но ... Я думал, что сначала я приложу все усилия с этим маршрутом.

Приношу свои извинения, если я не предоставил достаточно примеров кода, но этот этап проекта настолько укоренился, что трудно привести работоспособный пример. Пожалуйста, дайте мне знать, что еще мне нужно предоставить, я буду рад. И, пожалуйста, поймите, что я летаю возле штанов, так что будьте добры с любыми объяснениями ;-) Спасибо!

1 Ответ

0 голосов
/ 06 сентября 2018

Когда вы динамически добавляете компоненты в видимый графический интерфейс, базовый код выглядит так:

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

По умолчанию размер компонента Swing равен (0, 0), поэтому рисовать нечего (). Чтобы вызвать диспетчер компоновки, требуется revalidate (), чтобы компонентам были заданы размер и расположение в соответствии с правилами диспетчера компоновки.

Полагаю, я мог бы просто использовать диалоговое окно для новой записи,

Не прочитал весь ваш вопрос подробно, потому что было слишком сложно понять контекст того, что вы делаете.

Но если у вас есть несколько записей чего-то, возможно, вам следует использовать JTable для отображения данных. Затем вы можете использовать JDialog для запроса данных, а затем добавить данные в JTable. Управлять этим гораздо проще, чем пытаться добавлять / удалять панели.

...