3

3045 のフォームがあります。コンポーネント (1015 個のラベル、1015 個のテキストフィールド、1015 個のコンボボックス)。それらはすべて JPanel にあり、JPanel は JScrollPane にあります。問題は、スクロールが「遅い」ことです。私のPCには4GBのRAMがあるので、これは問題ではないと思います. なにが問題ですか?私のタスク マネージャーでは、アプリケーションは ~100 MB を使用します。

私のコード:

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

編集:私は多くのテストを行い、コンボボックスを使用している場合にのみラグが存在することに気付きました。たとえば、コンボボックスの代わりにテキストフィールドを使用すると、スクロールは正常です...

4

3 に答える 3

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);
   }
}
于 2013-06-16T22:22:00.327 に答える
2

すべての素朴な Swing プログラマーへの注意: Swing オブジェクトのすべての作成と操作は、別のスレッドから呼び出されたときに、イベント スレッドに追加された Runnable で、AWT イベント スレッドで行う必要があります。そうしないと、悪いことが起こる可能性があります。

例えば

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

また、Swing から Swing 以外のコードを起動し、完了時に Swing コードを実行する必要がある場合は、SwingWorker の使用方法も学びます。

于 2013-06-17T01:27:01.970 に答える
0

これは、使用している JDK に問題がある可能性があります。JDK 1.8.0_45 を使用しているときに、同様の問題が発生しました。

JDK を 1.8.0_31 にダウングレードすると、コンボボックスでスクロールが遅れるという問題が解決するはずです。

あるいは; -Dsun.java2d.opengl=trueVM 引数に追加します。

于 2015-08-16T22:16:12.203 に答える