Обновление динамического TextArea в Java

Я пытаюсь создать простой текстовый редактор с динамической текстовой областью в Java.

Приложение вначале имеет только 1 текстовую область. Каждый раз, когда я нажимаю клавишу ENTER, приложение создает новую текстовую область. Это работает! РЖУ НЕ МОГУ. Но когда я пытаюсь изменить предыдущую текстовую область, эта текстовая область не изменилась. И проблема в том, что моя предыдущая текстовая область уже была в контейнере. Итак, мой вопрос: как мы обновляем всю текстовую область в контейнере?

Посмотрите на мой код:

    import javax.swing.*;
    import javax.swing.text.*;
    import java.awt.*;
    import java.io.*;
    import java.awt.event.*;

    public class SimpleEditor extends JFrame {

            int count = 0;
            Container content = getContentPane();

            private JTextComponent[] textComp;

            public static void main(String[] args) {
                    SimpleEditor editor = new SimpleEditor();
                    editor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    editor.setVisible(true);
            }

            // Create an editor.
            public SimpleEditor() {
                    super("Swing Editor");
                    dinamicTA();
                    content.setLayout(new FlowLayout());

                    for(int i=0;i<count;i++) {
                            content.add(textComp[i]);
                    }

                    pack();
                    content.setSize(content.getPreferredSize());
                    pack();
            }

            //create DINAMIC TEXT AREA
            public void dinamicTA () {
                    if(count==0) {
                            textComp = new JTextComponent[1];
                            textComp[0] = createTextComponent();
                            count+=1;
                    }
                    else {
                            JTextComponent[] texttemp;
                            texttemp = new JTextComponent[count];
                            for(int i=0;i<count;i++) {
                                    texttemp[i] = createTextComponent();
                            }
                            count+=1;
                            textComp = new JTextComponent[count];
                            for(int i=0;i<count-1;i++) {
                                    textComp[i] = createTextComponent();
                                    //textComp[i].setText(texttemp[i].getText()+"wow"); <-- not working
                            }
                            textComp[count-1] = createTextComponent();
                            content.add(textComp[count-1]);
                    }
            }

            // Create the JTextComponent subclass.
            protected JTextComponent createTextComponent() {
                    JTextArea ta = new JTextArea();
                    if (count%2==0)
                            ta.setForeground(Color.red);
                    else
                            ta.setForeground(Color.GREEN);
                    ta.setFont(new Font("Courier New",Font.PLAIN,12));
                    ta.setLineWrap(true);                                                                                                                           
                    ta.setWrapStyleWord(true);  
                    ta.addKeyListener(new java.awt.event.KeyAdapter() {
                            public void keyReleased(java.awt.event.KeyEvent ev) {
                                    taKeyReleased(ev);
                            }
                    });

                    ta.setColumns(15);
                    pack();
                    ta.setSize(ta.getPreferredSize());
                    pack();

                    return ta;
            }

            private void taKeyReleased(java.awt.event.KeyEvent ev) { 
                    int key = ev.getKeyCode();
                    if (key == KeyEvent.VK_ENTER) {
                            dinamicTA();

                            pack();
                            content.setSize(content.getPreferredSize());
                            pack();
                    }
            }
    }

И еще 2 вопроса. Каждый раз, когда я нажимаю клавишу ENTER, создается текстовая область, а предыдущая текстовая область получает разрывную линию. Есть ли у вас идея удалить линию разрыва? Следующий вопрос: как перейти к следующей текстовой области после нажатия клавиши ENTER, не нажимая новую текстовую область?

Извините, слишком много вопросов.. хахаха. Спасибо раньше :)


person TblsX    schedule 25.05.2013    source источник


Ответы (2)


Для ваших первых вопросов я изменил код как `

import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;

public class SimpleEditor extends JFrame {

        /**
     * 
     */
    private static final long serialVersionUID = 1L;
        int count = 0;
        Container content = getContentPane();

        private JTextComponent[] textComp;
        // Create an editor.
        public SimpleEditor() {
                super("Swing Editor");
                dinamicTA();
                content.setLayout(new FlowLayout());

                for(int i=0;i<count;i++) {
                        content.add(textComp[i]);
                }

                pack();
                content.setSize(content.getPreferredSize());
                pack();
        }

        //create DINAMIC TEXT AREA
        public void dinamicTA () {
                if(count==0) {
                        textComp = new JTextComponent[1];
                        textComp[0] = createTextComponent();
                        count+=1;
                }
                else {
                        JTextComponent[] texttemp;
                        texttemp = textComp;
                        count+=1;
                        textComp = new JTextComponent[count];
                        for(int i=0;i<count-1;i++) {
                                textComp[i] = texttemp[i];
                                textComp[i].setText(textComp[i].getText()+"wow"); //<-- not working
                        }
                        textComp[count-1] = createTextComponent();
                        content.add(textComp[count-1]);
                        textComp[count-1].requestFocus(); //get focus
                }
        }

        // Create the JTextComponent subclass.
        protected JTextComponent createTextComponent() {
                final JTextArea ta = new JTextArea();
                if (count%2==0)
                        ta.setForeground(Color.red);
                else
                        ta.setForeground(Color.GREEN);
                ta.setFont(new Font("Courier New",Font.PLAIN,12));
                ta.setLineWrap(true);                                                                                                                           
                ta.setWrapStyleWord(true);  
                ta.addKeyListener(new java.awt.event.KeyAdapter() {
                        public void keyReleased(java.awt.event.KeyEvent ev) {
                                taKeyReleased(ev);
                        }
                });

                ta.setColumns(15);
                pack();
                ta.setSize(ta.getPreferredSize());
                pack();

                return ta;
        }

        private void taKeyReleased(java.awt.event.KeyEvent ev) { 
                int key = ev.getKeyCode();
                if (key == KeyEvent.VK_ENTER) {
                        dinamicTA();
                        pack();
                        content.setSize(content.getPreferredSize());
                        pack();
                }
        }

        public static void main(String[] args) {
            SimpleEditor editor = new SimpleEditor();
            editor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            editor.setVisible(true);
    }    
}

`

Я думаю, что проблема с исходными кодами заключается в следующем: каждый раз, когда вы добавляете новые компоненты, он теряет ссылку на предыдущие компоненты.

person Robin    schedule 25.05.2013
comment
СПАСИБО!! Как насчет второго и третьего вопроса... LOL. Кстати, вы можете объяснить эту строку private static final long serialVersionUID = 1L;? - person TblsX; 25.05.2013
comment
У меня есть идея для второго вопроса. Если я смогу вставить backspace в строку textarea, я получу ответ! Ты можешь это сделать? - person TblsX; 25.05.2013
comment
вы можете удалить 'private static final long serialVersionUID = 1L;' , я добавил это из-за предупреждения. Я только что обновил код для вашего вопроса 2 и 3, вы можете проверить его еще раз, чтобы увидеть, решает ли он вашу проблему. Решение - requestFocus() - person Robin; 25.05.2013
comment
Хороший! Еще один вопрос..хахахаха. Предположим, у нас уже есть 3 текстовые области. Можем ли мы определить, какую текстовую область мы сейчас используем? Итак, я хочу изменить текстовую область динамического массива на список. И с этим я могу вставить новую текстовую область в средний список. Но я не знаю, как узнать индексы предыдущей текстовой области. Предположим, я нажимаю вторую текстовую область. Результат будет: TextArea1 - TextArea2 - TextArea4 - TextArea3 - person TblsX; 26.05.2013
comment
Чтобы определить, какая текстовая область используется, я думаю, что метод getFocusOwner(), вы можете обратиться к следующей ссылке для API: getFocusOwner(). - person Robin; 27.05.2013

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

Если вы хотите динамически создать текстовую область, используйте динамическое хранилище, например ArrayList. Затем вы просто добавляете только что созданную текстовую область в ArrayList. Итак, в качестве переменной класса вы создаете ArrayList, например:

ArrayList<JTextComponent> components = new ArrayList<JTextComponent>();

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

components.add(...);

Я позволю вам взглянуть на API, чтобы узнать, как «получить» элемент из ArrayList.

Каждый раз, когда я нажимаю клавишу ENTER, создается текстовая область, а предыдущая текстовая область получает разрывную линию. Есть ли у вас идея удалить линию разрыва?

Действие по умолчанию для клавиши Enter добавляет строку новой строки в текстовую область. Это действие все еще выполняется вместе с KeyListener

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

Action enter = new AbstractAction()
{
    public void actionPerformed(ActionEvent e)
    {
        // add your MouseListener code here
    }
});
textArea.getActionMap().put("insert-break", enter);

См. привязки клавиш для получения дополнительной информации, включая ссылку на руководство по Swing. о привязках клавиш.

person camickr    schedule 25.05.2013