2012-07-09 2 views
9

나는 결국 HTML 링크를 보여주고 싶은 간단한 채팅 프로그램을 만들고 있습니다. 내 문제는 바로 내가 원하는대로 사용자 이름 옆에 텍스트를 표시 할 수 없다는 것입니다.JTextPane/JEditorPane 및 이상한 텍스트 문제

사용자 이름을 굵게 표시하고 텍스트를 바로 옆에 표시하고 싶지만 굵게 표시되지 않은 텍스트가 가운데에 표시됩니다.

사용자 이름을 굵게 표시하지 않으면 정상적으로 작동합니다. 상위 2 가지는 이름이 굵게 표시 될 때, 중간은 이름이 굵게 표시되지 않을 때, 밑줄은 중간 2처럼 표시되도록 하이퍼 링크를 표시하지만 이름은 굵게 표시됩니다. 여기

enter image description here

내가 뭘 잘못 코드인가? JTextPane를 JEditorPane로 바꾸려고 시도했는데 같은 일이 발생합니다.

package com.test; 

import java.awt.BorderLayout; 
import java.awt.Color; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextPane; 
import javax.swing.WindowConstants; 
import javax.swing.event.HyperlinkEvent; 
import javax.swing.event.HyperlinkEvent.EventType; 
import javax.swing.event.HyperlinkListener; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.SimpleAttributeSet; 
import javax.swing.text.StyleConstants; 
import javax.swing.text.html.HTML; 

public class JTextPaneTest extends JPanel { 

    JTextPane pane; 

    public JTextPaneTest() { 
     this.setLayout(new BorderLayout()); 

     pane = new JTextPane(); 
     pane.setEditable(false); 
     pane.setContentType("text/html"); 

     JScrollPane scrollPane = new JScrollPane(pane); 
     this.add(scrollPane, BorderLayout.CENTER); 

     pane.addHyperlinkListener(new HyperlinkListener() { 

      @Override 
      public void hyperlinkUpdate(HyperlinkEvent e) { 
       if (e.getEventType() == EventType.ACTIVATED) { 
        System.out.println(e.getDescription()); 
       } 

      } 
     }); 

    } 

    public void chatWithBold(String user, String text) { 

     SimpleAttributeSet bold = new SimpleAttributeSet(); 
     StyleConstants.setBold(bold, true); 

     SimpleAttributeSet normal = new SimpleAttributeSet(); 

     try { 
      pane.getDocument().insertString(pane.getDocument().getLength(), 
        user + ": ", bold); 
     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     try { 
      pane.getDocument().insertString(pane.getDocument().getLength(), 
        text + "\n", normal); 
     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    public void chatNoBold(String user, String text) { 

     SimpleAttributeSet bold = new SimpleAttributeSet(); 
     StyleConstants.setBold(bold, true); 

     SimpleAttributeSet normal = new SimpleAttributeSet(); 

     try { 
      pane.getDocument().insertString(pane.getDocument().getLength(), 
        user + ": ", normal); 
     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     try { 
      pane.getDocument().insertString(pane.getDocument().getLength(), 
        text + "\n", normal); 
     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    private void submitALinkWithBold(String user, String link) { 
     SimpleAttributeSet bold = new SimpleAttributeSet(); 
     StyleConstants.setBold(bold, true); 

     try { 
      pane.getDocument().insertString(pane.getDocument().getLength(), 
        user + ": ", bold); 
     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     SimpleAttributeSet attrs = new SimpleAttributeSet(); 
     attrs.addAttribute(HTML.Attribute.HREF, link); 

     SimpleAttributeSet htmlLink = new SimpleAttributeSet(); 
     htmlLink.addAttribute(HTML.Tag.A, attrs); 
     StyleConstants.setUnderline(htmlLink, true); 
     StyleConstants.setForeground(htmlLink, Color.BLUE); 
     try { 
      pane.getDocument().insertString(pane.getDocument().getLength(), 
        link + "\n", htmlLink); 
     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 

     JTextPaneTest chat = new JTextPaneTest(); 
     frame.add(chat); 

     frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 

     chat.chatWithBold("User1", "Hi everyone"); 
     chat.chatWithBold("User2", "Hey.. Hows it going"); 

     chat.chatNoBold("User1", "Hi everyone"); 
     chat.chatNoBold("User2", "Hey.. Hows it going"); 

     chat.submitALinkWithBold("User1", "http://www.stackoverflow.com"); 

     frame.setSize(400, 400); 

     frame.setVisible(true); 

    } 

} 
+2

잘 작동하고 짧은 데모 프로그램을 게시하기 위해 1+, 문제를 잘 보여주는 프로그램. –

+1

저는 JTextPane 전문가는 아니지만 'pane.setContentType ("text/html");'행을 주석 처리하면 문제가 사라지는 것에 유의합니다. –

+0

그래, 문제가 해결되었다는 사실을 알고 있습니다. 하이퍼 링크를 표시 할 수 있어야하기 때문에 text/html을 사용하고 있습니다. 텍스트/html로만 작동하는 것 같습니다. – systemoutprintln

답변

3

난 그냥 놀고 조금 주위를 검색하고 다음과 같은 솔루션을 발견 : 초기화

당신의 JTextPane이 같은과 콘텐츠 형식을 설정 한 후 : 그 초기화 후

final String emptyHtml = "<html><body id='bodyElement'></body></html>"; 
pane.getEditorKit().read(new StringReader(emptyHtml), pane.getDocument(), 0); 

다음 두 개의 새로운 필드 (편의상 단지 메서드에 사용됩니다) :

this.doc = (HTMLDocument) pane.getDocument(); 
this.bodyElement = this.doc.getElement("bodyElement"); 

지금이처럼 방법 submitALinkWithBold을 변경할 수 있습니다

final String html = "<p><b>" + user + ": </b>" 
    + "<a href='" + link + "'>" + link + "</a></p>"; 
doc.insertBeforeEnd(bodyElement, html); 

당신은 너무 다른 두 가지 방법 (chatWithBoldchatNoBold)에이 방식을 채택 할 수 있어야한다.

모든 방법을 변경하기 전까지는 결과가 좋지 않거나 전혀 작동하지 않습니다. 또한 모든 메서드를 변경 한 후에도 원래 예제처럼 보이지 않습니다 (큰 줄 간격, 다른 글꼴 ...). 나는 이것이 에 pane.getEditorKit()을 주조하고 그것의 setStyleSheet(…) 방법을 사용하여 해결할 수 있다고 생각하지만 나는 이것을 시도하지 않았다.

관련 문제