Прежде всего, перестаньте пытаться завинчивать с размерами компонентов.У Swing уже есть очень мощный API менеджера компоновки, который учитывает многие различные аспекты структур графического интерфейса, а также различия в платформе и оборудовании, позволяя ему выполнять свою работу.
A 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
, который уже почти все это делает?