Mercurial Hosting > luan
view src/luan/modules/swing/TextAreaLuan.java @ 1900:aa24812aaf98
minor
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 14 Apr 2025 19:06:46 -0600 |
parents | ef0438da68ae |
children |
line wrap: on
line source
package luan.modules.swing; import java.awt.Rectangle; import java.awt.Graphics; import java.awt.Color; import java.awt.event.FocusListener; import java.awt.event.FocusEvent; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JTextArea; import javax.swing.UIManager; import javax.swing.Timer; import javax.swing.text.DefaultCaret; import javax.swing.text.BadLocationException; import goodjava.logging.Logger; import goodjava.logging.LoggerFactory; public class TextAreaLuan extends JTextArea { private static final Logger logger = LoggerFactory.getLogger(TextAreaLuan.class); private static final DefaultCaret flatLafCaret = new DefaultCaret() { private final Timer blinkTimer = new Timer(500, new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { setVisible(!isVisible()); } }); @Override public void focusGained(FocusEvent e) { super.focusGained(e); blinkTimer.start(); } @Override public void focusLost(FocusEvent e) { // Don't call super — we want to keep caret visible blinkTimer.stop(); setVisible(true); } }; private boolean showWhitespace = false; public TextAreaLuan() { super(); //logger.info(UIManager.getLookAndFeel().getName()); if( UIManager.getLookAndFeel().getName().startsWith("FlatLaf") ) { setCaret(flatLafCaret); } } public int getLineHeight(int line) throws BadLocationException { if( !getLineWrap() ) return getRowHeight(); int startOffset = modelToView(getLineStartOffset(line)).y; int endOffset = modelToView(getLineEndOffset(line)).y; int height = endOffset - startOffset; if( height == 0 ) height = getRowHeight(); return height; } public int getLineRows(int line) throws BadLocationException { return getLineHeight(line) / getRowHeight(); } public void showWhitespace(boolean showWhitespace) { this.showWhitespace = showWhitespace; repaint(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if( !showWhitespace ) return; g.setColor(Color.LIGHT_GRAY); String text = getText(); int ascent = g.getFontMetrics().getAscent(); Rectangle visible = getVisibleRect(); for( int pos=0; pos<text.length(); pos++ ) { char ch = text.charAt(pos); String symbol; switch(ch) { case ' ': symbol = "·"; break; case '\t': symbol = "→"; break; case '\n': symbol = "¶"; break; default: continue; } Rectangle r; try { r = modelToView(pos); } catch(BadLocationException e) { throw new RuntimeException(e); } if( visible.contains(r) ) g.drawString( symbol, r.x, r.y + ascent ); } } }