#java #swing #jscrollpane #viewport #jeditorpane
#java #swing #jscrollpane #окно просмотра #jeditorpane
Вопрос:
У меня есть некоторый текстовый компонент (в частности, это JEditorPane
), и мне нужно в качестве ответа на определенное событие сделать видимой некоторую строку в текстовом компоненте, т. е. прокрутить до нее, если это необходимо. Как это сделать с помощью Swing?
Я нахожу setCaretPosition
, но это не всегда хорошо. Если курсор уже находился в позиции, установленной для него новой, это не сделает его видимым снова.
Ответ №1:
из руководств по использованию панелей редактора и текстовых панелей и по использованию панелей прокрутки вы можете получить JViewport, который определяет видимый прямоугольник
пример:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
public class IsRectVisible {
private static void createAndShowUI() {
JFrame frame = new JFrame("IsRectVisible");
frame.getContentPane().add(new IsRectVisibleGui());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowUI();
}
});
}
private IsRectVisible() {
}
}
class IsRectVisibleGui extends JPanel {
public static final Rectangle RECT = new Rectangle(450, 400, 100, 100);
public static final Dimension INNER_PANEL_SIZE = new Dimension(600, 800);
private static final Dimension SCROLLPANE_SIZE = new Dimension(250, 300);
private static final String NOT_VISIBLE = "Not Visible";
private static final String VISIBLE = "Visible";
private static final long serialVersionUID = 1L;
private InnerPanel innerPanel = new InnerPanel();
private JViewport viewport = new JViewport();
private JLabel statusLabel = new JLabel(NOT_VISIBLE);
IsRectVisibleGui() {
JScrollPane scrollpane = new JScrollPane();
scrollpane.setViewport(viewport);
viewport.add(innerPanel);
scrollpane.setPreferredSize(SCROLLPANE_SIZE);
viewport.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
Rectangle viewRect = viewport.getViewRect();
if (viewRect.intersects(RECT)) {
statusLabel.setText(VISIBLE);
} else {
statusLabel.setText(NOT_VISIBLE);
}
}
});
setLayout(new BorderLayout());
add(scrollpane, BorderLayout.CENTER);
add(statusLabel, BorderLayout.SOUTH);
}
class InnerPanel extends JPanel {
private static final long serialVersionUID = 1L;
InnerPanel() {
setPreferredSize(INNER_PANEL_SIZE);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.red);
g2.setStroke(new BasicStroke(4));
g2.draw(RECT);
}
}
}
и вы можете двигаться с этим, используя JScrollPane#scrollRectToVisible (прямоугольник справа)
Ответ №2:
Используйте метод modelToView(), передающий смещение и получающий прямоугольники. Затем используйте scrollRectToVisible
Ответ №3:
Станиславль, как обычно, абсолютно прав :). Вам нужно где-то сохранить позицию, в которую вы хотите перейти. Чем вы получите нужный вам ractengle с
Rectangle ractYouNeed = thePane.getUI().modelToView(thePane, position);
После этого вы могли бы легко прокрутить этот прямоугольник или что-то еще.