Обновить Jlist из другого JFrame

я хочу обновить JList, когда я нажимаю кнопку в другом JFrame.

Итак, у меня есть JFrame GuiBoss, который управляет сотрудниками (добавляет, удаляет, обновляет). Когда я нажимаю кнопку «Добавить», открывается другой Jframe, в котором я создаю нового сотрудника.

//Открываем "add_form", где я даю информацию о новом сотруднике.

private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {                                       
    GuiBoss gb = new GuiBoss(contrb,boss);
    Add_form af = new Add_form(gb,contrb,boss);
    af.setVisible(true);

}

//обновляем список добавленным новым сотрудником.

public void refresh(Employee e){
    System.out.println("I reach this point!");
    //if i print e.getName() it works, printing the right name that i give in the    "add_form"
    listModel.addElement(e);
    //listModel.clear(); //don't work either.

}

Моя проблема в том, что, когда я отправляю сведения о новом сотруднике, я вызываю функцию обновления (Employee e) из фрейма GuiBoss, на консоли появляется сообщение («Я достиг этой точки!»), Размер listModel изменяется , но список не обновляется. Также я должен сказать, что я правильно установил модель для списка.

//берем данные из формы и вызываем Refresh(Employee e) из основного фрейма("GuiBoss")

private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {                                       
    //String Id = txtID.getText();
    String UserName = txtName.getText();
    txtHour.setVisible(false);
    boolean b = false;
    if(rbtnYes.isSelected() == true){
        b = true;
    }
    if(rbtnNo.isSelected() == true){
        b = false;
    }
    if(rbtnYes.isSelected()==false && rbtnNo.isSelected() == false){
        System.out.println("Select the presence!");
    }
    else{
        txtOra.setVisible(true);
        String Hour = txtHour.getText();
        e = new Employee(UserName,b,Hour,boss);  //boss i get from main frame when i start this add new employee form
        contrb.addEmployee(e);
        gb.refresh(e);  //gb is of type GuiBoss were i have the function that does      
        // the refresh
    }  
}

Пожалуйста, дайте мне знать, если у вас есть идеи. Спасибо.


person user2271933    schedule 11.04.2013    source источник
comment
когда я нажимаю кнопку в другом JFrame Должен быть только один! См. Использование нескольких JFrames, хорошая/плохая практика?   -  person Andrew Thompson    schedule 12.04.2013


Ответы (1)


Вместо того, чтобы открывать еще один фрейм, почему бы не использовать модальное окно JDialog для сбора информации о новом сотруднике. Когда диалоговое окно закрыто, вы можете извлечь детали из диалогового окна и обновить список в текущем кадре.

Это предотвращает ненужное раскрытие частей вашего API.

Дополнительные сведения см. в разделе Как использовать диалоговые окна.

Обновлено

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

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListModel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestList03 {

    public static void main(String[] args) {
        new TestList03();
    }

    public TestList03() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private DefaultListModel model;

        public TestPane() {
            setLayout(new BorderLayout());
            model = new DefaultListModel();
            JList list = new JList(model);
            add(new JScrollPane(list));
            JButton btn = new JButton("Add");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    model.addElement("New Element");
                }
            });
            add(btn, BorderLayout.SOUTH);
        }

    }

}

Это предполагает, что есть что-то еще не так, что вы нам не показываете...

Обновлено с возможным исправлением проблем со ссылками

В основном это демонстрирует передачу ссылки на главную панель вспомогательной фабрике, которая отвечает за фактическое добавление значения обратно в основную панель. Обычно я бы использовал какой-нибудь interface вместо того, чтобы открывать всю панель, чтобы просто предоставить доступ к одному методу, но это был быстрый пример.

Он использует как обычный implements, так и внутренний класс как ActionListener, чтобы продемонстрировать два наиболее распространенных способа передачи ссылки на «я» другому классу.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListModel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestList03 {

    public static void main(String[] args) {
        new TestList03();
    }

    public TestList03() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel implements ActionListener {

        private DefaultListModel model;

        public TestPane() {
            setLayout(new BorderLayout());
            model = new DefaultListModel();
            JList list = new JList(model);
            add(new JScrollPane(list));

            JPanel buttons = new JPanel(new FlowLayout(FlowLayout.CENTER));

            JButton btn1 = new JButton("Add 1");
            btn1.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    new Factory(TestPane.this, "Added by Button 1");
                }
            });
            buttons.add(btn1);

            JButton btn2 = new JButton("Add 2");
            btn2.addActionListener(this);
            buttons.add(btn2);

            add(buttons, BorderLayout.SOUTH);
        }

        public void addItem(String text) {
            model.addElement(text);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            new Factory(TestPane.this, "Added by Button 2");
        }
    }

    public class Factory {

        public Factory(TestPane testPane, String text) {
            testPane.addItem(text);
        }
    }
}
person MadProgrammer    schedule 11.04.2013
comment
Если я работаю со своим списком и listModel в любое время, прежде чем я открою форму add_form, это работает. Я даже заполняю модель и список сотрудниками из репозитория, когда запускаются основные кадры. за наконечник). - person user2271933; 12.04.2013
comment
Похоже, у вас проблема со ссылкой. Я с подозрением отношусь к GuiBoss gb = new GuiBoss(contrb,boss); вызов - person MadProgrammer; 12.04.2013
comment
Я думаю, что вы правы, но мне нужно передать GuiBoss, потому что я должен вызвать функцию обновления из второго кадра. Или есть ли другой способ добавить в listModel из второго кадра (AddFrame), не вызывая основной? (ГиБосс)? - person user2271933; 12.04.2013
comment
Итак, предполагая, что метод actionPerformed находится внутри GuiBoss (либо напрямую, либо как внутренний класс), вы должны иметь возможность передать активную ссылку, используя либо this, либо GuiBoss.this, в зависимости от того, как определено actionPerformed. - person MadProgrammer; 12.04.2013
comment
Я добавил еще один пример, надеюсь, это поможет - person MadProgrammer; 12.04.2013
comment
Большое спасибо. С помощью этого второго примера мне удалось решить эту проблему. Действительно была проблема со ссылкой. Большое спасибо. - person user2271933; 12.04.2013