多个JTextPane的滚动条(Java)

多个JTextPane的滚动条(Java),java,scroll,jframe,jscrollpane,jtextpane,Java,Scroll,Jframe,Jscrollpane,Jtextpane,附件是我的窗口代码: import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ScrollPaneConstants; import java.awt.BorderLayout; import javax.swing.JTextPane; public class Window extends JFrame{ private JPane

附件是我的窗口代码:

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import java.awt.BorderLayout;
import javax.swing.JTextPane;
public class Window extends JFrame{
    private JPanel panel;
    private JTextPane textPane;
    private JTextPane textPane_1;   
    public Window() {
        super("Window");
        this.init();
        this.setSize(800, 600);
        this.setVisible(true);
    }
    void init(){
        panel = new JPanel();
        getContentPane().add(panel, BorderLayout.CENTER);
        panel.setLayout(null);      
        textPane = new JTextPane();
        textPane.setBounds(6, 48, 788, 185);
        panel.add(textPane);
        textPane.setFocusable(true);        
        textPane_1 = new JTextPane();
        textPane_1.setBounds(6, 346, 788, 185);
        panel.add(textPane_1);      
        JScrollPane scroll1 = new JScrollPane(textPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scroll1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        scroll1.setViewportView(textPane);
        panel.add(scroll1);
        this.add(scroll1);      
        JScrollPane scroll2 = new JScrollPane(textPane_1, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scroll2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        scroll2.setViewportView(textPane);
        panel.add(scroll2);
        this.add(scroll2);      
        this.add(panel);
    }
}
我的目标是让两个jTextPane都有自己的滚动条。不过,屏幕上显示的只是一个JTextPane(不确定是哪一个),它只有一个垂直滚动条(我认为这是因为JTextPane有换行符)。第二个JTextPane没有显示。有人能帮我吗


提前感谢所有回复者。

在本例中,您可以使用
GridLayout
。请参见上的Swing教程

下面是带有
GridLayout
和内联注释的代码

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;

public class MyWindow extends JFrame {
    private JPanel panel;
    private JTextPane textPane;
    private JTextPane textPane_1;

    public MyWindow() {
        super("Window");
        this.init();
    }

    void init() {
        // panel with GridLayout having 2 rows and 1 column
        panel = new JPanel(new GridLayout(2,1)); 

        textPane = new JTextPane();
        // enclose the text pane inside the scroll pane
        // scroll pane shows scrollbars when needed
        JScrollPane scroll1 = new JScrollPane(textPane);
        // add scroll pane at first column of the first row
        // never add text pane again in the panel because 
        //  it's already added in scroll pane
        panel.add(scroll1);

        textPane_1 = new JTextPane();
        JScrollPane scroll2 = new JScrollPane(textPane_1);
        // add scroll pane  at first column of the second row
        panel.add(scroll2);

        // finally add the panel in the JFrame's content pane in the center
        getContentPane().add(panel, BorderLayout.CENTER);
    }

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){

            @Override
            public void run() {
                MyWindow window=new MyWindow();
                window.setVisible(true);
            }
        });
    }
}
快照:



请看一下Swing教程,本例中您可以使用
GridLayout
。请参见上的Swing教程

下面是带有
GridLayout
和内联注释的代码

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;

public class MyWindow extends JFrame {
    private JPanel panel;
    private JTextPane textPane;
    private JTextPane textPane_1;

    public MyWindow() {
        super("Window");
        this.init();
    }

    void init() {
        // panel with GridLayout having 2 rows and 1 column
        panel = new JPanel(new GridLayout(2,1)); 

        textPane = new JTextPane();
        // enclose the text pane inside the scroll pane
        // scroll pane shows scrollbars when needed
        JScrollPane scroll1 = new JScrollPane(textPane);
        // add scroll pane at first column of the first row
        // never add text pane again in the panel because 
        //  it's already added in scroll pane
        panel.add(scroll1);

        textPane_1 = new JTextPane();
        JScrollPane scroll2 = new JScrollPane(textPane_1);
        // add scroll pane  at first column of the second row
        panel.add(scroll2);

        // finally add the panel in the JFrame's content pane in the center
        getContentPane().add(panel, BorderLayout.CENTER);
    }

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){

            @Override
            public void run() {
                MyWindow window=new MyWindow();
                window.setVisible(true);
            }
        });
    }
}
快照:



请看一下Swing教程,本例中您可以使用
GridLayout
。请参见上的Swing教程

下面是带有
GridLayout
和内联注释的代码

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;

public class MyWindow extends JFrame {
    private JPanel panel;
    private JTextPane textPane;
    private JTextPane textPane_1;

    public MyWindow() {
        super("Window");
        this.init();
    }

    void init() {
        // panel with GridLayout having 2 rows and 1 column
        panel = new JPanel(new GridLayout(2,1)); 

        textPane = new JTextPane();
        // enclose the text pane inside the scroll pane
        // scroll pane shows scrollbars when needed
        JScrollPane scroll1 = new JScrollPane(textPane);
        // add scroll pane at first column of the first row
        // never add text pane again in the panel because 
        //  it's already added in scroll pane
        panel.add(scroll1);

        textPane_1 = new JTextPane();
        JScrollPane scroll2 = new JScrollPane(textPane_1);
        // add scroll pane  at first column of the second row
        panel.add(scroll2);

        // finally add the panel in the JFrame's content pane in the center
        getContentPane().add(panel, BorderLayout.CENTER);
    }

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){

            @Override
            public void run() {
                MyWindow window=new MyWindow();
                window.setVisible(true);
            }
        });
    }
}
快照:



请看一下Swing教程,本例中您可以使用
GridLayout
。请参见上的Swing教程

下面是带有
GridLayout
和内联注释的代码

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;

public class MyWindow extends JFrame {
    private JPanel panel;
    private JTextPane textPane;
    private JTextPane textPane_1;

    public MyWindow() {
        super("Window");
        this.init();
    }

    void init() {
        // panel with GridLayout having 2 rows and 1 column
        panel = new JPanel(new GridLayout(2,1)); 

        textPane = new JTextPane();
        // enclose the text pane inside the scroll pane
        // scroll pane shows scrollbars when needed
        JScrollPane scroll1 = new JScrollPane(textPane);
        // add scroll pane at first column of the first row
        // never add text pane again in the panel because 
        //  it's already added in scroll pane
        panel.add(scroll1);

        textPane_1 = new JTextPane();
        JScrollPane scroll2 = new JScrollPane(textPane_1);
        // add scroll pane  at first column of the second row
        panel.add(scroll2);

        // finally add the panel in the JFrame's content pane in the center
        getContentPane().add(panel, BorderLayout.CENTER);
    }

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){

            @Override
            public void run() {
                MyWindow window=new MyWindow();
                window.setVisible(true);
            }
        });
    }
}
快照:



请看一看Swing教程,从以下两点开始:
JFrame
使用
BorderLayout
默认情况下,
BorderLayout
只允许单个组件占据其五个可用位置中的任意一个。其次,组件只能属于单个父级

看看你的代码

    scroll1.setViewportView(textPane);
    panel.add(scroll1);
    this.add(scroll1);      
    //...
    scroll2.setViewportView(textPane);
    panel.add(scroll2);
    this.add(scroll2);      
    this.add(panel);
  • 您将
    textPane
    设置为
    scroll1
  • scroll1
    添加到
    面板
  • 滚动
    添加到
    ,有效地将其从
    面板
    中删除
  • 您将
    textPane
    设置为
    scroll2
    的视口视图,并将其从
    scroll1
    的视口中删除
  • scroll2
    添加到
    面板
  • 您将
    scroll2
    添加到此中,有效地将其从
    面板中删除
  • 面板
    添加到此,覆盖先前添加到框架中的所有内容
  • 这实际上意味着
    面板
    边框布局
    将尝试在框架上布局的唯一可见组件,但它不包含任何内容

    相反,您可以在将每个滚动窗格添加到框架时为其指定位置,例如

        scroll1.setViewportView(textPane);
        this.add(scroll1, BorderLayout.NORTH);      
        //...
        scroll2.setViewportView(textPane_1);
        this.add(scroll2, BorderLayout.SOUTH);      
    
    使用工作示例更新

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTextPane;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Window extends JFrame {
    
        private JTextPane textPane;
        private JTextPane textPane_1;
    
        public Window() {
            super("Window");
            this.init();
            this.setSize(800, 600);
            this.setVisible(true);
        }
    
        void init() {
            textPane = new JTextPane();
            textPane_1 = new JTextPane();
            JScrollPane scroll1 = new JScrollPane(textPane);
            scroll1.setViewportView(textPane);
            JScrollPane scroll2 = new JScrollPane(textPane_1);
            add(scroll1, BorderLayout.NORTH);
            add(scroll2, BorderLayout.SOUTH);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    Window frame = new Window();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    }
    

    这是
    JTextPane
    的默认行为,它的总体大小由其内容的大小决定

    现在,您可以通过使用
    Scrollable
    界面并指定“initial”、
    PreferredScrollableViewportSize
    ,向scrollpane建议组件要使用多少空间

    幸运的是,
    JTextPane
    已经实现了这个接口,因此您只需要覆盖
    getPreferredScrollableViewportSize
    方法,例如

    textPane = new JTextPane() {
        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(200, 200);
        }
    };
    textPane_1 = new JTextPane() {
        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(200, 200);
        }
    };
    

    请查看以了解更多详细信息


    避免使用
    null
    布局,像素完美的布局在现代ui设计中是一种错觉。影响零部件单个尺寸的因素太多,您无法控制。Swing的设计目的是与核心布局管理器协作,丢弃这些管理器将导致无止境的问题,您将花费越来越多的时间试图纠正这些问题。首先,
    JFrame
    默认情况下使用
    边框布局,
    BorderLayout
    仅允许单个组件占据其五个可用位置中的任意一个。其次,组件只能属于单个父级

    看看你的代码

        scroll1.setViewportView(textPane);
        panel.add(scroll1);
        this.add(scroll1);      
        //...
        scroll2.setViewportView(textPane);
        panel.add(scroll2);
        this.add(scroll2);      
        this.add(panel);
    
  • 您将
    textPane
    设置为
    scroll1
  • scroll1
    添加到
    面板
  • 滚动
    添加到
    ,有效地将其从
    面板
    中删除
  • 您将
    textPane
    设置为
    scroll2
    的视口视图,并将其从
    scroll1
    的视口中删除
  • scroll2
    添加到
    面板
  • 您将
    scroll2
    添加到此中,有效地将其从
    面板中删除
  • 面板
    添加到此,覆盖先前添加到框架中的所有内容
  • 这实际上意味着
    面板
    边框布局
    将尝试在框架上布局的唯一可见组件,但它不包含任何内容

    相反,您可以在将每个滚动窗格添加到框架时为其指定位置,例如

        scroll1.setViewportView(textPane);
        this.add(scroll1, BorderLayout.NORTH);      
        //...
        scroll2.setViewportView(textPane_1);
        this.add(scroll2, BorderLayout.SOUTH);      
    
    使用工作示例更新

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTextPane;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Window extends JFrame {
    
        private JTextPane textPane;
        private JTextPane textPane_1;
    
        public Window() {
            super("Window");
            this.init();
            this.setSize(800, 600);
            this.setVisible(true);
        }
    
        void init() {
            textPane = new JTextPane();
            textPane_1 = new JTextPane();
            JScrollPane scroll1 = new JScrollPane(textPane);
            scroll1.setViewportView(textPane);
            JScrollPane scroll2 = new JScrollPane(textPane_1);
            add(scroll1, BorderLayout.NORTH);
            add(scroll2, BorderLayout.SOUTH);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    Window frame = new Window();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    }
    

    这是
    JTextPane
    的默认行为,它的总体大小由其内容的大小决定

    现在,您可以通过使用
    Scrollable
    界面并指定“initial”、
    PreferredScrollableViewportSize
    ,向scrollpane建议组件要使用多少空间

    幸运的是,
    JTextPane
    已经实现了这个接口,因此您只需要覆盖
    getPreferredScrollableViewportSize
    方法,例如

    textPane = new JTextPane() {
        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(200, 200);
        }
    };
    textPane_1 = new JTextPane() {
        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(200, 200);
        }
    };
    

    请查看以了解更多详细信息

    避免使用
    null
    布局,像素完美的布局在现代ui设计中是一种错觉。影响零部件单个尺寸的因素太多,您无法控制。Swing的设计宗旨是与核心的布局管理器协作,丢弃它们将导致无止境的问题,您将花费越来越多的时间来纠正这些问题