簡體   English   中英

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

[英]2 Synchronized JScrollPanes inside JSplitPane not working properly

我對Swing有問題。 我在JSplitPane中水平放置了兩個JScrollPane並同步了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的大小...)

更新這對我有用,解決方案是將盡可能多的內容放入滾動條顯示的JPanel中(快速滾動時字體會被切碎)

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM