Интересный вопрос, который занял у меня некоторое время, но я думаю, что у меня есть довольно верный ответ. Тем не менее, могут быть несколько лучших способов;
Итак, моя идея состоит в том, что мы должны начать с видимого прямоугольника. Исходя из этого, мы можем узнать, что такое первое видимое вертикальное смещение (getVisibleRect().y
) и конец видимого вертикального смещения (getVisibleRect().y+getVisibleRect().height
). Как только мы получим это, используя высоту шрифта, мы можем определить, какие строки видны.
Вторая часть - узнать, что содержат эти строки. Здесь я использую Utilities
с getRowStart()
и getRowEnd()
.
Вот пример кода того, что я детализировал (результат выводится на консоль при изменении размера рамки или прокрутки текстового поля):
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.Utilities;
public class TestTextAre {
private void initUI() {
JFrame frame = new JFrame(TestTextAre.class.getSimpleName());
final JTextArea ta = new JTextArea(5, 25);
ta.setText("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has "
+ "been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of "
+ "type and scrambled it to make a type specimen book.\n It has survived not only five centuries, but also the "
+ "leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the"
+ " release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing "
+ "software like Aldus PageMaker including versions of Lorem Ipsum.");
ta.setColumns(20);
ta.setEditable(false);
ta.setLineWrap(true);
ta.setWrapStyleWord(true);
JScrollPane scrollpane = new JScrollPane(ta);
scrollpane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
if (e.getValueIsAdjusting()) {
return;
}
printTAVisibleInfo(ta);
}
});
frame.add(scrollpane);
frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
printTAVisibleInfo(ta);
}
});
frame.pack();
frame.setVisible(true);
}
private void printTAVisibleInfo(final JTextArea ta) {
List taInfo = getTAInfo(ta);
int y1 = ta.getVisibleRect().y;
int y2 = y1 + ta.getVisibleRect().height;
int lineHeight = ta.getFontMetrics(ta.getFont()).getHeight();
int startRow = (int) Math.ceil((double) y1 / lineHeight);
int endRow = (int) Math.floor((double) y2 / lineHeight);
endRow = Math.min(endRow, taInfo.size());
System.err.println(startRow + " " + endRow);
for (int i = startRow; i < endRow; i++) {
System.err.println(taInfo.get(i) + " is visible");
}
}
private List getTAInfo(final JTextArea ta) {
List taInfo = new ArrayList();
int start = 0;
int end = -1;
int i = 0;
try {
do {
start = Utilities.getRowStart(ta, end + 1);
end = Utilities.getRowEnd(ta, start);
taInfo.add(new Row(i, start, end, ta.getDocument().getText(start, end - start)));
i++;
} while (end < ta.getDocument().getLength());
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return taInfo;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestTextAre().initUI();
}
});
}
public static class Row {
private final int row;
private final int start;
private final int end;
private final String text;
public Row(int row, int start, int end, String text) {
super();
this.row = row;
this.start = start;
this.end = end;
this.text = text;
}
public int getRow() {
return row;
}
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
public String getText() {
return text;
}
@Override
public String toString() {
return "Row " + row + " contains " + text + " (" + start + "," + end + ")";
}
}
}
Если у вас также есть горизонтальная полоса прокрутки, я думаю, вы должны иметь возможность вычислять горизонтальные смещения с помощью FontMetrics.stringWidth()
.
RODBC очень старый и может быть немного шелушащимся с колонками NVARCHAR. Попробуйте вместо этого использовать пакет RSQLServer , который предлагает альтернативное средство для подключения к SQL Server (а также предоставляет бэкэнд dplyr).