用 JLabel 修复 JScrollPane

fixing JScrollPane with JLabel

为了添加背景图像,我使用 JLabels 而不是 JPanel。

    JFrame frame=new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JLabel label=new JLabel(new ImageIcon("bg.png"));
    label.setLayout(new BoxLayout(label, BoxLayout.Y_AXIS));
    for(int i=0;i<20;i++)
         label.add(new JLabel(i.toString()));
    frame.add(label);

这里的问题是只有适合背景图像的组件才会显示(在我的例子中只有前 10 个 JLabel)

我尝试使用 JScrollPane

    JScrollPane scroll=new JScrollPane(l);
    for(int i=0;i<20;i++)
         label.add(new JLabel(i.toString()));
    frame.add(scroll);

但变化不大,所以我尝试使用 JPanel

    JPanel panel=new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
    JScrollPane scroll=new JScrollPane(panel);
    for(int i=0;i<20;i++)
         panel.add(new JLabel(i.toString()));
    label.add(scroll);
    frame.add(label);

所以我让 JScrollPane 正常工作,但 JPanel 覆盖了背景图像

我该怎么办?

这是将 JLabel 添加到标签的结果:

加入卷轴后的结果:

并且在将 setOpaque(false) 添加到 JPanel 之后:

您可以将图像添加为 JPanelpaintComponent() 方法的一部分,然后在其上方添加标签,然后将该窗格放入 JScrollPane 中,最后添加它到 JFrame,例如:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class PanelWithBackgroundImage {
    
    private JFrame frame;
    private JPanel pane;
    private Image img;
    private JScrollPane scroll;
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            
            @Override
            public void run() {
                new PanelWithBackgroundImage().createAndShowGui();
            }
        });
    }
    
    public void createAndShowGui() {
        frame = new JFrame("JFrame with bg example");
        try {
            img = ImageIO.read(new FileInputStream("/home/jesus/Pictures/tokyo.jpg"));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        pane = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
            }
        };
        
        pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
        
        for (int i = 0; i < 20; i++) {
            pane.add(new JLabel("label " + i));
        }
        
        scroll = new JScrollPane(pane);
        
        frame.add(scroll);
        frame.setSize(frame.getPreferredSize());
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

给出以下输出:

如果你想让 JLabels 居中,你可以改变 for 循环:

for (int i = 0; i < 20; i++) {
    JLabel label = new JLabel("label " + i);
    label.setAlignmentX(Component.CENTER_ALIGNMENT);
    pane.add(label);
}

看起来应该与此类似:


注:

您可以复制粘贴上面的代码,它应该可以工作,只需更改图像路径,并且该代码称为 Minimal, Complete and Verifiable Example (MCVE),下次请 post 演示什么你已经尝试过了,不仅仅是它的一部分,这样你会得到更多、更好、更快的答案。帮助我们帮助你! :)