JPanel обновляется неправильно - PullRequest
0 голосов
/ 26 апреля 2020

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

Вот пример выполнения:

  • Добавлены 5 событий в 1 день ev, ev2, ev3, ev4, ev5 | Отображает 5 событий.
  • Затем удалите ev3 | Обновления только для отображения события 1.
  • Удалить ev 3 (было событие 4) | Отображает события в порядке ev, ev2, ev5, ev4.
  • Удалить событие 2 | Отображает события в порядке ev, ev5, ev3, ev4.
  • Удалить событие 1 | Отображает события в порядке ev, ev2, ev3, ev4.

Единственное оставшееся событие (ev5) все еще существует в массиве событий и обновляется до основного кадра, поэтому я знаю, что функциональность это работает. Я предполагаю, что я не добавляю их правильно или обновляю JPanel правильно. Любая информация помогает, так как я довольно новичок в этом, но вот пример кнопки удаления actionPerformed, где он обновляет панели.

if(e.getSource() == remove) {

    // Update main GUI

    String input = JOptionPane.showInputDialog(null, "What event number are you removing?");
    if(input == null) {
        return;
    }
    int response = -1;
    while (response == -1) {
        try {
            response = Integer.parseInt(input);
        } catch (NumberFormatException exception) {
            input = JOptionPane.showInputDialog(null, "Event number couldn't be read. Input numerical value.");
        }
    }
    response -= 1;
    try {
        current.removeEventFromDay(dayNumberInMonth, response);
    } catch (IllegalArgumentException exception) {
        JOptionPane.showMessageDialog(null, "This event didn't exist.");
        return;
    }
    BorderLayout layout = (BorderLayout) panel.getLayout();
    panel.remove(layout.getLayoutComponent(BorderLayout.CENTER));
    JPanel center = new JPanel(new GridLayout(6, 1, 10, 5));
    String[] events = current.getDayEvents(dayNumberInMonth);
    for(int i = 0; i < events.length; i++) {
        center.add(new JButton((i + 1 + ": ") + events[i]));
    }
    panel.add(center, BorderLayout.CENTER);
    frame.add(panel);
    frame.revalidate();
    frame.repaint();
    // Update other GUI
    JFrame otherFrame = calendar.getFrame();
    JPanel otherPanel = calendar.getPanel();
    int leadingDays = calendar.getLeadingDays();
    BorderLayout otherLayout = (BorderLayout) otherPanel.getLayout();
    otherPanel.remove(otherLayout.getLayoutComponent(BorderLayout.CENTER));
    JPanel otherCenter = new JPanel(new GridLayout(0, 7, 5, 5));
    for(int i = 0; i < leadingDays; i++) {
        otherCenter.add(new JButton());
    } 
    JButton[] dayBtns = new JButton[current.getMonthListLength()];
    for(int i = 0; i < current.getMonthListLength(); i++ ) {
        events = current.getDayEvents(i);
        String list = "";
        if(events.length > 1) {
            list = events[0] + "...";
        }
        if (events.length == 1) {
            list = events[0];
        }
        dayBtns[i] = new JButton();
        dayBtns[i].setLayout(new BorderLayout());
        JLabel label1 = new JLabel("" + (1 + i));
        JLabel label2 = new JLabel(list);
        dayBtns[i].add(label1, BorderLayout.NORTH);
        dayBtns[i].add(label2, BorderLayout.SOUTH);
        dayBtns[i].addActionListener(calendar);
        otherCenter.add(dayBtns[i]);
    }
    otherPanel.add(otherCenter, BorderLayout.CENTER);
    otherFrame.add(otherPanel);
    otherFrame.revalidate();
    otherFrame.repaint();
}

Редактировать: вот метод removeEventFromDay, но он не содержит функциональности скорее это гарантирует, что правильный объект дня используется. Итак, вот метод removeEvent из класса дня вместе с ним.

public void removeEventFromDay(int day, int event) {
    this.monthDays[day].removeEvent(event);
}

Обратите внимание, что этот метод расположен в классе дня, а предыдущий - в классе года.

public void removeEvent(int eventNumber) {

    if(events.length == 0) {
        throw new IllegalArgumentException("There are no events to remove");
    }
    if(eventNumber >= events.length || eventNumber < 0) {
        throw new IllegalArgumentException("This event doesn't exist");
    }

    events[eventNumber] = null;
    String list = "";
    for(int i = 0; i < events.length; i++) {
        if(events[i] != null) {
            list += events[i] + " | ";
        }
    }

    Scanner lineScanner = new Scanner(list);

    String[] temp = new String[events.length - 1];

    String sum = "";

    int i = 0;
    while(lineScanner.hasNext()) {

        String add = lineScanner.next();

        if(!add.equals("|")) {
            sum += add;
            if(lineScanner.hasNext()) {
                sum += " ";
            }
        } else {
            sum.trim();
            temp[i] = sum;
            i++;
            sum = "";
        }
    }

    events = new String[temp.length];

    for(int j = 0; j < temp.length; j++) {
        events[j] = temp[j];
    }
}

2nd Edit:

В итоге я просто создал новый объект Frame, когда он удалил событие и закрыл другой. Это исправило проблему и заставило ее корректно обновляться, но я так и не смог выяснить случайное появление кнопок предыдущих списков.

...