Java JSplitPane内的2个同步JScrollPane工作不正常

Java JSplitPane内的2个同步JScrollPane工作不正常,java,swing,jscrollpane,jsplitpane,Java,Swing,Jscrollpane,Jsplitpane,我对Swing有意见。我将两个JScrollPane水平放置在一个JSplitPane中,并同步了JScrollPane。在每个JScrollPane中,我放置了一个JPanel。两个JScrollPane之间的同步(滚动一个JScrollPane也滚动另一个JScrollPane)工作正常。但当我向左/向右拖动JSplitPane分隔符直到JPanel的某个部分被隐藏时,水平滚动条就会显示出来,但处于禁用状态。我无法滚动查看JPanel的隐藏部分 代码如下: import java.awt.B

我对Swing有意见。我将两个JScrollPane水平放置在一个JSplitPane中,并同步了JScrollPane。在每个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();
    }

}

可能关键是移动JSplitPane的分隔符不会调整JScrollPane的大小。然而,JScrollPane上的视图发生了更改,因此滚动条由JScrollPane显示(当组件的首选大小大于JScrollPane中JPanel上的视口大小时,滚动条会自动显示) 但是滚动条变灰了,因为从JScrollPane的角度来看,没有必要滚动(它包含的JPanel没有调整大小,因此没有超过JScrollPane的大小…)

更新这对我来说很有效,解决方案是在JPanel中放入滚动条显示的尽可能多的内容(快速滚动时字体有点碎裂)

导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.Color;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JSplitPane;
公共类SplitPaneTest扩展了JFrame{
公共SplitPaneTest(){
SETTILE(“拆分”);
setDefaultCloseOperation(关闭时退出);
设置大小(200200);
JPanel panel1=新的JPanel();
panel1.setLayout(新的BorderLayout());
镶板1.立根背景(颜色:黄色);
panel1.setLayout(新的BorderLayout());
//面板1.设置最小尺寸(新尺寸(100200));
//面板1.设置首选尺寸(新尺寸(100200));
//面板1.重新验证();
面板1.添加(新的JLabel(“左面板!fhajsdfasbkbsdkjafbkajhbshabshjdfbajsbskjask”);
JScrollPane scrollPane1=新的JScrollPane(panel1,JScrollPane.VERTICAL\u SCROLLBAR\u根据需要,JScrollPane.HORIZONTAL\u SCROLLBAR\u根据需要);
//滚动窗格1.设置最小尺寸(新尺寸(100200));
//scrollPane1.setPreferredSize(新尺寸(100200));
//scrollPane1.revalidate();
JPanel panel2=新的JPanel();
panel2.setLayout(新的BorderLayout());
//面板2.设置最小尺寸(新尺寸(100200));
//面板2.设置首选尺寸(新尺寸(100200));
//面板2.重新验证();

panel2.添加(新JLabel)(“右面板DFGASDGSDGGHSGS当组件的首选大小大于滚动窗格的大小时,将自动显示滚动条

不能共享模型,因为每个滚动条的状态将取决于分配给每个滚动窗格的空间。只有当同步窗格的分隔符位于中间时,它们才会同步。

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

比如:

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 );
                }
            }
        }
    }

}

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

scrollPaneCreating.getViewport().setMinimumSize(新尺寸(160200));正在使JSplitPane分隔符无法调整大小。我希望JScrollPane在需要时显示。在JScrollPane上设置最小大小不允许我调整JSplitPane分隔符的大小。因此我执行了以下操作:scrollPane1.getViewport().setMinimumSize(新维度(160200));scrollPane2.getViewport().setMinimumSize(新维度(160200));仍然不走运。调整JSplitPane分隔符的大小后,滚动窗格无法显示其隐藏内容。请勿播放大小(首选、最小、最大)。组件应负责了解其自身大小,并应随着组件属性的更改而动态更改。setPreferredSize()在这里的其他几个线程中提到了variant,因此我尝试了它,它也可以工作…问题在于下面的代码片段:scrollPane2.getVerticalScrollBar().setModel(scrollPane1.getVerticalScrollBar().getModel());scrollPane2.getHorizontalScrollBar().setModel(scrollPane1.getHorizontalScrollBar().getModel());谢谢@camickr为我节省了时间。哇,太棒了。你的代码完全符合我的要求。
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 );
                }
            }
        }
    }

}