如何在 JScrollPane 中获取(可变)组件的完整大小?

Posted

技术标签:

【中文标题】如何在 JScrollPane 中获取(可变)组件的完整大小?【英文标题】:How to get the full size of a (changeable) component inside a JScrollPane? 【发布时间】:2016-04-04 17:52:22 【问题描述】:

我的代码是这样的:

JFrame frame = new JFrame();

JPanel panel = new JPanel();

JTextPane text = new JTextPane();
text.setPreferredSize(new Dimension(200,260));
text.setContentType("text/html");
text.setEditable(false);
text.setText("some random thing makes this pane bigger than its perferred size");

JScrollPane scroll = new JScrollPane(text);

panel.add(scroll);

frame.add(panel);
frame.setVisible(true);
frame.pack();
frame.validate();

我的问题是我不知道如何获得JTextPane 的实际大小(此处的文本)。我已经尝试了所有getSizesgetVisibleRectsscroll.getViewport().getViewSize()... 但他们都返回[200,260]。有人可以帮我解决这个问题吗?非常感谢您提供的任何帮助。

编辑:我发现了问题:我的getSizes 请求是在验证框架之前执行的。 我的可运行测试代码:

import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;

public class Abcd 

public static void main(String[] args) 
    // TODO Auto-generated method stub
    JFrame frame = new JFrame();

    JPanel panel = new JPanel();

    JTextPane text = new JTextPane();
    text.setPreferredSize(new Dimension(150,126));
    text.setContentType("text/html");
    text.setEditable(false);

    //Alicia Vikander's photo. She's cute anw.
    String tmp = "<a href=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Alicia_Vikander.jpg/220px-Alicia_Vikander.jpg\"><img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Alicia_Vikander.jpg/220px-Alicia_Vikander.jpg\"/></a>";
    //text.setText("asdf fssdfsdf sfdsdf sd sdf sfasdf fssdfsdf sfdsdf sd sdf sfasdf fssdfsdf sfdsdf sd sdf sfasdf fssdfsdf sfdsdf sd sdf sfasdf fssdfsdf sfdsdf sd sdf sfasdf fssdfsdf sfdsdf sd sdf sfasdf fssdfsdf sfdsdf sd sdf sfasdf fssdfsdf sfdsdf sd sdf sfasdf fssdfsdf sfdsdf sd sdf sfasdf fssdfsdf sfdsdf sd sdf sfasdf fssdfsdf sfdsdf sd sdf sfasdf fssdfsdf sfdsdf sd sdf sfasdf fssdfsdf sfdsdf sd sdf sf");
    text.setText(tmp);
    JScrollPane scroll = new JScrollPane(text);
    scroll.setPreferredSize(new Dimension(150,126));

    panel.add(scroll);

    frame.add(panel);
    frame.setVisible(true);
    frame.pack();
    frame.validate();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    for (double i = 0; i < 1000; i = i +  0.0001)
        System.out.print(text.getHeight()+"\n");            
        if (text.getHeight()!=123)   //3 pixels for the scrollpane's border i guessed
            System.out.print("i = "+i+", height = "+text.getHeight());
            break;
        
    

在我的计算机中i 大约是 50 - 100。所以我的新问题是:无论如何我可以尽快获得实际尺寸,但仍确保框架经过验证? 非常感谢。

【问题讨论】:

当我运行它时,您的测试实际上并没有改变text 的大小,而只是换行。我将你的测试文本乘以 50,然后它改变了大小,text.getSize() 相应地改变了它的输出 but they're all returning [200,260]. 不要使用setPreferredSize() 方法。 谢谢大家。我终于可以找出为什么它们返回[200,260] 而不是实际大小:getSizes 请求是在验证框架之前完成的。我已经编辑了这个问题,放了我的可运行示例(原来的示例有点微薄,我的错误)。我现在的问题是如何确保我可以在框架已经验证时获得尺寸。再次感谢您的帮助。 【参考方案1】:

我强烈建议你开始使用不同的Layout managers。

如果我对你的代码进行一些修改:

JFrame frame = new JFrame();

final JTextPane text = new JTextPane();
text.setContentType("text/html");
text.setEditable(false);
text.setText("some random thing makes this pane bigger than its perferred size");

final JScrollPane scroll = new JScrollPane(text);
scroll.addComponentListener(new ComponentAdapter()  
        @Override
        public void componentResized(ComponentEvent e) 
            System.out.println("Size of JScrollPane is: " + scroll.getSize());
            System.out.println("Size of JTextPane is: " + text.getSize());
        
);

frame.setLayout(new BorderLayout());
frame.add(scroll,BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);

我们将滚动组件的大小调用它的scroll.getSize() 和文本组件的大小调用它的text.getSize()

【讨论】:

我已经编辑了我的帖子(我的旧帖子太少了,我的错)。好吧,这是我的新(真正)问题。希望你能帮我解决它。再次感谢您的帮助 @HaM.1 不能真正理解你的循环???,而且你坚持不使用布局管理器....(请考虑使用它),因为如果组件大小可能会有所不同重新调整大小,我会使用 ComponentListener 作为示例来了解它们的大小...... 我使用 for 循环而不是 timertask 或其他东西来显示结果随时间的变化。我使用的代码实际上正在运行并且大小确实发生了变化,但for 循环向我显示我的下一行是在框架仍在验证时执行的。最终结果应该是height = 283,但我只能在索引运行到 50 时才能得到它(123 是内部没有文本的原始高度)。我尝试过使用布局管理器,但没有太大帮助,所以我没有将它放入示例代码中。 这不是真正正确的编码风格考虑在显示之前使用监听器示例验证,然后在 componentShown(ComponentEvent e) (ComponentListener) 中执行您的代码

以上是关于如何在 JScrollPane 中获取(可变)组件的完整大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何强制刷新/重绘 JScrollPane?

JScrollPane 组件不出现

调整JScrollPane大小的最佳实践

如何检查 JScrollPane 中的 JComponent 是不是对用户可见?

JScrollPane

使 JScrollPane 控制多个组件