scusa la risposta in ritardo:
l'apparente vantaggio di setLayout(null) è vanificato, nella maggior parte dei casi, dal numero di situazioni che si devono poi gestire a mano, che invece con un LayoutManager verrebbero gestite in modo trasparente. Una di queste è proprio quel che ritorna getPreferredSize sul JPanel, che per un contenitore senza LayoutManager (o meglio, posto a null) ritorna di default un ricco 0,0 - da cui lo scrollpane senza barre di scorrimento.
Adesso, se proprio devi, continua ad utilizzare il layout a null, ma bisogna inventarsi un work-around del genere:
codice:
import javax.swing.*;
import java.awt.*;
/**
*
* @author Andrea
*/
public class NullLayoutWithJScrollPane extends JFrame {
private class MyNullLayoutJPanel extends JPanel {
public Dimension getPreferredSize() {
int maxX = 0;
int maxY = 0;
Component[] components = this.getComponents();
for(int i = 0; i < components.length; i++){
Rectangle bounds = components[i].getBounds();
maxX = Math.max(maxX, (int)bounds.getMaxX());
maxY = Math.max(maxY, (int)bounds.getMaxY());
}
return new Dimension(maxX,maxY);
}
}
private JScrollPane scrollPane;
private MyNullLayoutJPanel nullPanel;
private JButton[] buttons;
public NullLayoutWithJScrollPane() {
super("test app");
nullPanel = new MyNullLayoutJPanel();
nullPanel.setLayout(null);
buttons = new JButton[20];
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton("Button "+i);
buttons[i].setBounds(10+i*30, 10+i*30, 100, 20);
nullPanel.add(buttons[i]);
}
scrollPane = new JScrollPane(nullPanel);
this.setSize(400,400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.getContentPane().add(scrollPane);
}
public static void main (String[] args) {
new NullLayoutWithJScrollPane();
}
}
oppure, meglio, sforzati di utilizzare un LayoutManager appropriato e lascia che sia questo a determinare lo spazio effettivo occupato dai vari componenti. I vantaggi sono molteplici, anche al costo di dover trimmare e fare del fine-tuning su layout manager "ostici" come GridBagLayout