Расположение переменных в Swing
Как бы вы получили генерацию достойно выглядящего графического интерфейса, если вы не знаете, сколько у вас будет компонентов и насколько они будут большими?
Пользователь, например, вводит, сколько текстовых полей они хотят и какие из этих текстовых полей сгруппированы в ограниченных панелях, и программа генерирует это.
Я использовал GridLayout, но проблема в том, что он делает все ячейки одинаковыми по ширине и высоте, что хорошо, когда все компоненты имеют одинаковый размер, но когда у меня, например, есть текстовое поле и ограниченная панель с несколькими поля, либо текстовое поле растягивается, либо панель сжимается.
Я хотел бы, чтобы все компоненты имели минимальный размер, но все же, вы знаете, их можно использовать.
Пример того, как сейчас, используя GridLayout, все поля нормальные, однострочные JTextFields, где панель с заголовком date полностью сжата (в ней три поля), а поля первого уровня - большие. У кого-нибудь есть указатели?
5 ответов
MiGLayout очень привлекательна, но BoxLayout
это альтернатива.
import java.awt.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.*;
public class BoxTest extends JPanel {
private List<JTextField> fields = new ArrayList<JTextField>();
public BoxTest() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.add(createPane(3, "One ", Color.red));
this.add(createPane(3, "Two ", Color.green));
this.add(createPane(10, "Three ", Color.blue));
}
private JPanel createPane(int n, String s, Color c) {
JPanel outer = new JPanel();
outer.setLayout(new BoxLayout(outer, BoxLayout.Y_AXIS));
outer.setBorder(BorderFactory.createLineBorder(c, 2));
for (int i = 0; i < n; i++) {
JPanel inner = new JPanel();
inner.setLayout(new BoxLayout(inner, BoxLayout.X_AXIS));
JLabel label = new JLabel(s + i + ":", JLabel.RIGHT);
label.setPreferredSize(new Dimension(80, 32));
inner.add(label);
JTextField tf = new JTextField("Stackru!", 32);
inner.add(tf);
fields.add(tf);
outer.add(inner);
}
return outer;
}
private void display() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane jsp = new JScrollPane(this,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
this.validate();
Dimension d = this.getPreferredSize();
d.height /= 2;
jsp.getViewport().setPreferredSize(d);
jsp.getVerticalScrollBar().setUnitIncrement(
this.getPreferredSize().height / fields.size());
f.add(jsp);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new BoxTest().display();
}
});
}
}
Ваша общая цель - "используемые размеры компонентов" конфликтуют с "неизвестным числом". Сделайте число достаточно большим, чтобы они не помещались на экране.
Подумайте, не будет ли вам лучше использовать JTables (ячейки можно сделать редактируемыми) в сочетании с JScrollPanel. Если вы хотите / должны придерживаться вашего подхода к генерации компонентов, поместите весь JPanel, содержащий ваши компоненты, в JScrollPane, таким образом, компоненты не будут сильно сжиматься.
Я бы посмотрел на miglayout. Это намного полезнее, чем любой из встроенных менеджеров компоновки.
Да, MiGLayout это хорошо. Вы можете сделать с ней что угодно.
Минимальный размер в AWT и Swing обычно не имеет смысла. Я предлагаю добавить панель для делегирования минимального размера первоначальному предпочтительному размеру и, возможно, добавить немного нового предпочтительного размера. В GridBagLayout
добавить веса, где вы хотите, чтобы дополнительное пространство, чтобы пойти в нормальном размере. Как упоминает Дюрандаль, всплывающие полосы прокрутки вокруг окна верхнего уровня бьют по сжатию макета или покиданию экрана (я пишу это на нетбуке, так что я знаю об окнах, больших, чем экран).