首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >智能JScrollPane自动投图

智能JScrollPane自动投图
EN

Stack Overflow用户
提问于 2010-08-02 22:28:09
回答 1查看 4.4K关注 0票数 7

我试图在包含JScrollPane的JTextPane上实现智能自动投篮。JTextPane用于记录我的应用程序的颜色。然而,我遇到了一面墙,试图做聪明的自动投篮。我所说的智能自动滚动并不是指每当事物发生变化时盲目地自动滚动,我的意思是检查你的滚动是否一直向下,然后自动滚动。然而,无论我做什么,要么总是自动投稿,要么根本不做。

作为一个测试脚本,下面是设置( JFrame被忽略了)

代码语言:javascript
复制
final JTextPane textPane = new JTextPane();
textPane.setEditable(false);
final JScrollPane contentPane = new JScrollPane(textPane);
contentPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

下面是丑陋的自动添加测试循环

代码语言:javascript
复制
while (true)
    try {
        Thread.sleep(1000);
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JScrollBar scrollBar = scroll;
                    boolean preCheck = ((scrollBar.getVisibleAmount() != scrollBar.getMaximum()) && (scrollBar.getValue() + scrollBar.getVisibleAmount() == scrollBar.getMaximum()));
                    System.out.println("Value: " + scroll.getValue()
                                    + " | Visible: " + scrollBar.getVisibleAmount()
                                    + " | Maximum: " + scrollBar.getMaximum()
                                    + " | Combined: " + (scrollBar.getValue() + scrollBar.getVisibleAmount())
                                    + " | Vis!=Max : " + (scrollBar.getVisibleAmount() != scrollBar.getMaximum())
                                    + " | Comb=Max: " + (scrollBar.getValue() + scrollBar.getVisibleAmount() == scrollBar.getMaximum())
                                    + " | Eval: " + preCheck);
                    StyledDocument doc = textPane.getStyledDocument();
                    doc.insertString(doc.getLength(), "FAGAHSIDFNJASDKFJSD\n", doc.getStyle(""));
                    if (!preCheck)
                            textPane.setCaretPosition(doc.getLength());
                } catch (BadLocationException ex) {
                            ex.printStackTrace();
                }
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }

它不漂亮,但它完成了任务。

这是相关的检查

代码语言:javascript
复制
 boolean preCheck = ((scrollBar.getVisibleAmount() != scrollBar.getMaximum()) && (scrollBar.getValue() + scrollBar.getVisibleAmount() == scrollBar.getMaximum()));
 if (preCheck)
     textPane.setCaretPosition(doc.getLength());

这就是一直给我带来麻烦的部分。首先要检查条形图是否可见但不可用(没有足够的文本,使条形图完整),然后,如果条形条的底部等于最大值。从理论上讲,这是可行的。然而,没有任何东西,包括移动支票,已经得到了我想要的结果。

有什么建议吗?

而不是复制,因为他们希望它总是滚动,而不仅仅是有时。

EN

回答 1

Stack Overflow用户

发布于 2010-08-03 05:08:52

编辑:

我用一个更灵活的版本替换了下面的代码,该版本可以在JScrollPane中的任何组件上工作。退房:智能滚动

代码语言:javascript
复制
import java.awt.*;
import java.awt.event.*;
import java.util.Date;
import javax.swing.*;
import javax.swing.text.*;

public class ScrollControl implements AdjustmentListener
{
    private JScrollBar scrollBar;
    private JTextComponent textComponent;
    private int previousExtent = -1;

    public ScrollControl(JScrollPane scrollPane)
    {
        Component view = scrollPane.getViewport().getView();

        if (! (view instanceof JTextComponent))
            throw new IllegalArgumentException("Scrollpane must contain a JTextComponent");

        textComponent = (JTextComponent)view;

        scrollBar = scrollPane.getVerticalScrollBar();
        scrollBar.addAdjustmentListener( this );
    }

    @Override
    public void adjustmentValueChanged(final AdjustmentEvent e)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                checkScrollBar(e);
            }
        });
    }

    private void checkScrollBar(AdjustmentEvent e)
    {
        //  The scroll bar model contains information needed to determine the
        //  caret update policy.

        JScrollBar scrollBar = (JScrollBar)e.getSource();
        BoundedRangeModel model = scrollBar.getModel();
        int value = model.getValue();
        int extent = model.getExtent();
        int maximum = model.getMaximum();
        DefaultCaret caret = (DefaultCaret)textComponent.getCaret();

        //  When the size of the viewport changes there is no need to change the
        //  caret update policy.

        if (previousExtent != extent)
        {
            //  When the height of a scrollpane is decreased the scrollbar is
            //  moved up from the bottom for some reason. Reposition the
            //  scrollbar at the bottom

            if (extent < previousExtent
            &&  caret.getUpdatePolicy() == DefaultCaret.UPDATE_WHEN_ON_EDT)
            {
                scrollBar.setValue( maximum );
            }

            previousExtent = extent;
            return;
        }

        //  Text components will not scroll to the bottom of a scroll pane when
        //  a bottom inset is used. Therefore the location of the scrollbar,
        //  the height of the viewport, and the bottom inset value must be
        //  considered when determining if the scrollbar is at the bottom.

        int bottom = textComponent.getInsets().bottom;

        if (value + extent + bottom < maximum)
        {
            if (caret.getUpdatePolicy() != DefaultCaret.NEVER_UPDATE)
                caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
        }
        else
        {
            if (caret.getUpdatePolicy() != DefaultCaret.UPDATE_WHEN_ON_EDT)
            {
                caret.setDot(textComponent.getDocument().getLength());
                caret.setUpdatePolicy(DefaultCaret.UPDATE_WHEN_ON_EDT);
            }
        }
    }

    private static void createAndShowUI()
    {
        JPanel center = new JPanel( new GridLayout(1, 2) );
        String text = "1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n";

        final JTextArea textArea = new JTextArea();
        textArea.setText( text );
        textArea.setEditable( false );
        center.add( createScrollPane( textArea ) );
        System.out.println(textArea.getInsets());

        final JTextPane textPane = new JTextPane();
        textPane.setText( text );
        textPane.setEditable( false );
        center.add( createScrollPane( textPane )  );
        textPane.setMargin( new Insets(5, 3, 7, 3) );
        System.out.println(textPane.getInsets());

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(center, BorderLayout.CENTER);
        frame.setSize(500, 200);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        Timer timer = new Timer(2000, new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                try
                {
                    Date now = new Date();
                    textArea.getDocument().insertString(textArea.getDocument().getLength(), "\n" + now.toString(), null);
                    textPane.getDocument().insertString(textPane.getDocument().getLength(), "\n" + now.toString(), null);
                }
                catch (BadLocationException e1) {}
            }
        });
        timer.start();
    }

    private static JComponent createScrollPane(JComponent component)
    {
        JScrollPane scrollPane = new JScrollPane(component);
        new ScrollControl( scrollPane );

        return scrollPane;
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3392290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档