Изменить JTextField из другого класса Java/BlueJ

Я работаю над проектом с JFrame (впервые). У меня есть несколько JTextFields и 1 JButton на рамке. Итак, что я пытаюсь сделать, это отредактировать текст моего JTextField из другого класса. Я ввожу 2 значения в JTextField и хочу, чтобы результат отображался в другом JTextField.

Всякий раз, когда я нажимаю кнопку, я хочу, чтобы одно текстовое поле JTextField9 было изменено на значение, которое я вычислил в методе другого моего класса (в данном случае метод totalHours() в модуле).

Я пробовал много примеров, которые я нашел, но ни один из них, кажется, не работал для меня T_T.

Вот код, с которым у меня проблемы.

Класс графического интерфейса:

private JButton button1;
private JTextField textfield5; // First value
private JTextField textfield7; // Second value
public JTextField textfield9;  // Outcome - I made it public because I would get an error of 'cannot find symbol setText()' in the Module Class (totalHours() method)

// So when I click on the Button I want the textfield9 to show the method (totalHours()) from the Module class
button1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent evt) 
        {
            Module module = new Module();
            int text = module.totalHours();
            String textt = Integer.valueOf(text).toString();
            textfield9.setText(textt);
        }
    });

Класс модуля:

Это результат, который я хочу, чтобы он отображался в текстовом поле9 всякий раз, когда я нажимаю кнопку на фрейме.

public int totalHours()
{
    int num1 = Integer.parseInt(getHoursWeek());        // getter from GUI Class - textfield5
    int num2 = Integer.parseInt(getTotalWeeksCourse()); // getter from GUI Class - textfield7
    int num3 = num1 * num2;
    gui.textfield9.setText(Integer.toString(num3));
    return num3;
}

Я не знаю почему, но в textfield9 ничего не отображается, вместо этого открывается другой JFrame с 2 исключениями:

Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: ""
at Module.totalHours(Module.java:49)
at GUI$1.actionPerformed(GUI.java:67)

Вот эти 2 строчки:

int num1 = Integer.parseInt(getHoursWeek()); // Module Class totalHours() method
int text = module.totalHours();  // GUI Class button1 actionlistener

Вот полный код обоих классов. Удаление ненужных строк.

Класс графического интерфейса:

public class GUI extends JFrame 
{
    private JMenuBar menuBar;
    private JButton button1;
    private JLabel label5;
    private JLabel label7;
    private JLabel label9;
    private JTextField textfield5;
    private JTextField textfield7;
    public JTextField textfield9;

//Constructor 
public GUI()
{        
    setTitle("GUI");
    setSize(468,400);

    //pane with null layout
    JPanel contentPane = new JPanel(null);
    contentPane.setPreferredSize(new Dimension(468,400));
    contentPane.setBackground(new Color(192,192,192));

    button1 = new JButton();
    button1.setBounds(181,332,127,44);
    button1.setText("Invoer");

    button1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent evt) 
        {
            Module module = new Module();
            int text = module.totalHours();
            String textt = Integer.valueOf(text).toString();
            textfield9.setText(textt);
        }
    });

    label5 = new JLabel();
    label5.setBounds(5,115,94,31);
    label5.setText("Module Nummer");

    label7 = new JLabel();
    label7.setBounds(274,14,156,33);
    label7.setText("Per module");

    label9 = new JLabel();
    label9.setBounds(276,57,90,35);
    label9.setText("Totaal uren");

    textfield5 = new JTextField();
    textfield5.setBounds(120,225,90,35);

    textfield7 = new JTextField();
    textfield7.setBounds(120,280,90,35);

    textfield9 = new JTextField();
    textfield9.setBounds(361,57,90,35);

    //adding components to contentPane panel
    contentPane.add(button1);
    contentPane.add(label5);
    contentPane.add(label7);
    contentPane.add(label8);
    contentPane.add(label9);
    contentPane.add(textfield5);
    contentPane.add(textfield7);
    contentPane.add(textfield9);

    //adding panel to JFrame and seting of window position and close operation
    getContentPane().add(contentPane);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    pack();
    setVisible(true);

    //initGUI();
}

 public static void main(String[] args)
 {
    System.setProperty("swing.defaultlaf", "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() 
        {
            new GUI();
        }
    });
}

public String getTextfield1()
{
    String txtfield1 = textfield1.getText();
    return txtfield1;
}

public String getTextfield2()
{
    String txtfield2 = textfield2.getText();
    return txtfield2;
}

public String getTextfield3()
{
    String txtfield3 = textfield3.getText();
    return txtfield3;
}

public String getTextfield4()
{
    String txtfield4 = textfield4.getText();    
    return txtfield4;
}

public String getTextfield5()
{
    String txtfield5 = textfield5.getText();
    return txtfield5;
}

public String getTextfield7()
{
    String txtfield7 = textfield7.getText();
    return txtfield7;
}

public String getTextfield9()
{
    String txtfield9 = textfield9.getText();
    return txtfield9;
}
}

Класс модуля:

public class Module
{
private GUI gui;

/**
 * Constructor for objects of class Module
 */
public Module()
{
    gui = new GUI();
}

public String getCourseName()
{
    return gui.getTextfield1();
}

public String getSchoolDays()
{
    return gui.getTextfield2();
}

public String getModuleNumber()
{
    return gui.getTextfield3();
}

public String getWeekNumber()
{
    return gui.getTextfield4();
}

public String getHoursWeek()
{
    return gui.getTextfield5();
}

public String getTotalWeeksCourse()
{
    return gui.getTextfield7();
}

public int totalHours()
{
    int num1 = Integer.parseInt(getHoursWeek());    
    int num2 = Integer.parseInt(getTotalWeeksCourse());
    int num3 = num1 * num2;
    gui.textfield9.setText(Integer.toString(num3));
    return num3;
}
}

Извините, если трудно понять, что я пытаюсь сказать, никогда не умел хорошо объяснять. Может ли кто-нибудь помочь мне с этим!?


person SC92    schedule 13.01.2015    source источник
comment
Вы пытались сначала установить текст в исходном классе? Я имею в виду, что не пытаюсь установить текст из другого класса, но можете ли вы сначала изменить его из исходного класса? Если это так, и это работает, создайте общедоступный метод в исходном классе, который устанавливает текст, а затем используйте этот метод во втором классе.   -  person DreadHeadedDeveloper    schedule 13.01.2015
comment
Я бы предложил дополнительную помощь, но это дамп кода, его действительно сложно читать или понимать. Используйте его, когда задаете вопросы google.com/   -  person DreadHeadedDeveloper    schedule 13.01.2015
comment
Набор текста @DreadHeadedDeveloper из графического интерфейса действительно работает, но я не уверен, что вы имеете в виду с общедоступным методом.   -  person SC92    schedule 13.01.2015
comment
У вас есть класс 1 и класс 2, класс 1 отлично изменяет текст, а класс 2 - нет, верно?   -  person DreadHeadedDeveloper    schedule 13.01.2015
comment
@DreadHeadedDeveloper Да, действительно. Если я попытаюсь изменить текст в самом классе графического интерфейса, он сработает (с помощью кнопки actionlisteren).   -  person SC92    schedule 13.01.2015
comment
Затем создайте метод в классе 1, который делает именно это, изменяет текст, делает его публичным методом, а затем вызывает этот метод в классе 2. Я хотел упомянуть pack() или repaint(), но это может сделать вещи более трудно для вас. Простой и простой способ таков: если он работает на c1, но не на c2, сделайте его метод в c1, а затем вызовите его из c2.   -  person DreadHeadedDeveloper    schedule 13.01.2015
comment
@DreadHeadedDeveloper Итак, я сделал его метод в классе GUI (public void), назвал его в классе Module с public void, но я все еще получаю сообщение об ошибке: java.lang.NumberFormatException: для входной строки:   -  person SC92    schedule 13.01.2015
comment
неважно, теперь я вижу это, хорошо, это проблема с входящими данными. Исключением является то, что он не может проанализировать строку по какой-либо причине. Сделайте мне одолжение, вызовите System.out.println() и в скобках распечатайте данные, которые вы пытаетесь проанализировать.   -  person DreadHeadedDeveloper    schedule 13.01.2015
comment
Лол, мой плохой друг, это совсем другая проблема, которую я пытался решить для тебя.   -  person DreadHeadedDeveloper    schedule 13.01.2015
comment
У меня есть это в классе GUI: public void invoer(). Класс модуля: public void total(){gui.invoer();}. Программа работает. но когда я пытаюсь получить значение в текстовом поле9 после нажатия кнопки, он открывает другой JFrame (не знаю, почему), и ошибка говорит: Исключение в потоке AWT-EventQueue-0 java.lang.NumberFormatException: для входной строки:   -  person SC92    schedule 13.01.2015
comment
Верно, я отредактировал свой пост, вызовите System.out.println() перед той строкой, где вы разбираете, и в скобках введите данные, которые вы пытаетесь разобрать, а именно: gethours   -  person DreadHeadedDeveloper    schedule 13.01.2015
comment
Бесконечный цикл открытия новых окон JFrame. Нет ли другого способа сделать расчет во втором классе и settext в классе GUI?   -  person SC92    schedule 13.01.2015
comment
@DreadHeadedDeveloper, можно ли привести пример с settext из другого класса?   -  person SC92    schedule 13.01.2015
comment
Я запутался, что вы подразумеваете под бесконечными циклами? Он начал выплевывать бесконечные циклы новых JFrames после того, как вы ввели этот System.out.println?   -  person DreadHeadedDeveloper    schedule 13.01.2015
comment
@DreadHeadedDeveloper Да, после этой строки открывается бесконечное количество новых JFrames. Не знаю, почему он все равно открывается в новом JFrame.   -  person SC92    schedule 13.01.2015
comment
И если вы удалите эту строку, она перестанет делать бесконечные циклы?   -  person DreadHeadedDeveloper    schedule 13.01.2015
comment
@DreadHeadedDeveloper Да, это так. Теперь он открывает только еще 1 JFrame после нажатия кнопки.   -  person SC92    schedule 13.01.2015
comment
???? Ад? Хорошо, опубликуйте весь код, я сам запускаю это.... теперь мне просто любопытно   -  person DreadHeadedDeveloper    schedule 13.01.2015
comment
@DreadHeadedDeveloper мой полный код доступен выше. Последние 2 блока кода. У меня нет с ним импорта.   -  person SC92    schedule 13.01.2015
comment
понял, дай мне секунду, плохо отвечу, как только разберусь   -  person DreadHeadedDeveloper    schedule 13.01.2015
comment
@DreadHeadedDeveloper Спасибо. Я думаю, вам следует добавить импорт, потому что я не включил их.   -  person SC92    schedule 13.01.2015
comment
К сожалению, извините, я не заметил длинного разговора во время составления ответа. Извините, @DreadHeadedDeveloper - я думаю, вы пришли к тому же, что и я.   -  person J Richard Snape    schedule 13.01.2015
comment
Не извиняйтесь, вы сначала решили ответ, и тоже довольно хорошо. Нужно больше людей, как вы на SO   -  person DreadHeadedDeveloper    schedule 13.01.2015


Ответы (1)


Проблема с вашим кодом заключается в том, что вы создаете новый объект Module в своем внутреннем классе ActionListener каждый раз, когда вы нажимаете кнопку, которая, в свою очередь, создает новый объект GUI и т. д. У вас также есть неприятный потенциальный цикл - если вы переместите модуль из ActionListener, он создаст новый графический интерфейс, который создаст новый модуль, создаст новый графический интерфейс и так далее...

Есть несколько вопросов - я буду решать их по одному:

Циклическая ссылка

Не создавайте новый графический интерфейс для каждого модуля и новый модуль для каждого графического интерфейса. Вместо этого — поле для ссылки на GUI и метод setGUI() в модуле:

public class Module
{
    private GUI gui;

    public void setGUI(GUI myGUI)
    {
        this.gui = myGUI;
    }
 ... // rest of Module class

вызовите это из конструктора GUI, т.е.

module.setGUI(this);

Создание объектов Module в ActionListener

Тогда проблема с этим блоком кода:

   button1.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent evt) 
    {
        Module module = new Module();
        int text = module.totalHours();
        String textt = Integer.valueOf(text).toString();
        textfield9.setText(textt);
    }
});

В частности - эта строка:

Module module = new Module();

Вам нужен один экземпляр объекта Module, на который ссылается ваш объект GUI. Затем вы каждый раз считываете значение totalHours из одного и того же объекта. Есть несколько разных вариантов, как это сделать — я предложу один:

  1. Иметь модуль как поле в вашем классе графического интерфейса
  2. Сделать класс GUI реализующим ActionListener
  3. добавьте свой метод actionPerformed в класс GUI:

    public void actionPerformed(ActionEvent evt) { int text = module.totalHours(); String textt = Integer.valueOf(text).toString(); textfield9.setText(textt); }

  4. замените текущий код для добавления прослушивателя действий на button1.addActionListener(this);

Исключение при получении ничего из метода totalHours()

Понимаете

Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: ""

Если вы посмотрите на трассировку стека, вы найдете что-то вроде:

at Module.totalHours(Module.java:49)

Когда вы смотрите на свой метод totalHours(), он читает текстовые поля графического интерфейса и пытается преобразовать их в целые числа. Они пусты (если вы ничего в них не ввели), поэтому parseInt пытается создать целое число из пустой строки (""). Вам нужно добавить некоторую проверку ошибок к этому методу.

person J Richard Snape    schedule 13.01.2015
comment
буквально начал выписывать одно и то же решение.... Ну ладно, хорошо сформулировано и по делу, +1 - person DreadHeadedDeveloper; 13.01.2015
comment
@JRichardSnape Спасибо, что уделили время изучению моего кода, я очень ценю это. Я реализовал ваш ответ, по крайней мере, я пытался. Я добавил метод setGUI() в класс Module и module.setGUI(this); в конструктор графического интерфейса. Я переместил «Модульный модуль = новый модуль ();» в поля графического интерфейса, но теперь я получаю сообщение об ошибке «StackOverFlow sun.awt.Win32GraphicsConfig» всякий раз, когда пытаюсь запустить программу. Он начинается с конструктора графического интерфейса. Я попытался удалить «GUI gui = new GUI();» из класса модуля, но тогда setGUI() не будет работать. Какие-либо предложения? - person SC92; 13.01.2015
comment
@DreadHeadedDeveloper Спасибо и вам за то, что уделили время! Но у меня все еще есть некоторые ошибки, к сожалению. - person SC92; 13.01.2015
comment
Извините, я забыл сказать, что вам нужно удалить GUI gui = new GUI(); из класса модуля. Вам нужно заменить его на GUI gui;, т. е. у вас все еще есть поле в модуле, содержащее ссылку на графический интерфейс, но вы не инициализируете его каждый раз, когда создается экземпляр объекта модуля. Я отредактирую ответ. - person J Richard Snape; 13.01.2015
comment
@JRichardSnape Большое спасибо за ваше время и помощь! Вы оба. Теперь это работает! Благодарю вас! - person SC92; 13.01.2015