【发布时间】:2021-04-22 16:09:13
【问题描述】:
我正在用 Java 8 编写一个基于 Swing 的 UI 组件,它基本上在一个可垂直滚动的字段中显示多个 JTextPanes,并有一个用于基本样式操作(字体、字体大小、粗体等)的工具栏
为此,我使用了JPanel,它还在JScrollPane 内实现了可滚动,其中包含使用垂直BoxLayout 的多个JTextPanes。
当我开始这个时,它看起来很好,并且所有 TextPanes 都足够高以容纳一行文本并在键入更多内容时进行缩放。当我更改字体大小时,就会出现问题。当字体大小改变时,JTextPane 应该会自动调整大小以适应新文本,但是当我使用按钮来改变它时,只有当我点击两次时大小才会改变。
这里有一些截图来解释我的意思:
这是在示例开始之后,我在顶部JTextPane 添加了一些文本。这里有 2 个 TextPanes。
这是在第一次单击按钮之后,它将字体大小设置为 30pt。文字较大,但 JTextPane 不会调整大小以适应它
这是在我再次单击该按钮之后。 JTextPane 现在可以正确缩放
我已经尝试在JTextPane 及其父对象上手动调用invalidate、revalidate 和repaint,但这没有任何效果。
JTextPane 也会在另一个属性更改(例如粗体)或 FontSize 更改为另一个值时调整大小。但它似乎总是落后于一个变化。
因此,当 FontSize 更改为 20,然后更改为 30,当 FontSize 设置为 30pt 时,它将调整大小以适应 20pt 字体。
有没有人知道什么可能导致问题以及如何解决?
这是最小示例的代码:
public class TestEditorPanes {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.add(getPanel());
frame.setSize(720, 480);
frame.setVisible(true);
}
private static JPanel getPanel() {
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel editorPanel = new ScrollablePanel();
editorPanel.setLayout(new BoxLayout(editorPanel, BoxLayout.Y_AXIS));
JTextPane textPane1 = new JTextPane();
JTextPane textPane2 = new JTextPane();
editorPanel.add(textPane1);
editorPanel.add(textPane2);
mainPanel.add(new JScrollPane(editorPanel), BorderLayout.CENTER);
// Button sets Font size to 30
JButton btnFontSize = new JButton("FontSize");
btnFontSize.addActionListener(e -> {
MutableAttributeSet attrs = new SimpleAttributeSet();
StyleConstants.setFontSize(attrs, 30);
textPane1.setCharacterAttributes(attrs, false);
});
mainPanel.add(btnFontSize, BorderLayout.NORTH);
return mainPanel;
}
private static class ScrollablePanel extends JPanel implements Scrollable {
@Override
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 30;
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 30;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
}
【问题讨论】: