我想要实现的目标:我希望能够将组件添加到已添加组件之间的滚动 Pane 中。换句话说,我想以某种方式将索引向上移动,并在旧组件所在的位置放置一些新组件。我创建了一个简短的程序来说明我的问题,它替换了未添加的组件。有人可以帮忙吗?
为什么我想实现它(为了回答与此相关的不可避免的问题,只有感兴趣时才阅读这篇文章):我有一个滚动 Pane ,我需要在其中显示大量组件,大约150000 个 JTable。这需要太多的内存和处理时间。所以我所做的就是加载带有 150000 个文本字段的滚动 Pane ,并且一次只显示 100 个表格。如果滚动到文本字段 200,它将加载接下来的 100 个表格,并用表格替换之前创建的文本字段。如果您移动到文本字段 300,它将加载接下来的 100 个表格,并删除前 100 个表格,再次用文本字段替换它。我的想法是,文本字段比表格占用的资源要少得多,到目前为止,这种想法似乎是正确的。所以这一切似乎都工作得很好(在我较小的测试文件上 - 大约 5000 条记录)。问题是创建 150000 个文本字段也需要大量时间。我想到了一个解决方案。不为每个表创建一个文本字段,而是为每 100 个表创建 1 个文本字段。这个想法是,当您滚动到文本字段 2(而不是 200)时,它会加载接下来的 100 个表,将文本字段 nr 2 替换为表 nr 200 - 299。所以不知何故,我需要将文本字段 3 及其下面的所有内容按顺序向下移动插入所有表。唷,希望这是有道理的
因此,看看下面的示例,我实际上想要实现的是将文本字段 20 替换为 5 个新文本字段,但不替换文本字段 21 - 25。
import javax.swing.*;
import java.awt.*;
public class Example {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ExampleScreen ex = null;
ex = new ExampleScreen();
ex.setVisible(true);
}
});
}
private static class ExampleScreen extends JFrame{
GridBagConstraints gc = new GridBagConstraints();
JPanel panel = new JPanel(new GridBagLayout());
JScrollPane scrollPane = new JScrollPane(panel);
public ExampleScreen() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
this.add(scrollPane, BorderLayout.CENTER);
setupFields();
createExtraFieldsInbetween(20);
this.pack();
scrollPane.getVerticalScrollBar().setUnitIncrement(16);
scrollPane.getViewport().setScrollMode(JViewport.BLIT_SCROLL_MODE);
}
//after this happens i need to add components somewhere in the middle, like after textfield 20 for example
private void setupFields() {
gc.gridy = 0;
gc.gridx = 0;
for(int k = 0; k < 50; k++) {
JTextField textField = new JTextField();
textField.setPreferredSize(new Dimension(1500,36));
textField.setText(new Integer(k).toString());
panel.add(textField, gc, k);
gc.gridy++;
}
}
//this is to create extra fields inbetween those already created
//this does not work, it overwrites the existing components, doesnt move them up
private void createExtraFieldsInbetween(int i) {
gc.gridy = i;
//create 5 extra
for(int k = i; k < i + 5; k++) {
JTextField textField = new JTextField();
textField.setPreferredSize(new Dimension(1500,36));
textField.setText("Extra Field : " + new Integer(k).toString());
panel.add(textField, gc, k);
gc.gridy++;
}
}
}
}
最佳答案
每当我看到像 150,000 这样的数字时,我认为用户不会费心滚动所有这些组件,因此您需要更好的 UI。
无论如何,如果您对 GridBagLayout 有问题,请不要使用 GridBagLayout。
在我看来,您只是垂直显示组件,因此请尝试 BoxLayout
。然后,您可以使用 add(...)
方法来指定要删除/添加组件的索引。
关于Java Swing GridBagLayout 在其他组件之间添加组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21328297/