下面是我原来问题的具体答案,但如果您想总体上实现类似的结构,那么遵循下面 camickr 的方法可能会更实用。要按照我最初想要的方式做到这一点,您必须重写 JPanel 并为外部容器实现 Scrollable。 (归功于用户 Kylar - JTextArea on JPanel inside JScrollPane does not resize properly )
import javax.swing.*;
import java.awt.*;
import javax.swing.text.*;
public class MyEditor extends JTextPane {
JFrame window;
JScrollPane editScroll;
NumberLines numPane;
HoldMe please;
public static void main(String args[]) {
new MyEditor();
}
MyEditor() {
setOpaque(false);
setEditorKit(new TextWrapKit());
numPane = new NumberLines();
numPane.setPreferredSize(new Dimension(50,100));
please = new HoldMe();
please.setLayout(new BorderLayout());
please.add(this,BorderLayout.CENTER);
please.add(numPane,BorderLayout.WEST);
editScroll = new JScrollPane(please);
editScroll.setPreferredSize(new Dimension(500,500));
editScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
editScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(editScroll);
window.pack();
window.setVisible(true);
}
private class HoldMe extends JPanel implements Scrollable{
public Dimension getPreferredScrollableViewportSize() {
return super.getPreferredSize(); //tell the JScrollPane that we want to be our 'preferredSize' - but later, we'll say that vertically, it should scroll.
}
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 16;//set to 16 because that's what you had in your code.
}
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 16;//set to 16 because that's what you had set in your code.
}
public boolean getScrollableTracksViewportWidth() {
return true;//track the width, and re-size as needed.
}
public boolean getScrollableTracksViewportHeight() {
return false; //we don't want to track the height, because we want to scroll vertically.
}
}
private class NumberLines extends JPanel {
NumberLines() {
setBackground(new Color(120,120,120));
setOpaque(false);
repaint();
}
@Override
protected void paintComponent(Graphics g) {
g.fillRect(0,0,this.getWidth(),this.getHeight());
}
}
private class TextWrapKit extends StyledEditorKit {
ViewFactory defaultFactory=new TextWrapFactory();
public ViewFactory getViewFactory() {
return defaultFactory;
}
}
private class TextWrapFactory implements ViewFactory {
public View create(Element elem) {
String kind = elem.getName();
if (kind != null) {
if (kind.equals(AbstractDocument.ContentElementName)) {
return new TextWrapView(elem);
} else if (kind.equals(AbstractDocument.ParagraphElementName)) {
return new ParagraphView(elem);
} else if (kind.equals(AbstractDocument.SectionElementName)) {
return new BoxView(elem, View.Y_AXIS);
} else if (kind.equals(StyleConstants.ComponentElementName)) {
return new ComponentView(elem);
} else if (kind.equals(StyleConstants.IconElementName)) {
return new IconView(elem);
}
}
// default to text display
return new LabelView(elem);
}
}
private class TextWrapView extends LabelView {
public TextWrapView(Element elem) {
super(elem);
}
public float getMinimumSpan(int axis) {
switch (axis) {
case View.X_AXIS:
return 0;
case View.Y_AXIS:
return super.getMinimumSpan(axis);
default:
throw new IllegalArgumentException("Invalid axis: " + axis);
}
}
}
}
编辑:代码替换为 SCCE,抱歉给您带来麻烦
好吧,它的结构是这样的......
• 顶级 - 扩展 JTextPane
• 将此 JTextPane 放入设置为 BorderLayout CENTER 的 JPanel
• 将另一个 JPanel 放入设置为 WEST 的同一个 JPanel
• 将容纳两者的 JPanel 放入 JScrollPane
• 准备部署(不)
基本上,我无法找到一种方法来做到这一点而不丢失一些关键的东西。我可以把它们全部放在一起,但我会失去滚动。或者我会向后滚动,但随后会丢失文本换行。有一次我换行,从技术上讲它滚动了,但没有达到应有的效果,换句话说,滚动 Pane 没有检测到文本的大小。我需要嵌套的 JPanel(第一个)与 JTextPane 一起滚动
问题区域在下面的构造函数中,抱歉,它太乱了,但我在这里尝试不同的东西时失去了它......可能没有帮助。如果有人能帮我解决这个问题,我将非常感激。
感谢您的阅读。
import javax.swing.*;
import java.awt.*;
import javax.swing.text.*;
import java.awt.BorderLayout;
public class MyEditor extends JTextPane {
JFrame window;
JScrollPane editScroll;
public static void main(String args[]) {
new MyEditor();
}
MyEditor() {
setOpaque(false);
setEditorKit(new TextWrapKit());
JPanel numPane = new JPanel();
JPanel packEdit = new JPanel();
packEdit.setLayout(new BorderLayout());
packEdit.add(this,BorderLayout.CENTER);
packEdit.add(numPane,BorderLayout.WEST);
editScroll = new JScrollPane(packEdit);
editScroll.setPreferredSize(new Dimension(500,500));
editScroll.setViewportView(packEdit);
editScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
editScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.add(editScroll);
window.pack();
window.setVisible(true);
}
private class TextWrapKit extends StyledEditorKit {
ViewFactory defaultFactory=new TextWrapFactory();
public ViewFactory getViewFactory() {
return defaultFactory;
}
}
private class TextWrapFactory implements ViewFactory {
public View create(Element elem) {
String kind = elem.getName();
if (kind != null) {
if (kind.equals(AbstractDocument.ContentElementName)) {
return new TextWrapView(elem);
} else if (kind.equals(AbstractDocument.ParagraphElementName)) {
return new ParagraphView(elem);
} else if (kind.equals(AbstractDocument.SectionElementName)) {
return new BoxView(elem, View.Y_AXIS);
} else if (kind.equals(StyleConstants.ComponentElementName)) {
return new ComponentView(elem);
} else if (kind.equals(StyleConstants.IconElementName)) {
return new IconView(elem);
}
}
// default to text display
return new LabelView(elem);
}
}
private class TextWrapView extends LabelView {
public TextWrapView(Element elem) {
super(elem);
}
public float getMinimumSpan(int axis) {
switch (axis) {
case View.X_AXIS:
return 0;
case View.Y_AXIS:
return super.getMinimumSpan(axis);
default:
throw new IllegalArgumentException("Invalid axis: " + axis);
}
}
}
}
最佳答案
extends JTextPane
为什么?
为什么?setEditorKit(new TextWrapKit());
使滚动 Pane 与默认组件一起使用。然后,如果由于某种原因您仍然需要自定义,请一次进行一项更改以确保它仍然有效。如果它不再起作用,那么您就知道问题出在哪里。
packEdit.add(numPane,BorderLayout.WEST);
在我看来,您正在尝试添加行号。执行此操作的标准方法是将组件添加到滚动 Pane 的行标题,而不是使其成为添加到视口(viewport)的面板的一部分。请参阅Text Component Line Number有关此方法的示例。
将来,每个问题都应该发布一个 SSCCE
。您无需 SSCCE
即可获得一个免费(尝试)答案。
关于java - 如何正确地将 JTextPane/JPanel 打包到 JPanel 中到 JScrollPane 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20182978/