【问题标题】:How to add multiple JPanels to a JScrollPane?如何将多个 JPanel 添加到 JScrollPane?
【发布时间】:2021-09-16 13:30:47
【问题描述】:

我正在努力将多个 JPanel 容器添加到 Java swing 中的单个 JScrollPane 中。我想要的输出是在JFrame 上的基本面板上存在一个滚动窗格,并让该滚动窗格现在包含 2 个面板。

基本上,就像滚动窗格可以将其视图设置为单个面板一样,我希望将其设置为 2 个面板。

这些面板上唯一存在的东西是在上面绘制的图形,没有JComponent 实例。我查看了类似这样的其他链接:Java Swing: how to add multiple JPanels to a JScrollPane,但我没有得到想要的输出。这是我最新的尝试,它只显示滚动窗格边缘并且面板不可见(最小可重复性):

import javax.swing.*;
import java.awt.*;

public class Test {
    
    public static void main(String[] args) {
        new Test();
    }
    
    public Test() {
        JFrame frame = new JFrame("Test"); //initialize frame
        frame.setSize(500, 500);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        JPanel base = new JPanel(); //make base panel with SpringLayout
        SpringLayout baseLayout = new SpringLayout();
        base.setLayout(baseLayout);
        
        JPanel panel1 = new JPanel() { //initialize JPanels
            public void paintComponent(Graphics tool) {
                super.paintComponent(tool);
                tool.drawRect(50, 50, 100, 100);
            }
        };
        
        JPanel panel2 = new JPanel() {
            public void paintComponent(Graphics tool) {
                super.paintComponent(tool);
                tool.drawRect(75, 75, 50, 50);
            }
        };
        
        Container cont = new Container(); //create a container to hold panels
        SpringLayout contLayout = new SpringLayout();
        cont.setLayout(contLayout);
        
        contLayout.putConstraint(SpringLayout.WEST, panel1, 0, SpringLayout.WEST, cont); 
        contLayout.putConstraint(SpringLayout.NORTH, panel1, 0, SpringLayout.NORTH, cont);
        cont.add(panel1); //add panel1 to top left corner of container
        
        
        contLayout.putConstraint(SpringLayout.WEST, panel2, 0, SpringLayout.WEST, cont); 
        contLayout.putConstraint(SpringLayout.NORTH, panel2, 0, SpringLayout.NORTH, cont);
        cont.add(panel2); //add panel2 to top left corner of container
        
        cont.setPreferredSize(new Dimension(201, 201));
        
        JScrollPane scroll = new JScrollPane(cont); //add container to scroll pane
        scroll.setPreferredSize(new Dimension(200, 200));
        
        baseLayout.putConstraint(SpringLayout.HORIZONTAL_CENTER, scroll, 0, SpringLayout.HORIZONTAL_CENTER, base); 
        baseLayout.putConstraint(SpringLayout.VERTICAL_CENTER, scroll, 0, SpringLayout.VERTICAL_CENTER, base);
        base.add(scroll); //add scroll pane to center of base JPanel
        
        frame.add(base);
        frame.setVisible(true);
    }
}

【问题讨论】:

  • 你在哪里给容器布局?它需要一个体面的布局才能正确定位添加的 JPanel。
  • @DontKnowMuchButGettingBetter 我编辑了我的帖子以包含容器的弹簧布局。可悲的是仍然产生相同的输出
  • 1) 为什么要使用 SpringLayout?这是最复杂的布局管理器之一,可能不需要。 2) 不要使用setPreferedSize()。每个 Swing 组件负责确定自己的首选大小。您可以通过覆盖 getPreferrdSize() 方法来做到这一点。阅读 Custom Painting 上的 Swing 教程以获取完整的工作示例。

标签: java swing jpanel jscrollpane


【解决方案1】:

好吧,所以我做了更多的试验,我添加了这几行,现在两个面板都正确显示在 JScrollPane 中:

panel1.setPreferredSize(cont.getPreferredSize());
panel2.setPreferredSize(cont.getPreferredSize());
        
panel1.setOpaque(false);
panel2.setOpaque(false);

不知道为什么它会起作用,如果有人能解释一下那就太好了。这是工作代码:

import javax.swing.*;
import java.awt.*;

public class Test {
    
    public static void main(String[] args) {
        new Test();
    }
    
    public Test() {
        JFrame frame = new JFrame("Test"); //initialize frame
        frame.setSize(500, 500);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        JPanel base = new JPanel(); //make base panel with SpringLayout
        SpringLayout baseLayout = new SpringLayout();
        base.setLayout(baseLayout);
        
        JPanel panel1 = new JPanel() { //initialize JPanels
            public void paintComponent(Graphics tool) {
                super.paintComponent(tool);
                tool.drawRect(50, 50, 100, 100);
            }
        };
        
        JPanel panel2 = new JPanel() {
            public void paintComponent(Graphics tool) {
                super.paintComponent(tool);
                tool.drawRect(75, 75, 50, 50);
            }
        };
        
        Container cont = new Container(); //create a container to hold panels
        SpringLayout contLayout = new SpringLayout();
        cont.setLayout(contLayout);
        
        contLayout.putConstraint(SpringLayout.WEST, panel1, 0, SpringLayout.WEST, cont); 
        contLayout.putConstraint(SpringLayout.NORTH, panel1, 0, SpringLayout.NORTH, cont);
        cont.add(panel1); //add panel1 to top left corner of container
        
        contLayout.putConstraint(SpringLayout.WEST, panel2, 0, SpringLayout.WEST, cont); 
        contLayout.putConstraint(SpringLayout.NORTH, panel2, 0, SpringLayout.NORTH, cont);
        cont.add(panel2); //add panel2 to top left corner of container
        
        
        cont.setPreferredSize(new Dimension(201, 201));
        panel1.setPreferredSize(cont.getPreferredSize());
        panel2.setPreferredSize(cont.getPreferredSize());
        
        panel1.setOpaque(false);
        panel2.setOpaque(false);
        
        JScrollPane scroll = new JScrollPane(cont); //add container to scroll pane
        scroll.setPreferredSize(new Dimension(200, 200));
        
        baseLayout.putConstraint(SpringLayout.HORIZONTAL_CENTER, scroll, 0, SpringLayout.HORIZONTAL_CENTER, base); 
        baseLayout.putConstraint(SpringLayout.VERTICAL_CENTER, scroll, 0, SpringLayout.VERTICAL_CENTER, base);
        base.add(scroll); //add scroll pane to center of base JPanel
        
        frame.add(base);
        frame.setVisible(true);
    }
}

【讨论】:

  • 空的JPanel 也将返回宽度为 0 像素、高度为 0 像素的首选尺寸。这就是为什么您没有看到面板的原因(它们的尺寸为零,这意味着没有任何东西可以绘制)。
  • @gthanop 哦,我想我认为 swing 会自动尝试为 JPanel 找到首选尺寸。感谢您的明显解释
  • 没问题。另请注意,您可能不打算让panel1panel2 相互重叠...尝试将panel2 的位置更改为EAST+SOUTH,然后您可以看到绘制的两个矩形(即两个面板)。
  • @gthanop 我打算让它们叠加,但正如你所说,如果有必要能够移动它们是很好的
  • 还有OverlayLayout 可以查看...老实说我从未使用过它,但它似乎很有希望覆盖面板。不要忘记在它们上面加上setOpaque(false);,这样你就可以看到两个矩形(这是因为非不透明的JComponent 不必根据the docs 绘制所有包含的像素)。我认为JPanels 默认情况下是不透明的,所以这就是为什么你必须对它们调用setOpaque(false);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多