我有一个JLabels
的列表,它们的大小为280 x 50,并包含文本。我想创建280 x 300 JPanel
,将所有标签添加到其中并使其可滚动(因为我们可以有6个以上的标签)。
我不确定如何在此特定大小的面板上添加6个以上的标签,也不知道如何使其滚动(我尝试将面板添加到相同大小的JScrollPane
上,但实际上没有任何反应)。有办法吗?
答案 0 :(得分:3)
首先,停止尝试拧紧组件尺寸的螺钉。 Swing已经拥有一个非常强大的布局管理器API,该API考虑了GUI框架的许多不同方面以及平台和硬件的差异,让它发挥作用。
JScrollPane
的依赖在于它的内容能够独立于JScrollPane
的大小来计算其大小,然后才可以决定何时显示滚动条。 JPanel
也是如此。它的大小应根据其内容的总需求来计算。奇怪的是,如果您使用布局管理器API,那么所有这些操作都是免费的。
所以,一个令人讨厌的例子可能看起来像...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(new TestPane()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int index = 0; index < 600; index++) {
JLabel label = new JLabel("This is test " + index);
// This is for demonstration purposes only
// you should let the lable calculate its size based on its text
// and image properties
label.setPreferredSize(new Dimension(280, 50));
add(label, gbc);
}
}
}
}
但是窗口很长!
因此,这变得稍微复杂一些。您需要向JScrollPane
提供有关如何调整组件尺寸的其他提示。为此,有Scrollable
...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(new TestPane()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel implements Scrollable {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int index = 0; index < 600; index++) {
JLabel label = new JLabel("This is test " + index);
// This is for demonstration purposes only
// you should let the lable calculate its size based on its text
// and image properties
label.setPreferredSize(new Dimension(280, 50));
add(label, gbc);
}
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(290, 300);
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return true;
}
}
}
所有这些提出了一个问题,为什么?为什么不只使用JList
或JTable
来完成所有这些工作呢?