Layout Variável no Swing

Como você poderia obter uma GUI decente gerada quando você não sabe quantos componentes você terá e quão grande eles serão?

Um usuário, por exemplo, digita quantos campos de texto eles querem e quais desses campos de texto estão agrupados em painéis com bordas e o programa gera isso.

Eu tenho usado o GridLayout, mas o problema é que ele cria todas as células da mesma largura e altura, o que é bom quando todos os componentes têm o mesmo tamanho, mas quando eu, por exemplo, tenho um campo de texto e um painel campos, o campo de texto é esticado ou o painel é espremido.

Eu gostaria que todos os componentes tivessem o tamanho mínimo, mas, ainda assim, utilizável.

Exemplo de como é agora, usando GridLayout , todos os campos são normais, JTextFields de uma linha, onde a data do título do painel é totalmente comprimida (tem três campos) e os campos do primeiro nível são muito grandes. Alguém tem alguma ponteira?

   

    O MiGLayout tem muito apelo, mas o BoxLayout é uma alternativa.

    imagem

     import java.awt.*; import java.util.List; import java.util.ArrayList; import javax.swing.*; public class BoxTest extends JPanel { private List fields = new ArrayList(); 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("Stackoverflow!", 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(); } }); } } 

    Eu olharia para miglayout. É muito mais útil do que qualquer um dos gerenciadores de layout embutidos.

    Seu objective geral – “tamanhos de componentes utilizáveis” se choca com “número desconhecido”. Torne o número grande o suficiente e eles não caberão em nenhuma canvas.

    Pense se não seria melhor usar JTables (as células podem se tornar editáveis) em conjunto com um JScrollPanel. Se você quiser / deve manter sua abordagem de geração de componentes, coloque o JPanel inteiro que contém seus componentes em um JScrollPane, assim os componentes não ficarão comprimidos demais.

    Sim, o MiGLayout é legal. Você pode fazer praticamente qualquer coisa com isso.

    O tamanho mínimo em AWT e Swing geralmente é inútil. Sugiro adicionar um painel para delegar tamanho mínimo ao tamanho preferido original e, possivelmente, adicionar um pouco ao novo tamanho preferido. Em GridBagLayout adicione pesos nos quais você deseja espaço adicional para o tamanho normal. Como Durandal menciona, aparecendo barras de rolagem ao redor da janela de nível superior bate apertando o layout ou saindo da canvas (estou escrevendo isso em um Netbook, então eu sei sobre janelas maiores que a canvas).