Я столкнулся с проблемой. Есть JTabbedPane, с панелями, сформированными на стадии инициации и неизменными. Рядом лежит JPanel. Если JPanel пустая, то переключение между закладками в JTabbedPane происходит почти мгновенно (по засечкам 2-3 миллисекунды, что совершенно не существенно и незаметно для глаза). Если же в JPanel добавить некоторое количество компонентов, то переключение между закладками в JTabbedPanel, начинает замедляться.
Я сначала грешил на разные свойства панелей, связанных логически в моей программе. Для чистоты эксперимента создал новый апплет:
| Код |
package tpt;
import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.JTextArea;
public class Applet1 extends JApplet { @SuppressWarnings("compatibility:-7644383762981381622") private static final long serialVersionUID = 1L; private JTabbedPane jTabbedPane1 = new JTabbedPane(); private JPanel jPanel1 = new JPanel(); private JPanel jPanel2 = new JPanel(); private JPanel jPanel3 = new JPanel(); private JButton jButton1 = new JButton(); private JPanel jPanel4 = new JPanel(); private JTextArea jTextArea1 = new JTextArea(); private JButton jButton2 = new JButton(); private JButton jButton3 = new JButton(); private JButton jButton4 = new JButton();
public Applet1() { }
private void jbInit() throws Exception { this.getContentPane().setLayout( null ); this.setBounds(new Rectangle(10, 10, 500, 500)); jTabbedPane1.setBounds(new Rectangle(0, 5, 400, 100)); jButton1.setText("JLabels"); jButton1.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { jButton1_mouseClicked(e); } }); jPanel4.setBounds(new Rectangle(0, 105, 365, 395)); jTextArea1.setBounds(new Rectangle(370, 110, 130, 390)); jButton2.setText("Next"); jButton2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { jButton2_actionPerformed(e); } }); jButton3.setText("Next"); jButton3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { jButton3_actionPerformed(e); } }); jButton4.setText("Next"); jButton4.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { jButton4_actionPerformed(e); } }); jPanel1.add(jButton1, null); jPanel1.add(jButton2, null); jTabbedPane1.addTab("jPanel1", jPanel1); jPanel2.add(jButton3, null); jTabbedPane1.addTab("jPanel2", jPanel2); jPanel3.add(jButton4, null); jTabbedPane1.addTab("jPanel3", jPanel3); this.getContentPane().add(jTextArea1, null); this.getContentPane().add(jPanel4, null); this.getContentPane().add(jTabbedPane1, null); jPanel4.setLayout(null); }
public void init() { try { jbInit(); } catch (Exception e) { e.printStackTrace(); } }
public static void main(String[] args) { Applet1 applet = new Applet1(); JFrame frame = new JFrame(); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); frame.getContentPane().add(applet, BorderLayout.CENTER); frame.setTitle( "Applet Frame" ); applet.init(); applet.start(); frame.setSize(500, 500); Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = frame.getSize(); frame.setLocation((d.width-frameSize.width)/2, (d.height-frameSize.height)/2); frame.setVisible(true); }
public void start() { }
public void stop() { }
public void destroy() { }
private void jButton1_mouseClicked(MouseEvent e) { Random rnd = new Random(); for (int i=0;i<2000;i++){ JLabel l=new JLabel("L-"+i); l.setLocation(rnd.nextInt(350), rnd.nextInt(380)); l.setSize(20,20); jPanel4.add(l); l.repaint(); } jPanel4.repaint(); }
private void jButton2_actionPerformed(ActionEvent e) { long t1,t2; t1=System.nanoTime(); jTabbedPane1.setSelectedIndex(1); t2=System.nanoTime(); jTextArea1.append(""+(t2-t1)+"\n"); }
private void jButton3_actionPerformed(ActionEvent e) { long t1,t2; t1=System.nanoTime(); jTabbedPane1.setSelectedIndex(2); t2=System.nanoTime(); jTextArea1.append(""+(t2-t1)+"\n"); }
private void jButton4_actionPerformed(ActionEvent e) { long t1,t2; t1=System.nanoTime(); jTabbedPane1.setSelectedIndex(0); t2=System.nanoTime(); jTextArea1.append(""+(t2-t1)+"\n"); } }
|
В принципе это творение запускается и как desktop приложение, поскольку есть метод main.
Теперь о результатах (см. рис)

В апплет вложено три компонента: JTabbedPane, JPanel, JTextArea.
В JTabbedPane вложено три панели. На первой две кнопки JLabels и Next, на остальных двух панелях только кнопки Next.
При нажатии на кнопку Next происходит активация следующей закладки и засекается время на эту операцию. ВРемя выводится в JTextArea.
На рисунке приведены результаты следующей работы. Сначала были трижды нажаты кнопки Next (по разу на каждой панели). Им соответсвуют три верхних числа в JTextArea. Потом по нажатию кнопки JLabels в JPanel было добавлено 2000 JLabel. После чего еще трижды были нажаты кнопки Next. Им соответсвуют три нижних числа в JTextArea. Различие в 600 раз видно невооруженным глазом.
В чем причина? В моем реальном приложении
(например это) число точек может достигать 5-10 тысяч. При этом перерисовка и обработка происходят мгновенно (не всегда, конечно), а вот обычное техническое переключение между панелями томозит невероятно.
Подскажите, пожалуйста, в чем причина.