问题描述
这个问题与此非常相似:JScrollPane doesn't top align when there is more than enough space to show the content 我试过这个解决方案,但它不起作用。
当我向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,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,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);
这将在其父容器中对齐滚动窗格,具体取决于所使用的布局管理器。它不会影响添加到滚动窗格的任何组件的对齐方式。不需要。
标签居中
标签的大小可以填充整个可用空间,因此您需要自定义标签文本的绘制方式。
如果你不希望它居中,那么你可以使用:
label.setVerticalAlignment( SwingConstants.TOP );
,
重新编写代码后,我想出了以下 GUI。
-
我添加了对
SwingUtilities
invokeLater
方法的调用。此方法可确保在 Event Dispatch Thread 上创建和执行所有 Swing 组件。 -
我删除了所有静态引用,
main
方法除外。 -
我将您的代码重新编写为方法,这样我就可以一次专注于 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,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;
}
}