Доступ к экземпляру JTextArea из другого класса в цикле массива. Каков наилучший способ?

#java #arrays #swing

#java #массивы #swing

Вопрос:

У меня возникли проблемы с концептуальным пониманием того, как заставить мое приложение работать.

У меня есть 15 компонентов JTextField, 15 компонентов JButton и 1 JTextArea. Я хочу, чтобы каждая кнопка вставляла текст внутри текстовой области из каждого соответствующего текстового поля.

Если вы хотите увидеть графику, объясняющую эту настройку — [http://i.imgur.com/Vnc3C.png ]здесь1

Мне удалось получить frame.finaltext в классе Curriculum subject, но он не отображается внутри метода actionPerformed.

Каков наилучший способ получить доступ к frame.finaltext.append(текстовые поля[i])

ТИА Адам

     import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import net.miginfocom.swing.MigLayout;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.JButton;
    import java.awt.Dimension;

    public class CurriculumSubject extends JPanel implements ActionListener{
    /**
     * This is an class that will hold  details for each subject. 
     */

    // First we want some variables 
    String subjectName;

    public CurriculumSubject (final JReport frame){
        MigLayout layout = new MigLayout("wrap 2");//, debug 4000");
        this.setLayout(layout);
        final JTextField [] textfields = new JTextField[15];
        JButton [] buttons = new JButton[15];

        for (int i=0;i<15;i  ){
            String content = "This is a test. "   i; 
            textfields[i] = new JTextField(content);
            this.add(textfields[i], "width 500:700:1000");
            buttons[i] = new JButton(">>>");
            buttons[i].addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e){
                    //Execute when button is pressed
                    String text = textfields[i].getText();
                    frame.finaltext.append(text);
                }});
            buttons[i].setPreferredSize(new Dimension(10,10));  
            this.add(buttons[i]);
        }
    }
}
  

Ответ №1:

Хорошо, я думаю, я понял, чего вы хотели. Вы должны определить свою JTextArea как переменную класса, чтобы у вас был один ее экземпляр в одном объекте form, а затем вы просто добавляете текст к этому объекту. Пример с методом:

 public class CurriculumSubject extends JPanel implements ActionListener {

    private JTextArea mainArea = new JTextArea();

    public CurriculumSubject(final JReport frame) {
        MigLayout layout = new MigLayout("wrap 2");//, debug 4000");
        this.setLayout(layout);
        final JTextField[] textfields = new JTextField[15];
        JButton[] buttons = new JButton[15];

        for (int i = 0; i < 15; i  ) {
            String content = "This is a test. "   i;
            textfields[i] = new JTextField(content);
            this.add(textfields[i], "width 500:700:1000");
            buttons[i] = new JButton(">>>");
            buttons[i].addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    //Execute when button is pressed
                    String text = textfields[i].getText();
                    addTextToFinalArea(text);
                }
            });
            buttons[i].setPreferredSize(new Dimension(10, 10));
            this.add(buttons[i]);
        }
    }

    public void addTextToFinalArea(String text) {
        mainArea.append(text);
    }
}
  

Комментарии:

1. Спасибо за ваш ответ. Единственная проблема заключается в том, что mainArea декалируется в JReport, а не в классе CurriculumSubject. Я передал экземпляр JReport во фрейм JReport — реальная вещь, к которой я хочу получить доступ, — это frame.finaltext (который является экземпляром JReport, в котором есть экземпляр JTextArea).

2. Проделайте то же самое с классом JReport. Объявите JTextArea там как final переменную в списке переменных класса. А затем создайте метод в классе JReport: public void addTextToFinalArea(String text) { mainArea.append(text); } и тогда вы сможете получить текстовую область с помощью frame.addTextToFinalArea(text);

3. Спасибо — другой форум, который я просматриваю, предлагает это.getParent().

4. this.getParent() не всегда работает. Если вы поместите свою панель в другую панель, то getParent() вернет элемент JPanel, а не JFrame. Что бы я сделал (хотя я не знаю, лучшее ли это решение) — я бы создал один статический объект главного окна и вызывал его статически JFrameClassName.staticInstanceObject .

Ответ №2:

Я понятия не имею, что такое JReport, но почему бы вам не предоставить в нем метод для приема строки (или создать подкласс JReport, предоставляющий этот метод):

 class ReportThingy extends JReport {
   public void addText(String text) {
        finaltext.append(text);
   }
 }
  

Обновить:

Похоже, у вас много виджетов, за которыми нужно следить. Я бы рекомендовал ввести шаблон Model-View-Controller, чтобы сделать ваше приложение более управляемым. В краткосрочной перспективе вы можете попробовать сделать виджет finaltext доступным для класса CurriculumSubject через установщик или в качестве аргумента конструктора.

Комментарии:

1. JReport — это класс, который запускает все это (и содержит JTextArea, называемый finaltext). Изображение показывает, что здесь происходит — i.imgur.com/Vnc3C.png — область справа находится внутри JReport и является JTextArea, вкладки находятся в классе TabbedPane, и каждая панель TabbedPane является предметом учебной программы. Как мне получить доступ к JReport.finaltext (JTextArea) из экземпляров учебной программы? Спасибо

2. Спасибо — установщик и получатель кажутся подходящими — я думаю, я справляюсь с этим двумя разными методами. Однако к тому времени, когда я использую метод actionPerformed, получить экземпляр JReport становится сложно — но это не значит, что другой метод не смог бы получить доступ к нему. Имеет ли это смысл? Мне придется взглянуть на MVC — я знаком с ним по небольшой работе, которую я проделал с django несколько лет назад. Еще раз спасибо.

3. Я также получаю ошибки java.lang. Исключение ArrayIndexOutOfBoundsException — для массива — каждый раз, когда я нажимаю кнопку, i равен 15, и есть 15 элементов 0-14. Если я перемещу этот метод, я предполагаю, что смогу передать ему значение i .

Ответ №3:

Мне интересно, что компилятор не жалуется на ваш код: вы используете не окончательную локальную переменную i в вашей анонимной внутренней ActionListener реализации. Попробуйте сохранить i в конечной переменной и использовать ее во внутреннем классе:

 for (int i = 0; i < 15; i  ) {
...
  final int index = i;
  buttons[i].addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e){
      //Execute when button is pressed
      String text = textfields[index].getText();
      frame.finaltext.append(text   "n");
  }});
...
}