Wie mache ich JTextPane Autoscroll nur, wenn die Bildlaufleiste unten ist und die Bildlaufsperre deaktiviert ist? Dies sollte nichts mit Caret zu tun haben, was ich anscheinend überall in Google finde. .. :(Wie mache ich JTextPane Autoscroll nur, wenn die Bildlaufleiste unten ist und die Bildlaufsperre ausgeschaltet ist?
Antwort
Text Area Scrolling von Interesse sein können
Ich habe keine Ahnung, wie die Scroll-Lock-Taste wirkt es mir folgendes aus der Wikipedia-Seite über Scroll Lock gefunden:
Daher Scroll Lock kann angesehen als nicht mehr existierenden Feature in fast allen modernen Programmen und Betriebssystemen.
so würde ich nicht darum kümmern.
ich denke, bin Ihr Programm erfüllt genau Ihre Anforderungen, mit einem möglichen Vorbehalt: Sie dürfen den Textbereich nicht eingeben. Das wäre also gut für einen Log Viewer, aber nicht für eine interaktive Konsole. Der Code läuft ein wenig lang, weil ich es zu einer Ready-to-Run-Demo des Ansatzes gemacht habe. Ich schlage vor, das Programm wie gehabt auszuführen und das Verhalten zu überprüfen. Wenn das Verhalten für Sie gut funktioniert, investieren Sie etwas Zeit in das Studium des Codes. Ich habe Kommentare in den Code eingefügt, um einige der wichtigeren Abschnitte hervorzuheben.
-Update 2013.07.17: Sie können auch weiter zufälligen Geck ‚s-Lösung in seiner separaten Antwort zu überprüfen, unten auf der Seite. Sein Ansatz ist eleganter als meiner.
Siehe auch Swing: Scroll to bottom of JScrollPane, conditional on current viewport location für eine mögliche Lösung, die die Caret-Position nicht beeinträchtigt.
SCCE Quellcode folgt:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.Timer;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
public class ScrollingJTextAreaExample extends JFrame {
// Worker thread to help periodically append example messages to JTextArea
Timer timer = new Timer();
// Merely informative counter, will be displayed with the example messages
int messageCounter = 0;
// GUI components
JScrollPane jScrollPane;
JTextArea jTextArea;
public ScrollingJTextAreaExample() {
initComponents(); // Boiler plate GUI construction and layout
// Configure JTextArea to not update the cursor position after
// inserting or appending text to the JTextArea. This disables the
// JTextArea's usual behavior of scrolling automatically whenever
// inserting or appending text into the JTextArea: we want scrolling
// to only occur at our discretion, not blindly. NOTE that this
// breaks normal typing into the JTextArea. This approach assumes
// that all updates to the ScrollingJTextArea are programmatic.
DefaultCaret caret = (DefaultCaret) jTextArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
// Schedule a task to periodically append example messages to jTextArea
timer.schedule(new TextGeneratorTask(), 250, 250);
// This DocumentListener takes care of re-scrolling when appropriate
Document document = jTextArea.getDocument();
document.addDocumentListener(new ScrollingDocumentListener());
}
// Boring, vanilla GUI construction and layout code
private void initComponents() {
jScrollPane = new javax.swing.JScrollPane();
jTextArea = new javax.swing.JTextArea();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jScrollPane.setViewportView(jTextArea);
getContentPane().add(jScrollPane, java.awt.BorderLayout.CENTER);
setSize(320, 240);
setLocationRelativeTo(null);
}
// ScrollingDocumentListener takes care of re-scrolling when appropriate
class ScrollingDocumentListener implements DocumentListener {
public void changedUpdate(DocumentEvent e) {
maybeScrollToBottom();
}
public void insertUpdate(DocumentEvent e) {
maybeScrollToBottom();
}
public void removeUpdate(DocumentEvent e) {
maybeScrollToBottom();
}
private void maybeScrollToBottom() {
JScrollBar scrollBar = jScrollPane.getVerticalScrollBar();
boolean scrollBarAtBottom = isScrollBarFullyExtended(scrollBar);
boolean scrollLock = Toolkit.getDefaultToolkit()
.getLockingKeyState(KeyEvent.VK_SCROLL_LOCK);
if (scrollBarAtBottom && !scrollLock) {
// Push the call to "scrollToBottom" back TWO PLACES on the
// AWT-EDT queue so that it runs *after* Swing has had an
// opportunity to "react" to the appending of new text:
// this ensures that we "scrollToBottom" only after a new
// bottom has been recalculated during the natural
// revalidation of the GUI that occurs after having
// appending new text to the JTextArea.
EventQueue.invokeLater(new Runnable() {
public void run() {
EventQueue.invokeLater(new Runnable() {
public void run() {
scrollToBottom(jTextArea);
}
});
}
});
}
}
}
class TextGeneratorTask extends TimerTask {
public void run() {
EventQueue.invokeLater(new Runnable() {
public void run() {
String message = (++messageCounter)
+ " Lorem ipsum dolor sit amet, consectetur"
+ " adipisicing elit, sed do eiusmod tempor"
+ " incididunt ut labore et dolore magna aliqua.\n";
jTextArea.append(message);
}
});
}
}
public static boolean isScrollBarFullyExtended(JScrollBar vScrollBar) {
BoundedRangeModel model = vScrollBar.getModel();
return (model.getExtent() + model.getValue()) == model.getMaximum();
}
public static void scrollToBottom(JComponent component) {
Rectangle visibleRect = component.getVisibleRect();
visibleRect.y = component.getHeight() - visibleRect.height;
component.scrollRectToVisible(visibleRect);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ScrollingJTextAreaExample().setVisible(true);
}
});
}
}
wenig spät auf diese Frage, aber ich kam mit dieser Lösung auf.
conversationPane = new JTextPane();
final JScrollPane conversationScrollPane = new JScrollPane(conversationPane);
conversationScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
BoundedRangeModel brm = conversationScrollPane.getVerticalScrollBar().getModel();
boolean wasAtBottom = true;
public void adjustmentValueChanged(AdjustmentEvent e) {
if (!brm.getValueIsAdjusting()) {
if (wasAtBottom)
brm.setValue(brm.getMaximum());
} else
wasAtBottom = ((brm.getValue() + brm.getExtent()) == brm.getMaximum());
}
});
Scheint perfekt für meine Bedürfnisse zu funktionieren. Kleine Erklärung: Wenn die Bildlaufleiste nicht von einer Person bewegt wird und der Balken zuletzt am Maximum/unten war, setzen Sie ihn auf das Maximum zurück. Wenn es manuell angepasst wird, überprüfen Sie, ob es so eingestellt wurde, dass es unten liegt.
Aus irgendeinem Grund hängt brm.setValue (brm.getMaximum()) meine Methode und mein zweiter Thread (nur unter Windows. linux mac solaris funktioniert super). tat dies mit setcaret postiion auf der textpanee, aber auf windows das gleiche ergebnis. Irgendeine Idee? – Meltea
@Meltea - Alle Interaktionen mit Swing/AWT-Objekten müssen im AWT-Ereignisversand-Thread durchgeführt werden. Wenn Sie einen "zweiten Thread" haben, müssen Sie mit der Benutzeroberfläche interagieren, indem Sie Runnables über SwingUtilities.invokeLater in die Warteschlange stellen. Wenn Sie eine Methode für ein Swing- oder AWT-Objekt aufrufen (z. B. brm.getMaximum()), fügen Sie vor dem Aufruf dieser Methode eine Protokollanweisung ein, die den Wert von SwingUtilities.isEventDispatchThread() in der Codezeile protokolliert. Wenn "false" gedruckt wird, verletzen Sie das Threading-Modell von Swing/AWT und müssen SwingUtilities.invokeLater (oder Ähnliches) verwenden. –
Du hast meinen Tag gerettet. – MrPk
starten:
JTextArea txt = new JTextArea();
JScrollPane jsp = new JScrollPane(history, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
txt.setCaretPosition(txt.getDocument().getLength()); // do this afeter any event
Hoffnung, die Sie
ich hilft benötigt, um das gleiche für eine Protokollierung Textbereich zu tun. Die Lösungen, die ich im Internet gefunden habe, funktionierten nicht für mich (sie hören entweder auf, automatisch zu scrollen, wenn sie schnell Nachrichten auflogen, oder sie blockierten die Bildlaufleiste unten, auch wenn Sie mit dem Mausrad nach oben scrollen).
Ich tat es auf diese Weise:
public static void makeTextAreaAutoScroll(JTextArea textArea) {
// Get the text area's scroll pane :
final JScrollPane scrollPane = (JScrollPane) (textArea.getParent().getParent());
// Disable the auto scroll :
((DefaultCaret)textArea.getCaret()).setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
// Add a listener to the vertical scroll bar :
scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
private int _val = 0;
private int _ext = 0;
private int _max = 0;
private final BoundedRangeModel _model = scrollPane.getVerticalScrollBar().getModel();
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
// Get the new max :
int newMax = _model.getMaximum();
// If the new max has changed and if we were scrolled to bottom :
if (newMax != _max && (_val + _ext == _max)) {
// Scroll to bottom :
_model.setValue(_model.getMaximum() - _model.getExtent());
}
// Save the new values :
_val = _model.getValue();
_ext = _model.getExtent();
_max = _model.getMaximum();
}
});
}
einfach es auf diese Weise verwenden:
makeTextAreaAutoScroll(yourTextArea);
Sie können mit diesem Stück Code testen:
new Timer().schedule(new TimerTask() {
@Override
public void run() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
String line = "test " + Math.random();
yourTextArea.append(yourTextArea.getText().isEmpty() ? line : "\n" + line);
}
});
}
}, 0, 5);
nun Ihr Textbereich Wenn die Bildlaufleiste ganz unten ist, halten Sie die automatische Bildlauffunktion an, wenn Sie die Bildlaufleiste verschieben (durch Ziehen der Leiste oder durch Drücken der Taste Rad), und automatisches Scrollen, wenn Sie die Bildlaufleiste erneut unten platzieren.
Nachdem ich Mike Clark und zufällige Kumpel Lösung gelesen habe, habe ich am Ende mit Code-Schnipsel.
private boolean doAutoScroll = true;
private JTextPane textPane;
private JScrollPane scrollPane;
public void setup() {
/* Left Panel */
textPane = new JTextPane();
textPane.setPreferredSize(new Dimension(600, 400)); // width, height
/*
* Not update the cursor position after inserting or appending text to the JTextPane.
* [NOTE]
* This breaks normal typing into the JTextPane.
* This approach assumes that all updates to the JTextPane are programmatic.
*/
DefaultCaret caret = (DefaultCaret) textPane.getCaret();
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
scrollPane = new JScrollPane(textPane);
scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
BoundedRangeModel brm = scrollPane.getVerticalScrollBar().getModel();
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
// Invoked when user select and move the cursor of scroll by mouse explicitly.
if (!brm.getValueIsAdjusting()) {
if (doAutoScroll) brm.setValue(brm. getMaximum());
} else {
// doAutoScroll will be set to true when user reaches at the bottom of document.
doAutoScroll = ((brm.getValue() + brm.getExtent()) == brm.getMaximum());
}
}
});
scrollPane.addMouseWheelListener(new MouseWheelListener() {
BoundedRangeModel brm = scrollPane.getVerticalScrollBar().getModel();
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
// Invoked when user use mouse wheel to scroll
if (e.getWheelRotation() < 0) {
// If user trying to scroll up, doAutoScroll should be false.
doAutoScroll = false;
} else {
// doAutoScroll will be set to true when user reaches at the bottom of document.
doAutoScroll = ((brm.getValue() + brm.getExtent()) == brm.getMaximum());
}
}
});
}
Der Unterschied besteht darin, dass sie zusätzlich MouseWheelListener
unter Verwendung doAutoScroll
Flags auch wenn Benutzer verwenden Mausrad zu aktualisieren, um nach oben und nach unten.
- 1. Werden BroadcastReceiver ausgelöst, wenn die App vollständig ausgeschaltet ist?
- 2. Ist es möglich, die Ausrichtung des Geräts zu ändern, wenn die Standard-Gerätedrehung ausgeschaltet ist?
- 3. Alarmmanager, wenn das Telefon ausgeschaltet ist - ANDROID
- 4. Wie hole ich Daten aus der Push-Benachrichtigung, wenn die App ausgeschaltet ist?
- 5. JTextPane: Wie die Schriftgröße
- 6. Wie kann ich die Geräteausrichtung erkennen, wenn die Ausrichtungssperre aktiviert ist und die App nur Portrait
- 7. GDCWebserver serverURL ist null, wenn WLAN ausgeschaltet ist
- 8. ASP.NET: Was genau ist betroffen, wenn Javascript ausgeschaltet ist?
- 9. IOS App überprüfen, wenn GPS ausgeschaltet ist
- 10. Hinzufügen eine Bildlaufleiste, wenn div unten unten Sichtöffnung erstreckt
- 11. Wie kann ich mein Silverlight 2-Steuerelement an die Seite anpassen? (Die Standardeinstellung ist eine Bildlaufleiste)
- 12. Wie mache Feld nur erforderlich, wenn das Formular neu ist?
- 13. verhindern, dass die Aktivität Touch-Ereignisse empfängt, wenn die Anzeige ausgeschaltet ist
- 14. Wie füge ich Text an QPlainTextEdit an, ohne Zeilenumbrüche hinzuzufügen, und halte die Bildlaufleiste unten?
- 15. Wie mache ich eine GUI, die sich so verhält?
- 16. Wie mache ich eine Klasse, die auch eine Liste ist?
- 17. Was ist die Arbeit von unten Code?
- 18. Ist das eine schlechte Javascript-Praxis, die ich hier mache?
- 19. Scroll Seite Positionierung ist ausgeschaltet
- 20. Regex für die Validierung nur, wenn die Länge 6 ist
- 21. Gibt an, wie die Bildlaufleiste angezeigt wird?
- 22. Wie validiere ich, dass eine VM ausgeschaltet ist?
- 23. Wie ändere ich die Feed-Dialog-Zielgruppe, wenn ich nur Leseberechtigungen angefordert habe. Die Standardeinstellung ist "Nur ich"
- 24. JavaFX TextArea und Autoscroll
- 25. -Test nur, wenn die Variable nicht null ist, wenn Anweisung
- 26. Wie mache ich nur Zahlen, die eingegeben werden können?
- 27. Wie kann ich den Legendentitel über den Beschriftungen platzieren, wenn die Legendenposition beispielsweise unten ist?
- 28. Wie verhindere ich, dass die Menüleiste nach unten bewegt wird, wenn mein Popover geöffnet ist?
- 29. Wie erzwinge ich Fußnoten ganz unten auf der Seite, wenn die Seite nicht voll ist?
- 30. Wie aktiviere ich eine Aktivität, während der Bildschirm ausgeschaltet ist?
Yup, das sieht aus wie ich es mache. – I82Much
Sehr sehr cool !! Vielen Dank! –
Es funktioniert nicht, wenn Sie Nachrichten an fasten (mit timer.schedule (new TextGeneratorTask(), 250, 5); zum Beispiel), wissen Sie, warum? –