2016-09-30 6 views
1

So habe ich eine JTextPane, die im Grunde dient als eine Konsole. Ich habe es im mittleren Feld von JFrame und JTextField im südlichen Feld. Der JTextField nimmt den Text, den er hat, und fügt ihn dem JTextPane hinzu, wenn der Benutzer die Eingabetaste drückt. Um die JTextPane nicht editierbar durch den Benutzer zu machen, musste ich setFocusable(false), weil mit setEditable(false) gestoppt jeden Text auf der JTextPane erscheint. Aber obwohl ich nicht möchte, dass der Benutzer den Bereich bearbeitet, möchte ich trotzdem, dass der Benutzer Text im Bereich hervorheben kann, aber ich kann keinen Weg finden, dies zu tun.Wie markieren Sie Text in einem JTextPane mit setFocusable (false)?

Unten ist ein Beispiel zeigen, was ich meine

Probe

package resources; 

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.*; 
import javax.swing.border.EmptyBorder; 
import javax.swing.text.AttributeSet; 
import javax.swing.text.SimpleAttributeSet; 
import javax.swing.text.StyleConstants; 
import javax.swing.text.StyleContext; 

public class SampeTextPane extends JFrame 
{ 
    public SampeTextPane() 
    { 
     setPreferredSize(new Dimension(350, 200)); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

     JTextPane display = new JTextPane(); 
     display.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     display.setMargin(new Insets(5, 5, 5, 5)); 
     display.setFocusable(false); 
     appendToPane(display, "Example", Color.BLUE); 

     JTextField field = new JTextField(); 
     field.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       appendToPane(display, field.getText(), Color.BLACK); 
       field.setText(""); 
      } 
     }); 

     add(display, BorderLayout.CENTER); 
     add(field, BorderLayout.SOUTH); 

     pack(); 
     setVisible(true); 
    } 

    private void appendToPane(JTextPane pane, String text, Color color) 
    { 
     StyleContext sc = StyleContext.getDefaultStyleContext(); 
     AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, color); 

     aset = sc.addAttribute(aset, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED); 

     int len = pane.getDocument().getLength(); 
     pane.setCaretPosition(len); 
     pane.setCharacterAttributes(aset, false); 
     pane.replaceSelection(text + "\n"); 
    } 

    public static void main(String[] args) 
    { 
     new SampeTextPane(); 
    } 
} 

Vielen Dank im Voraus für jede Hilfe.

Antwort

3

Mit setEditable (false) wurde kein Text mehr auf dem JTextPane angezeigt.

Sie können die JTextPane nicht bearbeiten, aber Sie können den Text nicht über den Textbereich aktualisieren.

Stattdessen können Sie den Text über die Document aktualisieren:

//int len = pane.getDocument().getLength(); 
//pane.setCaretPosition(len); 
//pane.setCharacterAttributes(aset, false); 
//pane.replaceSelection(text + "\n"); 

try 
{ 
    StyledDocument doc = pane.getStyledDocument(); 
    doc.insertString(doc.getLength(), text, aset); 
} 
catch(BadLocationException e) { System.out.println(e); } 
+0

Das funktionierte perfekt! Danke – Ryan

+0

............ und ist viel sauberer als meine Lösung. 1+ –

3

Eine weitere Option, wenn auch gewunden, ist ein boolesches Flag zu verwenden, um Änderungen an dem Dokument zu erlauben oder zu verbieten, schlug etwas StanislavL here.

In Ihrer Situation, könnte es etwas wie folgt aussehen:

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.*; 
import javax.swing.border.EmptyBorder; 
import javax.swing.text.AttributeSet; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DefaultStyledDocument; 
import javax.swing.text.DocumentFilter; 
import javax.swing.text.SimpleAttributeSet; 
import javax.swing.text.StyleConstants; 
import javax.swing.text.StyleContext; 

@SuppressWarnings("serial") 
public class SampeTextPane extends JFrame { 
    private boolean isApi = false; 

    public SampeTextPane() { 
     setPreferredSize(new Dimension(350, 200)); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

     JTextPane display = new JTextPane(); 

     ((DefaultStyledDocument) display.getDocument()).setDocumentFilter(new DocFilter()); 

     display.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     display.setMargin(new Insets(5, 5, 5, 5)); 
     // !! display.setFocusable(false); 
     appendToPane(display, "Example", Color.BLUE); 

     JTextField field = new JTextField(); 
     field.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       appendToPane(display, field.getText(), Color.BLACK); 
       field.setText(""); 
      } 
     }); 

     add(display, BorderLayout.CENTER); 
     add(field, BorderLayout.SOUTH); 

     pack(); 
     setVisible(true); 
    } 

    private void appendToPane(JTextPane pane, String text, Color color) { 
     isApi = true; 

     StyleContext sc = StyleContext.getDefaultStyleContext(); 
     AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, 
       color); 

     aset = sc.addAttribute(aset, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED); 
     int len = pane.getDocument().getLength(); 

     String selection = pane.getSelectedText(); 
     if (selection == null) { 
      pane.setCaretPosition(len); 
      text += "\n"; 
     }   
     pane.setCharacterAttributes(aset, false); 
     pane.replaceSelection(text); 

     isApi = false; 
    } 

    private class DocFilter extends DocumentFilter { 
     @Override 
     public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) 
       throws BadLocationException { 
      if (isApi) { 
       super.insertString(fb, offset, string, attr); 
      } 
     } 

     @Override 
     public void remove(FilterBypass fb, int offset, int length) throws BadLocationException { 
      if (isApi) { 
       super.remove(fb, offset, length); 
      } 
     } 

     @Override 
     public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) 
       throws BadLocationException { 
      if (isApi) { 
       super.replace(fb, offset, length, text, attrs); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> new SampeTextPane()); 
    } 

} 
+0

Interessante Art und Weise zu gehen, und von dem, was ich sehen kann, tut es über die gleiche Sache, aber es übersteigt leicht mein Java-Wissen. Trotzdem danke! – Ryan

+1

@Ryan: Ja, Camickrs Vorschlag ist ** viel ** sauberer, und ich bin froh, dass du damit gegangen bist. Ich habe meinen Code erstellt, bevor er seine richtige Antwort veröffentlicht hat, und so hasste ich es, meine "Bemühungen" nicht zu veröffentlichen. Ich habe natürlich seine Antwort abgestimmt. –

Verwandte Themen