2 JSplitPane 中同步的 JScrollPanes 无法正常工作



我对 Swing 有问题。我已经将两个JScrollPane水平放置在JSplitPane中,并同步了JScrollPanes。在每个JScrollPane中,我放置了一个JPanel。两个JScrollPane之间的同步,即(滚动一个JScrollPane也会滚动另一个JScrollPane)正常工作。但是当我向左/向右拖动 JSplitPane 分隔符直到 JPanel 的某些部分被隐藏时,将显示水平滚动条,但以禁用的形式显示。我无法滚动查看 JPanel 的隐藏部分。

这是代码:

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
public class SplitPaneTest extends JFrame {
    public SplitPaneTest() {
        setTitle( "Splits" );
        setDefaultCloseOperation( EXIT_ON_CLOSE );
        setSize( 400, 400 );
        JPanel panel1 = new JPanel();
        panel1.setLayout(new BorderLayout());
        panel1.add( new JLabel( "Left panel!" ) );
        JScrollPane scrollPane1 = new JScrollPane(panel1);
        JPanel panel2 = new JPanel();
        panel2.setLayout(new BorderLayout());
        panel2.add( new JLabel( "Right Panel" ) );
        JScrollPane scrollPane2 = new JScrollPane(panel2);
        scrollPane2.getVerticalScrollBar().setModel(scrollPane1.getVerticalScrollBar().getModel());
        scrollPane2.getHorizontalScrollBar().setModel(scrollPane1.getHorizontalScrollBar().getModel());
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, scrollPane1,
                scrollPane2);
        splitPane.setResizeWeight(0.5);
        add(splitPane);
        setVisible( true );
    }
    public static void main( String[] args ) {
        new SplitPaneTest();
    }
}

当组件的首选大小大于滚动窗格的大小时,将自动显示滚动条。

您无法共享模型,因为每个滚动条的状态会有所不同,具体取决于分配给每个滚动窗格的空间量。它们唯一同步的时间是当拆分窗格的分隔线位于中间时。

因此,您需要侦听每个滚动窗格的滚动条中的更改,而不是尝试从另一个滚动窗格调整滚动条。

像这样:

import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import java.awt.event.*;
public class SplitPaneTest2 extends JFrame {
    public SplitPaneTest2() {
        setTitle( "Splits" );
        setDefaultCloseOperation( EXIT_ON_CLOSE );
        setSize( 400, 400 );
        JPanel panel1 = new JPanel();
        panel1.setLayout(new BorderLayout());
        panel1.add( new JLabel( "Left panel!11111111111111111111" ) );
        JScrollPane scrollPane1 = new JScrollPane(panel1);
        JPanel panel2 = new JPanel();
        panel2.setLayout(new BorderLayout());
        panel2.add( new JLabel( "Right Panel11111111111111111111" ) );
        JScrollPane scrollPane2 = new JScrollPane(panel2);
//        scrollPane2.getVerticalScrollBar().setModel(scrollPane1.getVerticalScrollBar().getModel());
//        scrollPane2.getHorizontalScrollBar().setModel(scrollPane1.getHorizontalScrollBar().getModel());
        new ScrollBarSynchronizer(scrollPane1.getHorizontalScrollBar(), scrollPane2.getHorizontalScrollBar());
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, scrollPane1,
                scrollPane2);
        splitPane.setResizeWeight(0.5);
        add(splitPane);
        setVisible( true );
    }
    public static void main( String[] args ) {
        new SplitPaneTest2();
    }
    static class ScrollBarSynchronizer implements AdjustmentListener
    {
        JScrollBar[] scrollBars;
        public ScrollBarSynchronizer(JScrollBar... scrollBars)
        {
            this.scrollBars = scrollBars;
            for (JScrollBar scrollBar: scrollBars)
                scrollBar.addAdjustmentListener( this );
        }
        @Override
        public void adjustmentValueChanged(AdjustmentEvent e)
        {
            JScrollBar source = (JScrollBar)e.getSource();
            int value = e.getValue();
            for (JScrollBar scrollBar: scrollBars)
            {
                if (scrollBar != source)
                {
                    scrollBar.removeAdjustmentListener( this );
                    scrollBar.setValue( value );
                    scrollBar.addAdjustmentListener( this );
                }
            }
        }
    }
}

您还可以为垂直滚动条创建单独的同步器。

也许关键是移动JSplitPane的分隔符不会调整JScrollPane的大小。尽管如此,JScrollPane 上的 VIEW 还是发生了变化,因此滚动条由 JScrollPane 显示(当组件的首选大小大于 JScrollPane 中 JPanel 上的视口大小时,滚动条会自动出现)但是滚动条是灰色的,因为从JScrollPane的角度来看,没有必要滚动(它包含的JPanel没有调整大小,因此不超过JScrollPane的大小......

更新这对我有用,解决方案是在滚动条出现的 JPanels 中放置尽可能多的内容(快速滚动时字体有点碎)

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
public class SplitPaneTest extends JFrame {
    public SplitPaneTest() {
        setTitle( "Splits" );
        setDefaultCloseOperation( EXIT_ON_CLOSE );
        setSize( 200, 200 );
        JPanel panel1 = new JPanel();
        panel1.setLayout(new BorderLayout());
        panel1.setBackground(Color.YELLOW);
        panel1.setLayout(new BorderLayout());
        //panel1.setMinimumSize(new Dimension(100,200));
        //panel1.setPreferredSize(new Dimension(100,200));
        //panel1.revalidate();            
        panel1.add( new JLabel( "Left panel! fhajsdfasbkfbbsdkjafbkajhbshabshjdfbajsbskjaSK" ) );

        JScrollPane scrollPane1 = new JScrollPane(panel1,  JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        //scrollPane1.setMinimumSize(new Dimension(100,200));
        //scrollPane1.setPreferredSize(new Dimension(100,200));
        //scrollPane1.revalidate();
        JPanel panel2 = new JPanel();
        panel2.setLayout(new BorderLayout());
        //panel2.setMinimumSize(new Dimension(100,200));
        //panel2.setPreferredSize(new Dimension(100,200));
        //panel2.revalidate();
        panel2.add( new JLabel( "Right Panel dfgasdgsdghsgs<dg<sdgs<dgdsgdfsafasfasfasfsafa" ) );
        JScrollPane scrollPane2 = new JScrollPane(panel2, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        //scrollPane2.setMinimumSize(new Dimension(100,200));
        //scrollPane2.setPreferredSize(new Dimension(100,200));
        //scrollPane2.revalidate();
        scrollPane2.getVerticalScrollBar().setModel(scrollPane1.getVerticalScrollBar().getModel());
        scrollPane2.getHorizontalScrollBar().setModel(scrollPane1.getHorizontalScrollBar().getModel());
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, scrollPane1,
                scrollPane2);
        splitPane.setResizeWeight(0.5);
        //splitPane.setContinuousLayout(true);
        this.add(splitPane);
        this.setVisible( true );
    }
    public static void main( String[] args ) {
        new SplitPaneTest();
    }
}

相关内容

  • 没有找到相关文章

最新更新