Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> HTML-теги в JTextPane 
V
    Опции темы
malah
Дата 17.4.2007, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 28.10.2006

Репутация: нет
Всего: нет



Я вас приветствую!
Прочитал тему и заинтересовался, ведь скоро самому бакалавра сдавать, суть похожа, но конь не валялся  smile 
Есть вот такая статейка тут .
А вот у меня какой вопрос: редактору передается HTML код, но не простой.... а именно в нем есть не простой тег(специальная конструкция), который запрещает редактировать текст внутри себя. Т.Е. необходимо чтобы этот текст отображался в JTextPane, но его нельзя было изменять, а все остальное можно... Кроме этого требуется ввести свой атрибут, с той же целью, но чтоб его можно было добавлять в обычные теги. Как сделать ума не приложу, может кто сможет мне помочь... С JAVA пока очень слабо знаком, читать в инсте будут только осенью :(
PM MAIL   Вверх
nornad
Дата 18.4.2007, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1079
Регистрация: 16.2.2007
Где: в Караганде

Репутация: 6
Всего: 31



На форумах на Sun'е я находил что-то про то, как добавить парсеру свой тэг. Я там до сих пор копаюсь, так что ежели снова увижу - дам ссылку.
Суть теории - сделать объект своего тэга на основе неизвестного, добавить в парсер и зарегистрировать его там. Насчёт перехвата обработки тэга не скажу, но возможность должна быть.

P.S. Вообще у меня сложилось впечатление, что визуальный редактор HTML на жабе делать почти никто не умеет. Ну практически совершенно нет в сети информации. smile

Добавлено через 2 минуты и 2 секунды
Цитата(malah @  18.4.2007,  00:49 Найти цитируемый пост)
ведь скоро самому бакалавра сдавать

Цитата(malah @  18.4.2007,  00:49 Найти цитируемый пост)
слабо знаком, читать в инсте будут только осенью :(

На бакалавра сдавать в конце будущего учебного года? Время, в принципе достаточно, чтобы нормально разобраться.


--------------------
Три достоинства программиста: Леность, Нетерпение и Гордость
Ларри Уолл
PM MAIL WWW ICQ Skype MSN   Вверх
malah
Дата 18.4.2007, 06:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 28.10.2006

Репутация: нет
Всего: нет



Цитата

На бакалавра сдавать в конце будущего учебного года?

Если бы, десятого мая (ЭТОГО ГОДА) нужно сдать в деканат тему и план... 
PM MAIL   Вверх
nornad
Дата 18.4.2007, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1079
Регистрация: 16.2.2007
Где: в Караганде

Репутация: 6
Всего: 31



malah, посмотри тут - что-то про нестандратные тэги.


--------------------
Три достоинства программиста: Леность, Нетерпение и Гордость
Ларри Уолл
PM MAIL WWW ICQ Skype MSN   Вверх
nornad
Дата 19.4.2007, 02:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1079
Регистрация: 16.2.2007
Где: в Караганде

Репутация: 6
Всего: 31



Два способа вставки гиперссылки:
1. используя insertHTML()
Код

                try {
                    int sels = textPane.getSelectionStart(), sele = textPane.getSelectionEnd();
                    int cpos = textPane.getCaretPosition();
                    HTMLEditorKit kit = (HTMLEditorKit) textPane.getEditorKit();
                    HTMLDocument doc = (HTMLDocument) textPane.getStyledDocument();
                    if ( sels == sele ) {
                        kit.insertHTML(
                                doc, 0 > cpos ? 0 : cpos,
                                "<a href='http://www.nornad.com/'>nornad website</a> ", 0, 0, HTML.Tag.A
                        );
                        textPane.setCaretPosition(cpos + "nornad website".length());
                        doc.insertString(cpos + "nornad website".length(), " ", null);
                    } else {
                        String html = "<a href='http://www.nornad.com/'>" + textPane.getSelectedText() + "</a>";
                        textPane.replaceSelection("");
                        kit.insertHTML(
                                doc, sels, html,
                                0, 0, HTML.Tag.A
                        );
                    }
                }
                catch( Throwable th ) {
                    th.printStackTrace();
                }

2. используя механизм стандартных тэгов эдиторкита (предпочтительнее)
Код

    protected void setAttributeSet( AttributeSet attr, boolean setParagraphAttributes )
    {
        HTMLEditorKit kit = (HTMLEditorKit) textPane.getEditorKit();
        HTMLDocument doc = (HTMLDocument) textPane.getStyledDocument();
        int xStart = textPane.getSelectionStart();
        int xFinish = textPane.getSelectionEnd();

        if ( setParagraphAttributes )
            doc.setParagraphAttributes(xStart, xFinish - xStart, attr, false);
        else if ( xStart != xFinish )
            doc.setCharacterAttributes(xStart, xFinish - xStart, attr, false);
        else {
            MutableAttributeSet inputAttributes = kit.getInputAttributes();
            inputAttributes.addAttributes(attr);
        }
    }

...
                try {
                    String newHref = "http://www.nornad.com/";
                    SimpleAttributeSet attr2 = new SimpleAttributeSet();
                    attr2.addAttribute(StyleConstants.NameAttribute, HTML.Tag.A);
                    attr2.addAttribute(HTML.Attribute.HREF, newHref);
                    setAttributeSet(attr2, true);
                    textPane.grabFocus();
                }
                catch( Throwable th ) {
                    th.printStackTrace();
                }


P.S. Не сочтите гиперссылки за рекламу - просто я у себя тестил так, а придумывать что-то другое лень. smile


--------------------
Три достоинства программиста: Леность, Нетерпение и Гордость
Ларри Уолл
PM MAIL WWW ICQ Skype MSN   Вверх
nornad
Дата 24.4.2007, 02:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1079
Регистрация: 16.2.2007
Где: в Караганде

Репутация: 6
Всего: 31



Пока что не могу победить закавыку с добавлением гиперссылки (или другого тэга со схожей структурой).
Заключается закавыка в том, что если перед добавлением курсор стоял в конце документа, то после добавления тэга не получается написать ничего за ним. Всё, что будете вводить, будет добавляться внутрь этого тэга.
А вот как выйти за его пределы?..

Кстати, при добавлении списков схожая проблема - новый текст будет добавляться в первый и единственный элемент списка. Сейчас пытаюсь сделать так, чтобы по нажатию Enter добавлялся новый элемент списка, но потом будет проблема определения, надо ли завершить список. И снова вернёмся к проблеме выхода за пределы последнего тэга. В общем, как-то странно Сановцы реализовали эту поделку... То ли они хтмл не любят, то ли лень им было нормально всё сделать...


--------------------
Три достоинства программиста: Леность, Нетерпение и Гордость
Ларри Уолл
PM MAIL WWW ICQ Skype MSN   Вверх
nornad
Дата 25.4.2007, 03:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1079
Регистрация: 16.2.2007
Где: в Караганде

Репутация: 6
Всего: 31



С установкой фона в редакторе интересная история.
Можно, конечно, утсановить с помощью setBackground(), но тогда цвет установится у компонента, а не в хтмле.
Попытки установить при помощи задания атрибутов ни к чему хорошему не приводят - либо не ставится, либо внутрь body вставляется параграф, содержащий ещё один body, у которого и будет проставлен цвет фона.
Сегодня нашёл на форумах Sun вариант установки фона через внутренности документа. Фон устанавливается прекрасно. Одна проблема - "отваливается" остальное, например, отображение списков.

В конце концов, я решил проблему радикально при помощи топора, зубила и напильника:
Код

String source = textPane.getText();
String color = Integer.toHexString(Color.BLUE.getRGB());
color = 6 >= color.length() ? color : color.substring(color.length() - 6);
source = source.replaceFirst("<body(\\s+bgcolor\\s*=\\s*#[0-9a-f]{1,6})?>", "<body bgcolor='#" + color + "'>");
try {
  textPane.read(new StringReader(source), null);
}
catch ( IOException e1 ) {
  e1.printStackTrace();
}



--------------------
Три достоинства программиста: Леность, Нетерпение и Гордость
Ларри Уолл
PM MAIL WWW ICQ Skype MSN   Вверх
nornad
Дата 26.4.2007, 03:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1079
Регистрация: 16.2.2007
Где: в Караганде

Репутация: 6
Всего: 31



Сегодня я расскажу, как работать с ненумерованными списками.
Вот как можно добавить список в редактор:
Код

                HTMLDocument doc = (HTMLDocument) editor.getStyledDocument();
                Element par = doc.getParagraphElement(editor.getSelectionStart());
                par = getParentTag( par, "body|ul" );
                Action action;
                if ( null == par || par.getName().equalsIgnoreCase("body") )
                    action = bulAction;
                else
                    action = ulAction;
                action.actionPerformed(null);
                jTextArea1.setText(editor.getText());
                editor.grabFocus();

...

    private HTMLEditorKit.InsertHTMLTextAction bulAction
            = new HTMLEditorKit.InsertHTMLTextAction("bBullets", "<ul><li></li></ul>\n", HTML.Tag.BODY, HTML.Tag.UL);
    private HTMLEditorKit.InsertHTMLTextAction ulAction
            = new HTMLEditorKit.InsertHTMLTextAction("Bullets", "<ul><li></li></ul>\n", HTML.Tag.LI, HTML.Tag.UL);

bulAction нужен для того, чтобы вставлять список на уровне тэга BODY, а ulAction - на уровне тэга LI (чтобы была возможность делать вложенные списки).
Если вам потребуется иметь возможность вставлять списки в другие тэги (например, в P), то потребуются соответствующие экшены.
Вообще, на мой взгляд, реализовали сановцы это дело довольно отвратно. Идея, может быть, изначально и была великолепной, но вот реализация...
Если вы ещё не догадались о чём, я - поясню. Допустим, у нас есть хтмл вида
Код

<htm>
<body>
  <p> </p>
</body>
</html>

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

<htm>
<body>
  <p> </p>
  <ul>
  <li>

  </li>
  </ul>
</body>
</html>

Несколько неожиданно, не правда ли?

Но это ещё не всё.
Мало просто добавить список в JTextPane. Для того, чтобы по нажатию Enter добавлялся новый элемент списка ("умолчальное" поведение сановской поделки - перевод строки), надо отлавливать нажатие клавиши, проверять, где мы находимся (в каком тэге) и производить магические пассы.
Вот пример, который приближает работу списка к том, что мы привыкли видеть в большинстве редакторов:
Код

        editor.addKeyListener(new KeyAdapter()
        {
            public void keyPressed( KeyEvent e ) {
                switch(e.getKeyCode()) {
                    case KeyEvent.VK_ENTER:
                        HTMLDocument doc = (HTMLDocument) editor.getStyledDocument();
                        int p = editor.getCaretPosition();
                        Element elem = doc.getParagraphElement(p);
                        try {
                            int start = elem.getStartOffset();
                            int end = elem.getEndOffset();
                            String s = doc.getText(start, end - start);
                            boolean empty = null == s || s.matches("\\s*");
                            e.setKeyCode(0);
                            e.setKeyChar('\0');
                            if ( !empty ) {
                                ulItemAction.actionPerformed(null);
                            }
                            p = editor.getCaretPosition();
                            elem = doc.getParagraphElement(p);
                            doc.remove(elem.getStartOffset(), elem.getEndOffset()-elem.getStartOffset());
                            jTextArea1.setText(editor.getText());
                        }
                        catch ( BadLocationException e1 ) {
                            e1.printStackTrace();
                        }
                        break;
                }
            }
        });

...

    private HTMLEditorKit.InsertHTMLTextAction ulItemAction
            = new HTMLEditorKit.InsertHTMLTextAction("Bullets item", "<li></li>", HTML.Tag.UL, HTML.Tag.LI,
                    HTML.Tag.BODY, HTML.Tag.UL);



--------------------
Три достоинства программиста: Леность, Нетерпение и Гордость
Ларри Уолл
PM MAIL WWW ICQ Skype MSN   Вверх
nornad
Дата 28.4.2007, 03:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1079
Регистрация: 16.2.2007
Где: в Караганде

Репутация: 6
Всего: 31



С отступами нашёл способ через стиль атрибута, но есть загвоздка - работает это дело на уровне стилей текста в компоненте, а в хтмл не попадает.
Если у кого-нибудь есть идеи, как сделать нормально - милости просим.
Я пытался делать через хтмл-атрибут style, но ничего не вышло - компонент просто проигнорировал установку атрибута.


--------------------
Три достоинства программиста: Леность, Нетерпение и Гордость
Ларри Уолл
PM MAIL WWW ICQ Skype MSN   Вверх
nornad
Дата 30.4.2007, 02:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1079
Регистрация: 16.2.2007
Где: в Караганде

Репутация: 6
Всего: 31



Вот код для организации отступов. Жаль, что нормального способа (чтобы он отражался в хтмле) я пока не нашёл.
Код

    class LeftIndentAction extends StyledEditorKit.StyledTextAction
    {
        private float value;

        public LeftIndentAction( String name, float value ) {
            super(name);
            this.value = value;
        }

        public void actionPerformed( ActionEvent e ) {
            if ( editor != null ) {
                StyledDocument doc = getStyledDocument(editor);
                int offset = editor.getCaretPosition();
                Element paragraph = doc.getParagraphElement(offset);
                AttributeSet as = paragraph.getAttributes();
                float indent = StyleConstants.getLeftIndent(as);
                indent += value;
                MutableAttributeSet attr = new SimpleAttributeSet();
                StyleConstants.setLeftIndent(attr, indent);
                setParagraphAttributes(editor, attr, false);
                jTextArea1.setText(editor.getText());
                editor.grabFocus();
            }
        }
    }

...

    Action increaseIndentAction = new LeftIndentAction("Indent", 40);
    Action decreaseIndentAction = new LeftIndentAction("Indent", -40);
    // или
    JButton button = new JButton(new LeftIndentAction("Indent", 40));


Добавлено через 3 минуты и 58 секунд
Думаю, на этом пока и закончу.
Вопрос помечу решённым, т.к., в принципе, основные цели достигнуты.


--------------------
Три достоинства программиста: Леность, Нетерпение и Гордость
Ларри Уолл
PM MAIL WWW ICQ Skype MSN   Вверх
jecl
Дата 19.3.2008, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 12.10.2007

Репутация: нет
Всего: нет



Привет!
Есть такой вопрос.
Как сказать JTextPane игнорировать незнакомые теги?
Например, сохранил я из опен офиса свой дукумент в хтмл, и пытаюсь отобрахить его в JTextPane. При запуске машина пишит и ничего не выводится.
А загвоздка в теге типа <META HTTP-EQUIV='CONTENT-TYPE' CONTENT='text/html; charset=utf-8'>. После их удаления, все ок.
спс.

Это сообщение отредактировал(а) jecl - 19.3.2008, 19:09
PM MAIL   Вверх
filipp76
Дата 22.3.2008, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 241
Регистрация: 4.4.2007
Где: Украина, Киев

Репутация: 1
Всего: 1



Меня интересует добавление гиперссылок, использовал первый метод из двух предложенных, все хорошо но при клике на гиперссылку ничего не открываеться )), как сделать чтоб ссылка открывалась в браузере по умолчанию? (Сафари, Опера и т.д.)
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.0560 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.