Java6/Swing:JScrollPane顶部的绘画';s视口/视口组件

Java6/Swing:JScrollPane顶部的绘画';s视口/视口组件,java,swing,rendering,jscrollpane,paint,Java,Swing,Rendering,Jscrollpane,Paint,我想实现一个定制的JScrollPane,它能够在它自己的视口/视口组件的顶部的客户区中进行绘制。这方面的挑战是,当用户滚动视口或换言之,视口组件重新绘制时,保持自定义绘制代码重新绘制 我的目标是获得与iOS(iPhone/iPad)半透明滚动条相同的效果,这些滚动条呈现在可滚动列表的顶部(而不是经典的滚动条) 所以这只是一个绘画问题,不是关于滚动的问题:) 我已经做了一些工作,如下所示(下面的代码只在JScrollPane上方呈现了一条绿色测试行): 运行代码时,它看起来如下所示: 这里的关

我想实现一个定制的JScrollPane,它能够在它自己的视口/视口组件的顶部的客户区中进行绘制。这方面的挑战是,当用户滚动视口或换言之,视口组件重新绘制时,保持自定义绘制代码重新绘制

我的目标是获得与iOS(iPhone/iPad)半透明滚动条相同的效果,这些滚动条呈现在可滚动列表的顶部(而不是经典的滚动条)

所以这只是一个绘画问题,不是关于滚动的问题:)

我已经做了一些工作,如下所示(下面的代码只在JScrollPane上方呈现了一条绿色测试行):

运行代码时,它看起来如下所示:

这里的关键是将视口和视口组件设置为非不透明:

// From: ScrollPaneTest.configureUi()
textArea.setOpaque( false );
以及:

(如果不将这些设置为非不透明,JScrollPane将不会重新绘制,视口组件(JTextArea)将覆盖绿线)

现在我比较简单的问题是

有更好的方法吗?在两个组件上都必须使用
setOpaque(false)
,这感觉不太好

非常感谢你的帮助

在两个组件上都必须使用setOpaque(false)感觉不太好

好吧,也许容易一点。您可以重写JViewport的paintComponent()方法,然后只需在文本区域使用setOpaque(false),而不必在视口中使用:)


否则,我认为您需要使用
JLayer
类。有关示例,请参见Swing教程中的部分。

好吧,您可以不尝试直接在JScrollPane上绘制,而是以您想要的方式控制布局管理和视图端口和滚动条的布局。这里的困难在于如何分辨角和行/列headers@MadProgrammer有趣的想法。。如果我理解正确,我可以尝试布局正常的垂直JScrollBar,使其显示在JScrollPane的顶部,然后为JScrollBar实现自定义绘制?我不确定基本代码是否能够将每一个绘制在另一个之上,而不会出现我用原始方法避免的绘制问题。因为这里的主要问题是Java的绘画优化,因此那些
setOpaque(false)
JViewport
JScrollbar
都是组件,所以基本上,是的,控制布局管理(由
JScrollPane
控制)。您可以根据您的需要使
JScrollBar
s透明化,诀窍是让它们在一段时间后“隐藏”或鼠标悬停时显示…简化它的有趣方法-但不幸的是,您的示例并非100%正确。尝试运行它,然后在JTextArea中选择文本。您将看到所选内容覆盖了您的圆。使用我的代码(
setOpaque(false)
),圆圈(或绿线)正确地覆盖了整个JTextArea及其所选文本。但感谢JLayer的提示-我认为这绝对是正确的方法。@it'sLeto,
选择绘制你的圆圈
-有趣的是,你每天都会学到一些新东西:)然而,它似乎在你的工作中覆盖了
绘制()
,而不是绘制组件()。但是,我也同意JLayout可能是更好的方法。好的,我认为使用JLayer是我问题的正确答案。我不想将您的答案设置为正确,因为JLayer提示只是一个最下面的提示:)什么是Stackoverflow的好方法,您想给出一个我可以设置为正确的单独答案(JLayer)吗?或者我应该把这个答案设置为正确的?谢谢:)@It'sLeto,
我不想把你的答案设置为正确的,因为JLayer提示只是一个提示:)
-答案为你指明了正确的方向,并给出了两种可能的解决方案。在您的评论中,您包含了您最喜欢的解决方案。其他阅读文章的人可以选择他们喜欢的方法。是的,问题已经得到了回答,因为这两种方法都有效。好的,我接受了你的正确答案-非常感谢!
// From: ScrollPaneTest.configureUi()
textArea.setOpaque( false );
// From: TestScrollPane.paintChildren()
JViewport viewPort = super.createViewport();
viewPort.setOpaque( false );
import java.awt.*;
import javax.swing.*;

public class ScrollPaneTest5
{
    private JFrame          frame;
    private JScrollPane  scrollPane;
    private JTextArea       textArea;

    public static void main( String[] args ) throws Exception
    {
        UIManager.setLookAndFeel( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
        new ScrollPaneTest5();
    }

    public ScrollPaneTest5()
    {
        configureUi();

        SwingUtilities.invokeLater( new Runnable() {
            @Override public void run() {
                frame.setVisible( true );
            }
        } );
    }

    private void configureUi()
    {
        textArea = new JTextArea();
        textArea.setWrapStyleWord( true );
        textArea.setLineWrap( true );
//        textArea.setOpaque( false );
        textArea.setText( "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor "
                + "invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo "
                + "duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor "
                + "sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor "
                + "invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et "
                + "justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum "
                + "dolor sit amet." );

        scrollPane = new JScrollPane();
//        scrollPane.setViewportView( textArea );
        scrollPane.setLocation( 50, 50 );
        scrollPane.setSize( 200, 200 );

        frame = new JFrame( getClass().getSimpleName() );
        frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
        frame.setLayout( null );
        frame.setSize( 340, 380 );
        frame.setLocationRelativeTo( null );

        frame.add( scrollPane );



        JViewport viewport = new JViewport()
        {
            public void paintComponent(Graphics g)
            {
                super.paintComponent(g);

                g.setColor( Color.BLUE );
                g.drawArc( 100, 100, 80, 80, 0, 360);
            }
        };

        textArea.setOpaque( false );
        viewport.setView(textArea);
        scrollPane.setViewport( viewport );
    }
}