我有一個具有一些子元素(包括JTextField)的自定義swing組件。我想爲容器提供與JTextField相同的基線,所以我重寫了容器中的getBaseline方法。但是,當爲容器調用getBaseline時,並不總是設置JTextField的位置。我試圖在容器的getBaseline方法中添加對doLayout的調用,但這沒有幫助。我想是這樣的:在父容器中使用子組件的getBaseline(int w,int h)
public int getBaseline(int w, int h) {
Dimension size = textField.getPreferredSize();
int textBaseline = textField.getBaseline(size.width, size.height);
int textY = textField.getY();
return textY + textBaseline;
}
在上面的代碼textY處等於0
我已經寫了一些代碼來說明問題。點擊第一次「添加」,基準線是錯誤的。第二次是正確的。
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
class CustomComponent extends JPanel {
public CustomComponent() {
setLayout(new GridBagLayout());
textField.setColumns(8);
layoutElements();
}
public void addComponent() {
JPanel comp = new JPanel();
comp.setPreferredSize(new Dimension(50, 200));
comp.setBackground(Color.red);
otherComponents.add(comp);
layoutElements();
}
public int getBaseline(int w, int h) {
Dimension size = textField.getPreferredSize();
return textField.getY() + textField.getBaseline(size.width, size.height);
}
public Component.BaselineResizeBehavior getBaselineResizeBehavior() {
return Component.BaselineResizeBehavior.CONSTANT_DESCENT;
}
private void layoutElements() {
removeAll();
GridBagConstraints constraints = new GridBagConstraints();
constraints.anchor = GridBagConstraints.SOUTH;
add(textField, constraints);
for (JPanel comp : otherComponents)
add(comp, new GridBagConstraints());
if (getParent() != null)
getParent().validate();
}
private JTextField textField = new JTextField();
private ArrayList<JPanel> otherComponents = new ArrayList<JPanel>();
}
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
frame.getContentPane().add(panel);
JButton addComponent = new JButton("Add");
GridBagConstraints constraints = new GridBagConstraints();
constraints.anchor = GridBagConstraints.BASELINE;
panel.add(addComponent, constraints);
final CustomComponent customComp = new CustomComponent();
panel.add(customComp, constraints);
addComponent.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
customComp.addComponent();
}
});
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
也許我還應該提到組件在運行時被添加到容器。我也嘗試添加validate()到getBaseline方法和添加新組件後的容器容器。 – gerrit 2012-07-30 19:37:00
嗯...不能在快速測試中複製(簡單的JPanel返回其第一個孩子的基線) - 最好顯示證明問題的SSCCE – kleopatra 2012-07-31 08:08:21