我有3045的表格!组件(1015个标签,1015个文本字段,1015个组合框)。所有这些都在JPanel和JScrollPane中的JPanel中。问题是滚动是“滞后”。我的PC上有4GB RAM,所以我不认为这是问题所在。怎么了? 在我的任务管理器中,应用程序使用~100mb。
我的代码:
final JScrollPane scrollPane_1 = new JScrollPane();
final JPanel panel = new JPanel();
panel.setLayout(null);
scrollPane_1.setViewportView(panel);
int y =0;
for(int i=0; i<1015;i++)
{
JLabel length = new JLabel();
length.setBounds(10, y, 350, 20);
length.setFont(new Font("Tahoma", Font.BOLD, 11));
length.setEnabled(false);
panel.add(length);
panel.revalidate();
JComboBox combo = new JComboBox();
combo.setModel(new DefaultComboBoxModel(new String[] {"=", "!="}));
combo.setBounds(10, y + 20, 70, 20);
panel.add(combo);
panel.revalidate();
JTextField text = new JTextField();
text.setBounds(10 + 80, y + 20, 200, 20);
panel.add(text);
panel.revalidate();
}
编辑:我做了很多测试,我意识到只有当我使用组合框时才存在延迟,如果我使用例如文本字段而不是组合框,滚动是正常的... < / p>
答案 0 :(得分:5)
使用布局管理器时,您的代码对我来说似乎并不那么迟钝。请测试一下:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.*;
public class Foo2 {
protected static final int PREF_W = 400;
protected static final int PREF_H = 400;
public static void main(String[] args) {
final JScrollPane scrollPane_1 = new JScrollPane() {
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
};
final JPanel panel = new JPanel();
panel.setLayout(new GridLayout(0, 1));
scrollPane_1.setViewportView(panel);
for (int i = 0; i < 1015; i++) {
JPanel innerPanel = new JPanel();
innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.LINE_AXIS));
JLabel length = new JLabel("foo");
length.setFont(new Font("Tahoma", Font.BOLD, 11));
length.setEnabled(false);
innerPanel.add(length);
innerPanel.add(Box.createHorizontalGlue());
JComboBox<String> combo = new JComboBox<String>();
combo.setPrototypeDisplayValue(" ");
combo.setModel(new DefaultComboBoxModel<String>(new String[] { "=", "!=" }));
combo.setMaximumSize(combo.getPreferredSize());
innerPanel.add(combo);
JTextField text = new JTextField(10);
JPanel textWrapper = new JPanel();
textWrapper.add(text);
innerPanel.add(textWrapper);
panel.add(innerPanel);
}
JFrame frame = new JFrame();
frame.add(scrollPane_1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
修改强>
改为使用JTable呢?
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class Foo3 {
protected static final int PREF_W = 400;
protected static final int PREF_H = 400;
public static void main(String[] args) {
final JScrollPane scrollPane_1 = new JScrollPane() {
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
};
String[] columnNames = {"Foo", "Bar", "Baz"};
String[][] data = new String[1015][3];
for (int i = 0; i < data.length; i++) {
data[i] = new String[]{"foo", "==", ""};
}
DefaultTableModel model = new DefaultTableModel(data, columnNames){
@Override
public boolean isCellEditable(int row, int column) {
return (column != 0);
}
};
JTable table = new JTable(model);
table.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(
new JComboBox<String>(new String[]{"==", "!="})));
final JPanel panel = new JPanel();
panel.setLayout(new GridLayout(0, 1));
scrollPane_1.setViewportView(table);
JFrame frame = new JFrame();
frame.add(scrollPane_1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
答案 1 :(得分:2)
所有天真Swing程序员的注释:所有创建和操作Swing对象必须在AWT事件线程上,在添加到事件线程的Runnable中完成,当从不同的线程调用时,否则会发生不好的事情!
e.g。
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Swing object creation and modification code!
}
});
}
如果需要从Swing启动非Swing代码并在完成时运行Swing代码,还要学习如何使用SwingWorker。
答案 2 :(得分:0)
这可能是您正在使用的JDK的问题。使用JDK 1.8.0_45时遇到了类似的问题。
将JDK降级为1.8.0_31应该可以解决使用组合框落后滚动的问题。
可替换地;将-Dsun.java2d.opengl=true
添加到您的VM参数中。