一些启发式方法:
当您真正想要覆盖 时,不要使用,就像在创建自己的组件时可能会做的那样,如下所示。set[Preferred|Maximum|Minimum]Size()
get[Preferred|Maximum|Minimum]Size()
不要在可以依赖组件的仔细覆盖时使用,如此处及下面所示。set[Preferred|Maximum|Minimum]Size()
getPreferred|Maximum|Minimum]Size
使用来派生后几何图形,如下图和此处所示。set[Preferred|Maximum|Minimum]Size()
validate()
如果组件没有首选大小,例如,您可能必须调整容器的大小,但任何此类选择都是任意的。注释可能有助于澄清意图。JDesktopPane
当您发现必须遍历许多组件才能获得派生大小时,请考虑备用布局或自定义布局,如这些注释中所述。
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/**
* @see https://stackoverflow.com/questions/7229226
* @see https://stackoverflow.com/questions/7228843
*/
public class DesignTest {
private List<JTextField> list = new ArrayList<JTextField>();
private JPanel panel = new JPanel();
private JScrollPane sp = new JScrollPane(panel);
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
DesignTest id = new DesignTest();
id.create("My Project");
}
});
}
private void addField(String name) {
JTextField jtf = new JTextField(16);
panel.add(new JLabel(name, JLabel.LEFT));
panel.add(jtf);
list.add(jtf);
}
private void create(String strProjectName) {
panel.setLayout(new GridLayout(0, 1));
addField("First Name:");
addField("Last Name:");
addField("Address:");
addField("City:");
addField("Zip Code:");
addField("Phone:");
addField("Email Id:");
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addPropertyChangeListener("permanentFocusOwner",
new FocusDrivenScroller(panel));
// Show half the fields
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sp.validate();
Dimension d = sp.getPreferredSize();
d.setSize(d.width, d.height / 2);
sp.setPreferredSize(d);
JInternalFrame internaFrame = new JInternalFrame();
internaFrame.add(sp);
internaFrame.pack();
internaFrame.setVisible(true);
JDesktopPane desktopPane = new JDesktopPane();
desktopPane.add(internaFrame);
JFrame frmtest = new JFrame();
frmtest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmtest.add(desktopPane);
frmtest.pack();
// User's preference should be read from java.util.prefs.Preferences
frmtest.setSize(400, 300);
frmtest.setLocationRelativeTo(null);
frmtest.setVisible(true);
list.get(0).requestFocusInWindow();
}
private static class FocusDrivenScroller implements PropertyChangeListener {
private JComponent parent;
public FocusDrivenScroller(JComponent parent) {
this.parent = parent;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
Component focused = (Component) evt.getNewValue();
if (focused != null
&& SwingUtilities.isDescendingFrom(focused, parent)) {
parent.scrollRectToVisible(focused.getBounds());
}
}
}
}