3

I have a form with 3045! components (1015 labels, 1015 textfields, 1015 comboboxes). All of them are in a JPanel and the JPanel in a JScrollPane. The problem is that the scrolling is 'laggy'. I have 4gb RAM in my PC so I don't think that this is the problem. What is wrong? In my task manager the application uses ~100mb.

My code:

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();
}

EDIT: I done a lot of tests and i realized that the lag exists only when i am using combo boxes, if i use eg textfields instead of comboboxes, the scrolling is normal...

user1005633
  • 625
  • 3
  • 9
  • 23

3 Answers3

5

When using a layout manager, your code doesn't seem all that laggy to me. Please test this:

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);
   }
}

Edit

How about with a JTable instead?

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);
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
2

A note for all naive Swing programmers: all creation and manipulation of Swing Objects must be done on the AWT Event Thread, in a Runnable added to the Event Thread, when called from a different Thread, otherwise bad things can happen!

e.g.

 public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        // Swing object creation and modification code!
      }
    });
 }     

Also learn how to use SwingWorker if you need to launch non-Swing code from Swing and run Swing code when it completes.

Aequitas
  • 2,205
  • 1
  • 25
  • 51
Infernoz
  • 131
  • 4
  • Once you get enough rep. to make comments, please make answers like this a comment rather than an answer to the question (which it is not). +1 to help with that 'rep' thing.. – Andrew Thompson Jun 17 '13 at 05:53
0

This is likely to be an issue with the JDK you are using. I have had similar problems when using JDK 1.8.0_45.

Downgrading your JDK to 1.8.0_31 should solve the issue that you are having with comboboxes lagging the scrolling.

Alternatively; add -Dsun.java2d.opengl=true to your VM arguments.

Aequitas
  • 2,205
  • 1
  • 25
  • 51