changeset 1876:d74dca32fe7b default tip

swing
author Franklin Schmidt <fschmidt@gmail.com>
date Sat, 05 Apr 2025 19:22:51 -0600
parents 31da4bd4e6b8
children
files src/luan/modules/swing/TextAreaLineNumbersLuan.java
diffstat 1 files changed, 55 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/modules/swing/TextAreaLineNumbersLuan.java	Sat Apr 05 09:58:40 2025 -0600
+++ b/src/luan/modules/swing/TextAreaLineNumbersLuan.java	Sat Apr 05 19:22:51 2025 -0600
@@ -9,6 +9,9 @@
 import java.awt.event.ComponentListener;
 import java.awt.event.ComponentAdapter;
 import java.awt.event.ComponentEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
 import javax.swing.JPanel;
 import javax.swing.BoxLayout;
 import javax.swing.JLabel;
@@ -26,6 +29,7 @@
 	private final TextAreaLuan textArea;
 	private int width;
 	private int lines;
+	private int lineStartSelection = -1;
 
 	public TextAreaLineNumbersLuan(TextAreaLuan textArea) {
 		this.textArea = textArea;
@@ -33,7 +37,7 @@
 		//logger.info("lines "+lines);
 		setFont(textArea.getFont());
 		setLayout( new BoxLayout(this, BoxLayout.Y_AXIS) );
-		for( int i=1; i<=lines; i++ ) {
+		for( int i=0; i<lines; i++ ) {
 			JLabel label = newJLabel(i);
 			add(label);
 		}
@@ -44,12 +48,56 @@
 		textArea.addComponentListener(resizeListener);
 	}
 
-	private JLabel newJLabel(int i) {
-		String text = String.valueOf(i);
+	private final MouseListener mouseListener = new MouseAdapter() {
+		@Override public void mousePressed(MouseEvent event) {
+			if( event.getButton() == MouseEvent.BUTTON1 ) {
+				JLabel label = (JLabel)event.getComponent();
+				int line = (Integer)label.getClientProperty("line");
+				logger.info("clicked "+line);
+				lineStartSelection = line;
+				int start, end;
+				try {
+					start = textArea.getLineStartOffset(line);
+					end = textArea.getLineEndOffset(line);
+				} catch(BadLocationException e) {
+					throw new RuntimeException(e);
+				}
+				textArea.setCaretPosition(start);
+				textArea.moveCaretPosition(end);
+			}
+		}
+
+		@Override public void mouseReleased(MouseEvent event) {
+			if( event.getButton() == MouseEvent.BUTTON1 )
+				lineStartSelection = -1;
+		}
+
+		@Override public void mouseEntered(MouseEvent event) {
+			if( lineStartSelection >= 0 && (event.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0 ) {
+				JLabel label = (JLabel)event.getComponent();
+				int line = (Integer)label.getClientProperty("line");
+				logger.info("entered "+line);
+				int start, end;
+				try {
+					start = textArea.getLineStartOffset(Math.min(line,lineStartSelection));
+					end = textArea.getLineEndOffset(Math.max(line,lineStartSelection));
+				} catch(BadLocationException e) {
+					throw new RuntimeException(e);
+				}
+				textArea.setCaretPosition(start);
+				textArea.moveCaretPosition(end);
+			}
+		}
+	};
+
+	private JLabel newJLabel(int line) {
+		String text = String.valueOf(line+1);
 		JLabel label = new JLabel(text,JLabel.RIGHT);
 		label.setVerticalAlignment(JLabel.TOP);
 		label.setFont(getFont());
 		label.setForeground(getForeground());
+		label.putClientProperty("line",line);
+		label.addMouseListener(mouseListener);
 		return label;
 	}
 
@@ -62,7 +110,7 @@
 			for( Component label : getComponents() ) {
 				Dimension size = label.getPreferredSize();
 				Dimension newSize = new Dimension( width, size.height );
-				label.setPreferredSize(newSize);
+				//label.setPreferredSize(newSize);
 				label.setMaximumSize(newSize);
 				//label.revalidate();
 				//logger.info("setPreferredSize "+label.getPreferredSize().width);
@@ -131,11 +179,12 @@
 				fixHeights(start,end);
 			}
 		} else if( lines < n ) {
-			for( int i=lines+1; i<=n; i++ ) {
+			for( int i=lines; i<n; i++ ) {
 				JLabel label = newJLabel(i);
 				add(label);
 			}
 			lines = n;
+			fixWidth();
 			if( textArea.getLineWrap() )
 				fixHeights();
 		} else {  // lines > n
@@ -146,6 +195,7 @@
 				//logger.info("getComponentCount "+getComponentCount());
 			}
 			lines = n;
+			fixWidth();
 			if( textArea.getLineWrap() )
 				fixHeights();
 			repaint();