2010-02-08 15 views
5

Mam JEditorPane, który jest wyświetlany wewnątrz wyskakującego okienka, uruchamiany przyciskiem. Okienko zawiera długie tekstu w związku z tym jest zagnieżdżona wewnątrz JScrollPane i okienko jest ograniczona do maksymalnej wielkości 300 x 100:Sterowanie preferowanym rozmiarem JEditorPane z długim tekstem

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      String text = "Potentially looooooong text. " + 
       "Lorem ipsum dolor sit amet, consectetuer" + 
       "adipiscing elit, sed diam nonummy nibh euismod " + 
       "tincidunt ut laoreet dolore magna aliquam" + 
       "adipiscing elit, sed diam nonummy nibh euismod" + 
       "erat volutpat. Ut wisi enim ad minim veniam, " + 
       "quis nostrud exerci tation."; 

      final JEditorPane editorPane = new JEditorPane("text/html", text); 
      editorPane.setEditable(false); 

      final JButton button = new JButton("Trigger Popup"); 
      button.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        JPopupMenu popup = new JPopupMenu(); 
        popup.setLayout(new BorderLayout()); 
        popup.add(new JScrollPane(editorPane)); 
        Dimension d = popup.getPreferredSize(); 
        int w = Math.min(300, d.width); 
        int h = Math.min(100, d.height); 
        popup.setPopupSize(w, h); 
        Dimension s = button.getSize(); 
        popup.show(button, s.width/2, s.height/2); 
       } 
      }); 

      JFrame f = new JFrame("Layout Demo"); 
      f.setSize(200, 200); 
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      f.setLocationRelativeTo(null); 
      f.getContentPane().add(button); 
      f.setVisible(true); 
     } 
    }); 
} 

Gdy przykład JEditorPane pokazano pierwszy raz (to znaczy, kiedy przycisk jest kliknął raz) to jakoś wydaje się zgłosić preferowaną wysokość, która jest zbyt mała (1):

first invocation

Po kolejnych kliknięć przycisku, układ jest tak, jak można by się go spodziewać (2):

subsequent invocations

Jak mogę wyegzekwować/nałożyć odpowiednią preferowany rozmiar więc byłoby zawsze zainicjować podobne (2)?

Odpowiedz

11

JEditorPane nie może obliczyć swoją ostateczną preferowaną szerokość i wysokość równocześnie, to musi wiedzieć, zanim się może obliczyć drugą.

Na pierwszym przejściu, ta JEditorPane oblicza swoją preferowaną wysokość w oparciu o założenie, że jego szerokość będzie nieograniczona, dlatego zwraca wysokość jednej linii (ponieważ tekst nie zawiera żadnych podziałów wierszy.)

On drugie przejście, szerokość została już ustawiona (ograniczona przez rozmiar pierwszego JPopupMenu), a teraz, gdy zna maksymalną szerokość, może obliczyć, jak wysoki musi być.

Najprostszym rozwiązaniem jest ustawienie maksymalnej szerokości za każdym razem, gdy ustawisz tekst.

String text = "Potentially looooooong text. " + 
    "Lorem ipsum dolor sit amet, consectetuer" + 
    "adipiscing elit, sed diam nonummy nibh euismod " + 
    "tincidunt ut laoreet dolore magna aliquam" + 
    "adipiscing elit, sed diam nonummy nibh euismod" + 
    "erat volutpat. Ut wisi enim ad minim veniam, " + 
    "quis nostrud exerci tation."; 

final JEditorPane editorPane = new JEditorPane("text/html", text); 
editorPane.setSize(300, Integer.MAX_VALUE); 
editorPane.setEditable(false); 

Nie martw się o co zbyt duża, to nadal kurczyć, aby dopasować zawartość (jak widać po zmianie tekstu "Hello, World!"

+0

@finnw. Doskonałe wyjaśnienie i obejścia - dziękuję bardzo! – netzwerg

+1

Doskonałe rozwiązanie, +1! Chociaż minęło trochę czasu, mam dla ciebie inne dobre pytanie. Próbowałem tego samego podejścia z JTextPane, to tylko podklasa JEditorPane. t. Próbuję wejść głęboko (BasicTextUI), aby zrozumieć, gdzie jest różnica, ale może już to znasz? :-) – AgostinoX