dlaczego to zamula tylko w ten sposób?

0

Opowiem w skrócie i wkleje trochę kodu:
Aplikacja składa się z paska menu, paska narzędzi i 'obszaru roboczego'. Obszar roboczy jest zbudowany z JTabbedPane zawierającego w każdej zakładce JScrollPane, a w każdym z nich są jakieś tam panele, po których można rysować (w sumie to zmieniać ich tło).

Wszystko działa ładnie pięknie poza JButtonami, które umieszczam w lewym górnym rogu każdego z JScrollPane'ów. A jest z nimi taki problem:
Przycisk ten jest odpowiedzialny za zmniejszanie do rozmiarów minimalnych paneli we wszystkich zakładkach (jeśli te rozmiary są większe). Kliknięcie go powoduje właściwy skutek w aktualnie otwartej zakładce. Jednak bezpośrednie przełączenie po tym kliknięciu na inną zakładkę powoduje ok.6sekundowe zawieszenie aplikacji (procek pracuje na maxa), po czym odzyskujemy władzę i przechodzimy do tej zakładki co ją wybraliśmy i jest tam wszystko tak jak powinno być.

Z prób zdiagnozowania kiedy takie zawieszenia występują, a kiedy nie wynika, że:
-dzieje się tak tylko przy scenariuszu wykonywanych akcji tak jak opisałem,

Nie dochodzi do 'zawieszeń' jeśli między pomiędzy kliknięciem przycisku a przejściem do innej zakładki:
-klikniemy jakiś przycisk(Jbutton,Jtogglebuton) w pasku narzędzi,
-klikniemy ponownie już otwartą zakładkę.

Wybieranie czegokolwiek z paska menu pomiędzy wspomnianymi operacjami nie chroni przed 'zawieszaniem'
Objaśnienia do kodu:

  • JButtony o których mowa należą do tablicy "rog[]"
  • przyciski paska narzędzi nie powodują w zasadzie żadnych modyfikacji 'obszaru roboczego' a jedynie zmieniają zmienne sterujące sposobem rysowania na panelach.

Myślę, że najistotniejsze fragmenty kodu to:


public mojaAplikacja()
{
(...)
 glpanel = new JPanel(new BorderLayout());
zakladka = new JTabbedPane();

       obszarRoboczy();

     zakladka.addChangeListener(new ChangeListener()
     {
         public void stateChanged(ChangeEvent event)
         {
            aktywna_zakl = zakladka.getSelectedIndex();
            lewy=false;
            prawy=false;
            fill_podswietl_combo(zakladka.getSelectedIndex(),pieter);
         }
     });
zakladka.setPreferredSize( new Dimension( dostepnyY+8 , dostepnyX+31 ) );
     zakladka.setSize( new Dimension( dostepnyY+8 , dostepnyX+31 ) );

     srodkowy = new JPanel();   
     srodkowy.add(zakladka);

glpanel.add(pod_przybornik, BorderLayout.NORTH);     
     glpanel.add(srodkowy, BorderLayout.CENTER);

     JScrollPane calosc = new JScrollPane(glpanel);
     add(calosc);
}

   private void obszarRoboczy()
   {
       zakladka.removeAll();

       jakiPanel();
       System.out.println("Rozmiar panela jest="+rozmPan);

       pole = new Panelik[pieter][rozmiarX][rozmiarY];
       space= new int[pieter][rozmiarX][rozmiarY];                              
       kwadraty= new JPanel[pieter];
       pietro = new JPanel[pieter];
       przewijany = new JScrollPane[pieter];
       poziomaSkala = new skala[pieter];
       pionowaSkala = new skala[pieter];

       rog = new JButton[pieter];
       rogI = new ImageIcon[pieter];

       max=rozmiarX*rozmiarY*pieter;
       System.out.println("max="+max);

       if(rozmiarX>rozmiarY)                
       {    tab = new int[rozmiarX*30];
       }
       else 
       {    tab = new int[rozmiarY*30];
       }

       for (int k=0 ; k<pieter ; k++)
       {
           kwadraty[k] = new JPanel();
           kwadraty[k].setLayout(new GridLayout(rozmiarX,rozmiarY));    
           kwadraty[k].setBounds(0,0,rozmPan*rozmiarY,rozmPan*rozmiarX);

           pietro[k] = new JPanel();
           pietro[k].setLayout(null);

           for (int i=0 ; i<rozmiarX ; i++)             
           {
               for (int j=0 ; j<rozmiarY ; j++)         
               {
                       pole[k][i][j] = new Panelik();
                       obsluga obsl = new obsluga(k,i,j);
                       pole[k][i][j].addMouseListener(obsl);
                       kwadraty[k].add(pole[k][i][j]);
               }
           }

           pietro[k].add(kwadraty[k]);

           przewijany[k] = new JScrollPane(pietro[k]);
           rogI[k] = new ImageIcon("minim.gif");
           rog[k]= new JButton();
           rog[k].setIcon(rogI[k]);
           rog[k].addActionListener(new ActionListener()
           {
               public void actionPerformed(ActionEvent e)
               {
                    for (int h=0 ;h<pieter ; h++ )
                    {   
                        pietro[h].setPreferredSize(new Dimension(rozmiarY*rozmPan,rozmiarX*rozmPan));
                        kwadraty[h].setBounds(0,0,rozmiarY*rozmPan,rozmiarX*rozmPan);

                        //pietro[h].revalidate();
                        //pietro[h].repaint();

                        poziomaSkala[h].setPreferredWidth(rozmPan*rozmiarY);
                        poziomaSkala[h].setSkok(rozmPan);
                        pionowaSkala[h].setPreferredHeight(rozmPan*rozmiarX);
                        pionowaSkala[h].setSkok(rozmPan);

                        przewijany[h].revalidate();
                        przewijany[h].repaint();
                    }
                    zakladka.revalidate();
                    zakladka.repaint();

                    glpanel.revalidate();
                    glpanel.repaint();
               }
           });

           przewijany[k].setCorner(JScrollPane.UPPER_LEFT_CORNER, rog[k]);

           poziomaSkala[k] = new skala( skala.HORIZONTAL , rozmPan,stala_s,rozmPan*dostepnyY+4 );
           pionowaSkala[k] = new skala( skala.VERTICAL , rozmPan,stala_s,rozmPan*dostepnyX+4 );
           poziomaSkala[k].setPreferredWidth( rozmPan*rozmiarY );
           pionowaSkala[k].setPreferredHeight( rozmPan*rozmiarX );
           przewijany[k].setColumnHeaderView(poziomaSkala[k]);
           przewijany[k].setRowHeaderView(pionowaSkala[k]);

           zakladka.addTab(""+k, null, przewijany[k], "Poziom "+k);
           zakladka.setMnemonicAt(k, 48+k ); 
       }
       zakladka.revalidate();
       zakladka.repaint();
   }
0

Skorzystaj z profilera - powie Ci w jakiej funkcji spędza najwięcej czasu. W NetBeans jest już wbudowany.

0

korzystam tylko i wyłącznie z Eclipse. Czy tam też jest coś w tym stylu (jak się do tego dostać) ?

0

Moim zdaniem masz nadmiarowe wywołania revalidate(). To jest nierzadko bardzo kosztowna czasowo procedura, która i tak jest wywoływana z automatu na tak małym zbiorze komponentów jak to możliwe. Jeżeli niepotrzebnie wymuszasz przeprowadzenie dodatkowych doLayout(), które nic nie zmieniają, to stąd możesz mieć te przycinki.
Dwa cytaty z javadoca revalidate:

  1. "Supports deferred automatic layout. "
  2. "This method will automatically be called on this component when a property value changes such that size, location, or internal layout of this component has been affected."
0

wywołania revalidate() i repaint(), faktycznie były nadmiarowe. Nie mniej, zamulanie ustąpiło dopiero w momencie przypisania tego actionListener'a do specjalnie powołanego w tym celu (zwykłego) przycisku znajdującego się w pasku narzędziowym.
Dlatego też uważam, że sprawa pozostaje nadal niewyjaśniona.

0

Sprawa się wyjaśniła. Przyczyną zamulania jest duża liczba komponentów/kontenerów, a dokładniej chodzi o 'focus'. Akurat w tym przypadku ominąłem to w przenosząc zrobioną funkcjonalność do paska menu do jednego z JToggleButtonów ( rozwiązaniem mogłoby być również odpowiednie ustawienie FocusSubsystem. Zainteresowanym poleca się:
http://download.oracle.com/ja[...]orial/uiswing/misc/focus.html )

Myślę, że temat można uznać za zamknięty :) .

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0