如何解决添加填充有文本的 JTextArea/JTextPane 时,防止 JSscrollPane 调整大小
互联网上的你好
我的问题是,当我在 setViewPortView(textArea)
上调用 JScrollPane
并且 JTextArea
已经包含文本时,JScrollPane
会调整大小以适应 JTextArea
的整个文本{1}}。我希望滚动窗格保持相同的大小,同时将其余文本隐藏在下面的滚动窗格中,以便我可以向下滚动以查看其余文本。
请参阅以下应该可以运行的示例:
- 点击“编辑”按钮。
JTextPane
现在替换为可编辑的JTextArea
。 - 在按钮上方输入
JTextArea
。输入足够多的文本,使其开始按预期向下滚动,多行文本。 - 再次单击现在标题为“保存”的同一个按钮。现在,不可编辑的
JTextPane
将显示在JScrollPane
而不是JTextArea
。 - 看看
JSCrollPane
如何调整大小?
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main extends JFrame {
private final JScrollPane scrollPane;
private final JTextArea textArea;
private final JTextPane textPane;
private final JButton editButton;
private String text;
private boolean isEditing = false;
public Main() {
setLayout(new GridBagLayout());
textArea = new JTextArea();
textArea.setVisible(false);
textPane = new JTextPane();
textPane.setEditable(false);
scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setViewportView(textPane);
editButton = new JButton("Edit");
editButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
isEditing = !isEditing;
textPane.setVisible(!isEditing);
textArea.setVisible(isEditing);
if(isEditing) {
scrollPane.setViewportView(textArea);
editButton.setText("Save");
}
else {
scrollPane.setViewportView(textPane);
editButton.setText("Edit");
text = textArea.getText();
}
textPane.setText(text);
}
});
GridBagConstraints bag = new GridBagConstraints();
bag.gridx = 0;
bag.gridy = 0;
bag.gridwidth = 3;
bag.gridheight = 1;
bag.weightx = 1.0;
bag.weighty = 1.0;
bag.fill = GridBagConstraints.BOTH;
bag.anchor = GridBagConstraints.NORTH;
bag.insets = new Insets(5,5,5);
add(scrollPane,bag);
bag = new GridBagConstraints();
bag.gridx = 1;
bag.gridy = 1;
bag.gridwidth = 1;
bag.gridheight = 1;
bag.weightx = 1.0;
bag.weighty = 1.0;
add(editButton,bag);
setSize(1000,500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
Main ui = new Main();
});
}
}
PS:我正在切换到 JTextPane
,因为我打算呈现我已排除的降价文本以保持示例简单。我正在使用 JDK 8u231
我尝试保存原始尺寸并在换出它们时使用 setPreferredSize
和 setMaximumSize
进行设置,但它没有解决我的问题。我还想在窗口调整大小时保持可调整大小。
更新:我需要使用 GridBag
布局,因为我有一个 JPanel
,我通过覆盖它上方的 paint()
函数在其上进行绘制
解决方法
Swing 组件应确定其自己的首选大小。你不应该硬编码随机大小。然后布局管理器可以使用这些信息。
最简单的方法是使用以下方法向 JTextArea 提示它应包含的行/列数:
JTextArea textArea = new JTextArea(15,40);
然后,您可以使用适当的布局管理器来允许组件随着框架大小的变化而动态调整大小。我会为此使用 BorderLayout。然后,在将组件添加到框架后,您可以打包框架。
一个基本的解决方案可能是:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main5 extends JFrame {
private final JScrollPane scrollPane;
private final JTextArea textArea;
private final JTextPane textPane;
private final JButton editButton;
private String text;
private boolean isEditing = false;
public Main5() {
// setLayout(new GridBagLayout());
// textArea = new JTextArea();
// textArea.setVisible(false);
setLayout( new BorderLayout() );
textArea = new JTextArea(15,40);
textPane = new JTextPane();
textPane.setPreferredSize( textArea.getPreferredSize() );
textPane.setEditable(false);
scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setViewportView(textPane);
editButton = new JButton("Edit");
editButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
isEditing = !isEditing;
textPane.setVisible(!isEditing);
// textArea.setVisible(isEditing);
if(isEditing) {
scrollPane.setViewportView(textArea);
editButton.setText("Save");
textArea.requestFocusInWindow();
}
else {
scrollPane.setViewportView(textPane);
editButton.setText("Edit");
text = textArea.getText();
}
textPane.setText(text);
}
});
/*
GridBagConstraints bag = new GridBagConstraints();
bag.gridx = 0;
bag.gridy = 0;
bag.gridwidth = 3;
bag.gridheight = 1;
bag.weightx = 1.0;
bag.weighty = 1.0;
bag.fill = GridBagConstraints.BOTH;
bag.anchor = GridBagConstraints.NORTH;
bag.insets = new Insets(5,5,5);
add(scrollPane,bag);
bag = new GridBagConstraints();
bag.gridx = 1;
bag.gridy = 1;
bag.gridwidth = 1;
bag.gridheight = 1;
bag.weightx = 1.0;
bag.weighty = 1.0;
add(editButton,bag);
*/
add(scrollPane,BorderLayout.CENTER);
JPanel wrapper = new JPanel();
wrapper.add(editButton);
add(wrapper,BorderLayout.PAGE_END);
// setSize(1000,500);
pack();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
Main5 ui = new Main5();
});
}
}
即使您将其转换为使用 CardLayout,它仍然可以工作,因为卡片面板的大小取决于添加到其中的最大面板的大小。
,好的,我找到了解决方案。如果我将 JScrollPane
的首选大小设置为某个不太大的固定值,那么它仍然是我想要的大小,并且不会垂直增长。当我调整窗口大小时,它也会随着窗口调整大小。请参阅下面的代码,并感谢 Andrew Thompson 在评论中提出 CardLayout
。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main extends JFrame {
private final JScrollPane scrollPane;
private final JTextArea textArea;
private final JTextPane textPane;
private final JButton editButton;
private String text;
private final JPanel cardPanel;
private final CardLayout cards;
private boolean isEditing = false;
public Main() {
setLayout(new GridBagLayout());
textArea = new JTextArea();
textPane = new JTextPane();
textPane.setEditable(false);
cards = new CardLayout();
cardPanel = new JPanel();
cardPanel.setLayout(cards);
cardPanel.add(textPane);
cardPanel.add(textArea);
scrollPane = new JScrollPane(cardPanel);
scrollPane.setPreferredSize(new Dimension(Integer.MAX_VALUE,50));
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
editButton = new JButton("Edit");
editButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
isEditing = !isEditing;
if(isEditing) {
editButton.setText("Save");
}
else {
editButton.setText("Edit");
text = textArea.getText();
}
textPane.setText(text);
cards.next(cardPanel);
}
});
GridBagConstraints bag = new GridBagConstraints();
bag.gridx = 0;
bag.gridy = 0;
bag.gridwidth = 3;
bag.gridheight = 1;
bag.weightx = 1.0;
bag.weighty = 1.0;
bag.fill = GridBagConstraints.BOTH;
bag.anchor = GridBagConstraints.NORTH;
bag.insets = new Insets(5,bag);
setSize(1000,500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
Main ui = new Main();
});
}
}
我添加了:
scrollPane.setPreferredSize(new Dimension(Integer.MAX_VALUE,50));
我实际上并不希望它是 50,但幸运的是它并没有让它高 50 像素。我只是想让它或多或少保持窗口高度的一半,就像开始时一样。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。