gpt4 book ai didi

Java JTextPane 向 JScrollPane 添加空白区域

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:46:12 25 4
gpt4 key购买 nike

我在 JScrollPane 中有一个 JTextPane。我想要实现的是在 JTextPane 下添加一个空白空间,以允许用户进一步向下滚动文本 Pane ,以便最后一行(在框架底部可见) 可以向上滚动到第一行位置。很难解释所以这里有一些照片: enter image description here

我尝试解决这个问题是在 JTextPane 下添加一个带有 Borderlayout.SOUTHJPanel。并更新 setPreferredSize(0, frameHeight - (const+ fontHeight))

const = A constant value I got from experimenting

int fontHeight = textPane.getFontMetrics(textPane.getFont()).getHeight();

在您调整字体大小之前,它工作正常...基本上它非常 hacky 并且似乎不是很可靠。

问题:是否有内部方法可以添加此功能?如果没有,我该如何改进现有解决方案以提高稳定性?

编辑----------------这里是工作代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.text.BadLocationException;


public class Main extends JFrame{
private JTextPane zNum, tField;
private JPanel scrollPanel;
private JScrollPane tScrollPane;
private Font font = new Font("Source Code Pro", Font.PLAIN, 12);

public Main(){
super("Test Editor");
getContentPane().setLayout(new BorderLayout());

zNum = new JTextPane();
zNum.setText("1");
zNum.setEditable(false);
zNum.setBorder(new EmptyBorder(2, 6, 2, 6));
zNum.setBackground(Color.GRAY);
zNum.setFont(font);

tField = new JTextPane();
tField.setBorder(new EmptyBorder(2, 6, 2, 6));
tField.setBackground(Color.LIGHT_GRAY);
tField.setFont(font);

scrollPanel = new JPanel();
scrollPanel.setLayout(new BorderLayout());
scrollPanel.add(zNum, BorderLayout.LINE_START);
scrollPanel.add(tField, BorderLayout.CENTER);
scrollPanel.setBackground(Color.LIGHT_GRAY);

tScrollPane = new JScrollPane(scrollPanel);
tScrollPane.setBorder(BorderFactory.createEmptyBorder());
getContentPane().add(tScrollPane, BorderLayout.CENTER);

setPreferredSize(new Dimension(300, 200));
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setResizable(true);
pack();
setLocationRelativeTo(null);
setVisible(true);

// Resize
this.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent event) {
updateMargin(tField);
}
});
}

void updateMargin(JTextPane textPane) {
JViewport viewport = (JViewport)
SwingUtilities.getAncestorOfClass(JViewport.class, textPane);

if (viewport != null) {
int len = textPane.getDocument().getLength();
try {
Rectangle end = textPane.modelToView(len);
if (end != null) {
tField.setBorder(new EmptyBorder(0, 0, viewport.getHeight() - (end.height + 4), 0));
}
} catch (BadLocationException e) {
throw new RuntimeException(e);
}
}
}

public static void main(String[] args){
new Main();
}
}

最佳答案

您可以根据其封闭的 JViewport 的边界及其文档的最后一行来设置 JTextPane 的边距:

static void updateMargin(JTextPane textPane) {
JViewport viewport = (JViewport)
SwingUtilities.getAncestorOfClass(JViewport.class, textPane);

if (viewport != null) {
Insets margin = textPane.getMargin();

int len = textPane.getDocument().getLength();
try {
Rectangle end = textPane.modelToView(len);
if (end != null) {
margin.bottom = viewport.getHeight() - end.height;
textPane.setMargin(margin);
}
} catch (BadLocationException e) {
throw new RuntimeException(e);
}
}
}

每当调整 JTextPane 的大小时、当它变得可显示时以及当它的文本发生更改时,您都希望调用该方法。为了更好地衡量,如果调用 JTextPane 的继承 setPage 方法,我也会调用它:

static void configureMargin(final JTextPane textPane) {
textPane.addPropertyChangeListener("page", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent event) {
updateMargin(textPane);
}
});

textPane.addHierarchyListener(new HierarchyListener() {
@Override
public void hierarchyChanged(HierarchyEvent event) {
long flags = event.getChangeFlags();
if ((flags & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {
updateMargin(textPane);
}
}
});

textPane.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent event) {
updateMargin(textPane);
}
});

textPane.getDocument().addDocumentListener(new DocumentListener() {
private void updateTextPane() {
EventQueue.invokeLater(new Runnable() {
public void run() {
updateMargin(textPane);
}
});
}

@Override
public void changedUpdate(DocumentEvent event) {
updateTextPane();
}

@Override
public void insertUpdate(DocumentEvent event) {
updateTextPane();
}

@Override
public void removeUpdate(DocumentEvent event) {
updateTextPane();
}
});
}

关于Java JTextPane 向 JScrollPane 添加空白区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27048608/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com