Jscrollpane 在标签太小时居中对齐

Jscrollpane center aligns when label is too small

这个问题和这个非常相似:我试过这个解决方案,但它不起作用。

当我在jscrollpane 中添加jlabel 时,当jlabel 较小时,标签会居中。滚动条显示时它正常工作。设置 boxlayout 不会改变任何东西。我觉得这不能正常工作,因为我正在为面板设置一个首选尺寸?但是,如果我删除 panel.setPreferredSize(new Dimension((int)(screenSize.width*0.7 - 50), screenSize.height-150)); 行,当没有文本时,标签会变小,并且会变大以容纳我不想要的文本。如果我添加面板而不是标签,即使没有文本,它也会使屏幕滚动?

这是我的代码:

public class Test {
    // JFrame 
    static JFrame frame = new JFrame("Test"); 
    //panel 1
    static JPanel panel = new JPanel(new BorderLayout());
    // label to display text 
    static JLabel label = new JLabel(); 
    //scroll panel in main method
    
    
    public static void main(String[] args) throws Exception {
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

        label.setBorder(new EmptyBorder(5, 5, 5, 20));
        label.setText("any text makes it centered beyond 40 lines");
        //create panel
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.add(label, BorderLayout.NORTH);
        panel.add(Box.createVerticalGlue());
        panel.setPreferredSize(new Dimension((int)(screenSize.width*0.7 - 50), screenSize.height-150));
        panel.setBorder(new EmptyBorder(5, 5, 5, 10));
        
        JScrollPane jspanel = new JScrollPane(label, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        //jspanel.add(label, BorderLayout.CENTER);
        jspanel.setPreferredSize(new Dimension((int)(screenSize.width*0.7 - 70), screenSize.height-180));
        jspanel.getVerticalScrollBar().setUnitIncrement(20);
        jspanel.setBorder(BorderFactory.createEmptyBorder());
        jspanel.setAlignmentX(JScrollPane.LEFT_ALIGNMENT);
        jspanel.setAlignmentY(JScrollPane.TOP_ALIGNMENT);
        //panel.setPreferredSize(new Dimension(640, 480));
        //frame.add(panel);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(jspanel);
        frame.setSize((int)(screenSize.width*0.7), screenSize.height - 50);
        frame.revalidate();
        frame.pack();  
        frame.setVisible(true);
    }
}
    jspanel.setAlignmentX(JScrollPane.LEFT_ALIGNMENT);
    jspanel.setAlignmentY(JScrollPane.TOP_ALIGNMENT);

这将在其父容器中对齐滚动窗格,具体取决于所使用的布局管理器。它不会影响添加到滚动窗格的任何组件的对齐方式。不需要。

the label becomes centered

标签的大小可以填满整个 space 可用空间,因此您需要自定义标签文本的绘制方式。

如果您不希望它居中,那么您可以使用以下方法将它放在顶部:

label.setVerticalAlignment( SwingConstants.TOP );

修改您的代码后,我想出了以下 GUI。

  1. 我添加了对 SwingUtilities invokeLater 方法的调用。此方法确保所有 Swing 组件都在 Event Dispatch Thread.

    上创建和执行
  2. 我删除了所有静态引用,main 方法除外。

  3. 我将您的代码重新编写为方法,这样我就可以一次专注于 GUI 的一部分。

这是完整的可运行示例。这是一个最小的可重现示例。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

public class JScrollPaneTestGUI implements Runnable {
    
    public static void main(String[] args) { 
        SwingUtilities.invokeLater(new JScrollPaneTestGUI());
    }
    
    @Override
    public void run() {
        JFrame frame = new JFrame("JScrollPane Test"); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        JScrollPane jspanel = createJScrollPane();
        frame.add(jspanel, BorderLayout.CENTER);
        
        frame.pack();  
        frame.setVisible(true);
    }

    private JScrollPane createJScrollPane() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBackground(Color.YELLOW);
        panel.setPreferredSize(new Dimension(400, 300));
        
        JLabel label = new JLabel();
        label.setBorder(new EmptyBorder(5, 5, 5, 20));
        label.setText("any text makes it centered beyond 40 lines");
        //create panel
        panel.add(label, BorderLayout.NORTH);
        
        JScrollPane jspanel = new JScrollPane(panel);
       
        return jspanel;
    }
    
}