2012-08-27 22 views
5

Nie rozumiem zachowania zawijania w JTextPane. Jeśli wstawię krótki tekst, a następnie JComponent, a następnie ponownie krótki tekst, widzę wstawione rzeczy w jednej linii, jeśli ramka jest wystarczająco duża oczywiście. Ale jeśli tekst jest znacznie dłuższy, więc zajmuje kilka linii, komponent jest zawsze umieszczany w nowej linii.Jak zawijać tekst wokół komponentów w JTextPane?

Zrozumiałem, że po wstawieniu komponentu do JTextPane jego tekst jest dłuższy o jeden znak. Więc jeśli komponent jest rozpatrywany przez JTextPane jako postać, dlaczego nie zachowuje się jak postać? Czy to zależy od wersji java? Używam Java (TM) SE Runtime Environment (build 1.7.0-b147)

Poniżej jest mój kod (instancję zmiennej currentText z shortText/longtext do odtworzenia wymienionego zachowania):

import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTextPane; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.SimpleAttributeSet; 

public class Test { 
    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     JTextPane textPane = new JTextPane(); 
     textPane.setContentType("text/html"); 

     String shortText = "one two three four five six seven"; 
     String longText = "A text component that can be marked up with attributes that are represented graphically. You can find how-to information and examples of using text panes in Using Text Components, a section in The Java Tutorial. This component models paragraphs that are composed of runs of character level attributes. Each paragraph may have a logical style attached to it which contains the default attributes to use if not overridden by attributes set on the paragraph or character run. Components and images may be embedded in the flow of text."; 
     String currentText = shortText; 

     try { 
      // insert text before the component 
      textPane.getDocument().insertString(textPane.getDocument().getLength(), currentText, 
        new SimpleAttributeSet()); 

      textPane.setSelectionStart(textPane.getDocument().getLength()); 
      textPane.setSelectionEnd(textPane.getDocument().getLength()); 

      JComboBox component = new JComboBox(); 
      component.setMaximumSize(component.getPreferredSize()); 
      textPane.insertComponent(component); 

      // insert text after the component 
      textPane.getDocument().insertString(textPane.getDocument().getLength(), currentText, 
        new SimpleAttributeSet()); 

     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     textPane.setEditable(false); 

     frame.add(new JScrollPane(textPane)); 
     frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 
} 

Odpowiedz

3

To dziwne zachowanie zdaje się zdarzać ze względu na ustawiony typ zawartości. Spróbuj usunąć tę linię:

textPane.setContentType ("text/html"); 

, a zobaczysz, że wszystko działa dobrze po tym. Nie jestem pewien, dlaczego tak się dzieje - może to być jakiś błąd renderowania lub tylko zamierzone zachowanie.

P.S. Nie sądzę, że używanie komponentów Swing w panelu tekstowym (bez względu na przyczynę) jest dobrym rozwiązaniem. Ale to tylko moja opinia ...

+0

Tak, to działa. Dlaczego uważasz, że nie jest dobrym pomysłem korzystanie z JTextPane? Chcę stworzyć program do wykonywania ćwiczeń. Ćwiczenia muszą zawierać pola kombinowane i pola tekstowe. Użytkownik musi także mieć możliwość "podkreślenia" (zaznaczenia) tekstu. Jak zrobić to w inny sposób? Użyj JLabels lub wyłączone JTextFields? Nie możesz wybrać swojego tekstu, prawda? Nawet jeśli możesz pomyśleć, że nie byłoby dobrze dodawać tak wiele z tych elementów za każdym razem, gdy masz tekst. – ka3ak

+0

@ ka3ak cóż, to może być jeden z niewielu przypadków, gdy jest to najprostszy sposób robienia rzeczy :) –