Я создал JPanel, который содержит произвольное количество JLabels, выложенное с помощью менеджера макета потока с выравниванием по левому краю. Давайте назовем это FlowPanel.Работа с менеджерами компоновки Java
Каждый FlowPanel имеет глубину, и я хотел бы складывать произвольное количество этих FlowPanels друг над другом, каждый из которых имеет отступы с фиксированной глубиной *. В конечном счете, цель состоит в том, чтобы отображать эти панели в панели JScrollPane с вертикальной полосой прокрутки (если необходимо), но не с горизонтальной полосой прокрутки.
Я попытался уложить FlowPanels с GridBagLayout, и хотя было достаточно легко заставить их стекать вертикально и отступать так, как я хочу, я не могу понять, как правильно получить ширину. То есть FlowPanels просто запустили правую часть моей основной панели, не обращая внимания на отображаемую ширину.
Я пробовал использовать setPreferredSize, setSize, возиться с GridBagConstraints ... не повезло.
Пожалуйста, помогите! :)
несколько примеров кода, чтобы продемонстрировать проблему. Этот код имеет 2 проблемы: 1. Строки должны быть постоянной высоты, даже если всего несколько строк. 2. Строки прокручиваются с правой стороны экрана, когда FlowPanels содержат слишком много элементов.
public class FlowExample {
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame();
StackPanel stackPanel = new StackPanel();
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(
new JScrollPane(stackPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER),
BorderLayout.CENTER);
frame.setLocation(200, 200);
frame.setSize(300, 300);
frame.setVisible(true);
List<FlowPanel> content = new ArrayList<FlowPanel>();
for (int i = 0; i < 20; i++) {
FlowPanel flowPanel = new FlowPanel((int) (4 * Math.random()));
for (int j = 0; j < (int) (20 * Math.random()); j++) {
flowPanel.add(new JLabel("label " + j));
}
content.add(flowPanel);
stackPanel.layoutGUI(content);
Thread.sleep(1000);
}
System.in.read();
System.exit(0);
}
}
class StackPanel extends JPanel {
public StackPanel() {
setLayout(new BorderLayout());
}
public void layoutGUI(final List<FlowPanel> content) {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
layoutGUI(content);
}
});
return;
}
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout(content.size(), 1));
for (FlowPanel flowPanel : content) {
flowPanel.setBorder(BorderFactory.createEmptyBorder(0, flowPanel.getDepth() * 10, 0, 0));
mainPanel.add(flowPanel);
}
removeAll();
add(mainPanel, BorderLayout.CENTER);
revalidate();
}
}
class FlowPanel extends JPanel {
private int depth;
public FlowPanel(int depth) {
setLayout(new FlowLayout(FlowLayout.LEFT));
this.depth = depth;
}
public int getDepth() {
return depth;
}
}
Вот пример кода с использованием GridBagLayout для прокладки основной панели. Это лучший результат я получил, но, как вы можете видеть, FlowPanels до сих пор не завернуть ...
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.weightx = 1;
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.anchor = GridBagConstraints.LINE_START;
for (FlowPanel flowPanel : content) {
System.out.println("setting border to " + flowPanel.getDepth());
flowPanel.setBorder(BorderFactory.createEmptyBorder(0, flowPanel.getDepth() * 10, 0, 0));
mainPanel.add(flowPanel, constraints);
}
constraints.weighty = 1;
mainPanel.add(new JPanel(), constraints);
removeAll();
add(mainPanel, BorderLayout.CENTER);
revalidate();
вы пробовали просто складывая их (с помощью GridLayout было бы достаточно), но назначая левую единственную пустую границу для каждой панели? –
Кажется, что не работает ... написание образца кода для демонстрации. –
Какое поведение вы хотите, если FlowPanel шире, чем StackPanel? Должна ли она обернуться и увеличить ее глубину? Или вы хотите проверить, как вы добавляете JLabels, что вы не достигли максимума. ширина пока? –