Java - 使用运行时更改约束 JScrollPanes 下面的组件
Java - Constraining Components below JScrollPanes with runtime change
我有一个 JFrame 和一个包含 JTable 的 JScrollPane。在 JTable 下面我放置了一个带有 SpringLayout 的 JButton:
l.putConstraint(SpringLayout.NORTH, but, 50, SpringLayout.SOUTH, sP);
JButton 向 JTable 添加一行并更新 JScrollPane 的大小。由于它们相互约束,我希望按钮更新他的位置并向下移动。但是,它不会发生。
因为我只用一个普通的 JTable 尝试了同样的方法,它工作得很好,但我需要这个 JScrollPane 来避免 JTable 将自身扩展到框架之外。
这是我的完整测试代码:
package tests;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SpringLayout;
import javax.swing.table.DefaultTableModel;
public class WhosebugQRuntimeAlignment extends JFrame{
private JScrollPane sP;
private JTable tab;
private JButton but;
private DefaultTableModel dtm;
public static void main(String[] args){
WhosebugQRuntimeAlignment frame = new WhosebugQRuntimeAlignment("Test");
frame.setSize(new Dimension(1280, 720));
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
}
WhosebugQRuntimeAlignment(String title){
super(title);
//DefaultTabelModel to create the Table
dtm = new DefaultTableModel(new String[][]{{"data1", "data2"}}, new String[]{"Column1", "Column2"});
tab = new JTable(dtm);
//set TableHeaderHeight to RowHeight
tab.getTableHeader().setPreferredSize(new Dimension(tab.getWidth(), tab.getRowHeight()));
//create ScrollPane containing the Table
sP = new JScrollPane(tab);
//set the size of the ScrollPane
sP.setPreferredSize(new Dimension(500, (dtm.getRowCount()+1)*16+3));//+1 for the Header, +3 to hide ScrollBars if they are not neccesary
sP.setMaximumSize(new Dimension(tab.getWidth(), 360));
//create the button to add an row to the table
but = new JButton("Hit me");
but.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dtm.addRow(new String[]{"Banana", "Apple"});
//updating the size of the ScrollPane
sP.setPreferredSize(new Dimension(500, (dtm.getRowCount()+1)*16+3));
sP.setSize(sP.getPreferredSize());
}
});
//constraining the Components on the GUI
SpringLayout l = new SpringLayout();
this.setLayout(l);
l.putConstraint(SpringLayout.HORIZONTAL_CENTER, sP, 0, SpringLayout.HORIZONTAL_CENTER, this.getContentPane());
l.putConstraint(SpringLayout.NORTH, sP, 50, SpringLayout.NORTH, this.getContentPane());
l.putConstraint(SpringLayout.HORIZONTAL_CENTER, but, 0, SpringLayout.HORIZONTAL_CENTER, sP);
l.putConstraint(SpringLayout.NORTH, but, 50, SpringLayout.SOUTH, sP);
//adding the Components to the GUI
this.add(sP);
this.add(but);
}
}
使用 JScrollPane 的要点是您不需要不断调整它的大小。随着添加到滚动窗格的组件的首选大小增加,滚动条将出现在滚动窗格上。因此,使用滚动窗格的默认首选大小创建 GUI,并让 Swing 布局管理器工作。
通常,滚动窗格将添加到框架上 BorderLayout 的中心,以便在用户调整框架大小时,space 被分配给滚动窗格。
然而,从可见 GUI 添加(或删除)组件的一般规则是使用:
panel.add(...);
panel.revalidate(); // to invoke the layout manager
panel.repaint(); // to paint the components
我有一个 JFrame 和一个包含 JTable 的 JScrollPane。在 JTable 下面我放置了一个带有 SpringLayout 的 JButton:
l.putConstraint(SpringLayout.NORTH, but, 50, SpringLayout.SOUTH, sP);
JButton 向 JTable 添加一行并更新 JScrollPane 的大小。由于它们相互约束,我希望按钮更新他的位置并向下移动。但是,它不会发生。
因为我只用一个普通的 JTable 尝试了同样的方法,它工作得很好,但我需要这个 JScrollPane 来避免 JTable 将自身扩展到框架之外。
这是我的完整测试代码:
package tests;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SpringLayout;
import javax.swing.table.DefaultTableModel;
public class WhosebugQRuntimeAlignment extends JFrame{
private JScrollPane sP;
private JTable tab;
private JButton but;
private DefaultTableModel dtm;
public static void main(String[] args){
WhosebugQRuntimeAlignment frame = new WhosebugQRuntimeAlignment("Test");
frame.setSize(new Dimension(1280, 720));
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
}
WhosebugQRuntimeAlignment(String title){
super(title);
//DefaultTabelModel to create the Table
dtm = new DefaultTableModel(new String[][]{{"data1", "data2"}}, new String[]{"Column1", "Column2"});
tab = new JTable(dtm);
//set TableHeaderHeight to RowHeight
tab.getTableHeader().setPreferredSize(new Dimension(tab.getWidth(), tab.getRowHeight()));
//create ScrollPane containing the Table
sP = new JScrollPane(tab);
//set the size of the ScrollPane
sP.setPreferredSize(new Dimension(500, (dtm.getRowCount()+1)*16+3));//+1 for the Header, +3 to hide ScrollBars if they are not neccesary
sP.setMaximumSize(new Dimension(tab.getWidth(), 360));
//create the button to add an row to the table
but = new JButton("Hit me");
but.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dtm.addRow(new String[]{"Banana", "Apple"});
//updating the size of the ScrollPane
sP.setPreferredSize(new Dimension(500, (dtm.getRowCount()+1)*16+3));
sP.setSize(sP.getPreferredSize());
}
});
//constraining the Components on the GUI
SpringLayout l = new SpringLayout();
this.setLayout(l);
l.putConstraint(SpringLayout.HORIZONTAL_CENTER, sP, 0, SpringLayout.HORIZONTAL_CENTER, this.getContentPane());
l.putConstraint(SpringLayout.NORTH, sP, 50, SpringLayout.NORTH, this.getContentPane());
l.putConstraint(SpringLayout.HORIZONTAL_CENTER, but, 0, SpringLayout.HORIZONTAL_CENTER, sP);
l.putConstraint(SpringLayout.NORTH, but, 50, SpringLayout.SOUTH, sP);
//adding the Components to the GUI
this.add(sP);
this.add(but);
}
}
使用 JScrollPane 的要点是您不需要不断调整它的大小。随着添加到滚动窗格的组件的首选大小增加,滚动条将出现在滚动窗格上。因此,使用滚动窗格的默认首选大小创建 GUI,并让 Swing 布局管理器工作。
通常,滚动窗格将添加到框架上 BorderLayout 的中心,以便在用户调整框架大小时,space 被分配给滚动窗格。
然而,从可见 GUI 添加(或删除)组件的一般规则是使用:
panel.add(...);
panel.revalidate(); // to invoke the layout manager
panel.repaint(); // to paint the components