Trước hết, hãy xem lời khuyên khôn ngoan của @ AndrewThompson này:
Có một số chủ đề hữu ích để hiểu ý nghĩa của nó ở đây:
- Vị trí và đường viền cửa sổ không thể thay đổi kích thước
- Tôi có nên tránh sử dụng các phương thức kích thước set (Ưu tiên | Tối đa | Tối thiểu) trong Java Swing không?
- Ví dụ về bố cục lồng nhau
- Cung cấp khoảng trắng trong Swing GUI
Bạn sẽ thấy việc sử dụng các phương thức như setLocation()
, setBounds()
hoặc setSize()
rất không khuyến khích. Tuy nhiên, tôi đã thấy cách tiếp cận này trước khi áp dụng để cho phép các biểu mẫu tùy chỉnh. Nhưng thay vì tọa độ cụ thể (x, y) và cố định (chiều rộng, chiều cao), bạn có thể lưu trữ các ràng buộc cho GridBagLayout
. Giả sử bạn có một bảng như thế này:
Đầu tiên tôi sẽ bắt đầu với một lớp để bọc dữ liệu từ DB:
public class Data {
private String componentType, text;
private int column, row, width, height, weightX, weightY;
public Data(String componentType, int column, int row, int width, int height
,int weightX, int weightY, String text) {
this.componentType = componentType;
this.column = column;
this.row = row;
this.width = width;
this.height = height;
this.weightX = weightX;
this.weightY = weightY;
this.text = text;
}
// getters and setters here
}
Vì các cuộc gọi cơ sở dữ liệu là tác vụ tốn thời gian, bạn phải cân nhắc sử dụng SwingWorker để thực hiện lệnh gọi cơ sở dữ liệu (tác vụ tốn thời gian) trong một chuỗi nền và tạo / cập nhật GUI của bạn trong Chuỗi sự kiện của Công văn .
Sau khi nói điều này, bạn có thể có một cái gì đó như thế này:
public class Demo {
private JPanel content;
private JFrame frame;
private void createAndShowGUI() {
content = new JPanel(new GridBagLayout());
SwingWorker<Void, Data> worker = new SwingWorker<Void, Data>() {
@Override
protected Void doInBackground() {
try{
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db","root","password");
Statement stat = con.createStatement();
ResultSet rs = stat.executeQuery("select * from TableName");
while(rs.next()){
String componentType = rs.getString("component");
int column = rs.getInt("x");
int row = rs.getInt("y");
int width = rs.getInt("width");
int height = rs.getInt("height");
int weightx = rs.getInt("weightx");
int weighty = rs.getInt("weighty");
String text = rs.getString("text");
Data data = new Data(componentType, column, row, width, height
,weightx, weighty, text);
publish(data);
}
rs.close();
stat.close();
con.close();
} catch(Exception e) {
System.out.println(e);
}
return null;
}
@Override
protected void process(List<Data> chunks) {
for(Data data : chunks) {
JComponent component = null;
if(data.getComponentType().equalsIgnoreCase("JTextField")) {
component = new JTextField(data.getText());
}
if(data.getComponentType().equalsIgnoreCase("JComboBox")) {
component = new JComboBox();
}
if(data.getComponentType().equalsIgnoreCase("JLabel")) {
component = new JLabel(data.getText());
}
if(component != null) {
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = data.getColumn();
constraints.gridy = data.getRow();
constraints.gridwidth = data.getWidth();
constraints.gridheight = data.getHeight();
constraints.weightx = data.getWeightX();
constraints.weighty = data.getWeightY();
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.BOTH;
constraints.insets = new Insets(8,8,8,8);
content.add(component, constraints);
}
}
}
@Override
protected void done() {
frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(content);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
};
worker.execute();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Demo().createAndShowGUI();
}
});
}
}
Và bạn sẽ thấy một cái gì đó như thế này: