JScrollPane + JPanel, brak suwaków

0

Mam pewien panel, który dziedziczy po JPanel i chcę w nim umieszczać jakieś tam kontrolki. Kontrolek może być duża ilość, więc chciałbym aby możliwe było przewijanie panelu w przypadku, gdyby kontrolki przestały się mieścić (oś pionowa). Zrobiłem testową pętlę, tworzącą mi radio-buttony i niestety poniższy kod nie daje mi tej funkcjonalności - w ogóle nie ma suwaków. Nie wiem co jest nie tak. Myślałem, że problemem jest to, że rozmiar EditAreasPanel się de facto nie zmienia (tylko dochodzą komponenty), ale nawet kiedy w 'setBounds' dopisałem 'parentContainer.getHeight()+800' (czyli powinno już nie mieścić się na ekranie) suwaki nadal się nie pojawiły :/

public EditAreasPanel(Container parentContainer)
	{
		setBounds(0,0,parentContainer.getWidth(),parentContainer.getHeight());
		setLayout(null);
		
		int cnt=0;
		for(int i=0; i<200; i++)
		{
			JRadioButton rButton = new JRadioButton("abc");
			rButton.setBounds(20, 20+cnt, 200,25);
			add(rButton);
			
			cnt+=50;
		}
		
		scrollPane = new JScrollPane(this);
		scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
	}
1

To działa inaczej...
Gdy masz taki kod

SuperDuperPanel panel = new SuperDuperPanel();
okienko.add(panel);

i chcesz go przerobić na JScrollPanel, to nie możesz dodawać tego panelu, tylko właśnie JScrollPanel w jego miejsce

SuperDuperPanel panel = new SuperDuperPanel();
okienko.add(new JScrollPane(panel)); // dodajemu scroll pane zamiast panelu
0

No tak, to ma sens... Zrobiłem tak jak pokazałeś, ale niestety dalej całość zachowuje się tak jakby komponent mieścił się w scrollPane - nie pojawiają się suwaki.

fragment kodu w konstruktorze głównego okna aplikacji (JFrame):

 
scrollPane = new JScrollPane(editAreasPanel);
		scrollPane.setBounds(0,0, 700, 400);
		scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		add(scrollPane);
0

Spróbuj czegoś takiego:

panel.add(button);
panel.setLayout(new GridLayout(n, 1));
frame.revalidate();

1: Dodajesz jakiś komponent do panelu
2: Ustalasz nowy LayoutManager na scrollowanym panelu, gdzie n (jeśli nie działa, to n+1) to liczba komponentów dodanych do panelu
3: Do stosowaniu przy dynamicznym dodawaniu komponentów, użyj na swoim JFrame, bez tego nie zauważysz zmiany, dopóki np. nie zmienisz rozmiaru okna

0

Aby JScroll panel działał musisz po prostu dodać

scrollPane.setBounds(x, y, wys, szer);

0

Sorki za double nie zmieniło posta :S

eee? nie dodaleś magicznej rzeczy tak wgl:
scrollPane.setViewportView(panel);

0

Całkowicie wystarczy to co już jest

new JScrollPane(panel)
0

Misiek89 - to jest średnie rozwiązanie ponieważ nie chcę mieć żadnego LayoutManagera, bo oprócz kontrolek, na tym panelu będą też inne panele które w specyficzny sposób będę chciał umiejscowić i mieć nad tym kontrolę. Ponadto musiałbym dodać licznik komponentów. Niby nie jest to dużo roboty ale trochę zaciemnia kod, a poza tym i bez tego to powinno działać... ale dzięki za radę.

polish civil - W pierwszym podanym fragmencie kodu, faktycznie o tym zapomniałem, ale później dodałem setBounds (co jest w drugim fragmencie) i nic się nie zmieniło :(

Polish - tak jak napisał bogdans, samo wywołanie konstruktora ustawia VievportView, ale dla pewności sprawdziłem i nic to nie dało

Ma ktoś jeszcze jakiś pomysł ?

0

Jeżeli ustalasz rozmiar obiektu (panelu?) editAreasPanel, (setBounds(0,0,parentContainer.getWidth(),parentContainer.getHeight();), to paski się nie pojawią bo nie są potrzebne - panel mieści się na ekranie. Możesz wymusić pojawienie się pasków

scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

ale będą nieaktywne.
Druga sprawa, czym jest parentContainer i kiedy wykonywany jest konstruktor EditAreasPanel? Jeśli parentContainer, to główne okno, a konstruktor wywoływany jest przed wyświetleniem okna, to parentContainer.getWidth() i parentContainer.getHeight() zwracają zero.
Rozwiązanie jest takie:

  • w głównym oknie setBounds(....);
  • w konstruktorze EditAreasPanel setPreferredSize(new Dimension(...,40+200*25));
0

bogdans - tak, parentContainer to główne okno (JFrame) i w jego konstruktorze, po ustaleniu setBounds i innych atrybutów, tworzony jest EditAreasPanel (obiekt klasy dziedziczącej po MyPanel, która dziedziczy po JPanel) i wywoływany jego konstruktor. Także parentContainer.getWidth() i parentContainer.getHeight() nie są zerowe.

Jednak po zmianie

setBounds(0,0,parentContainer.getWidth(),parentContainer.getHeight());

na:

		setLocation(0, 0);
		setPreferredSize(new Dimension(700, 900));

pojawiają się suwaki i są nawet aktywne ale nie przesuwają :P Można za nie złapać i je przeciągać ale okno scrollPanelu się nie przesuwa i po zwolnieniu przycisku myszy z suwaka, natychmiast wraca on na swoje pierwotne miejsce (jakby był na sprężynie)... nie wiem co się dzieje

0

Tak że parentContainer.getWidth() i parentContainer.getHeight() nie są zerowe

Na 99,99% procenta, są zerowe. Dodaj wiersz

System.out.println(parentContainer.getWidth()+"  "+parentContainer.getWidth());

i się rozstrzygnie.
Analogiczny kod u mnie działa, musiałeś skopać w innym miejscu. Jeśli to nie tajemnica, to pokaż więcej kodu.

0

Sprawdziłem, System.out.println(parentContainer.getWidth()+" "+parentContainer.getWidth()); wypisuje odpowiednie wartości.

Projekt nie jest ściśle tajny - to projekt na zaliczenie przedmiotu - gra typu PointAndClick.

Poniżej zamieszczam jego kod, przy czym pierwsze dwa linki prowadzą do klas mających bezpośrednią "styczność" z problemem, natomiast kolejne pliki to klasy niezbędne do działania całości - jeżeli ktoś będzie chciał to sobie uruchomić. Właściwie to znalazłem sposób na uporanie się z problemem - po prostu zamiast JScrollPane, mogę użyć JComboBox - i to nawet będzie chyba lepsze rozwiązanie w moim przypadku i zacząłem je już implementować, ale linijki z JScrollPanem nadal są ale zakomentowane. Niemniej jednak chciałbym wiedzieć dla czego rozwiązanie ze scrollPanem nie działa, w końcu pewnie itak kiedyś ten problem do mnie wróci.

http://wklej.org/id/1040110/
http://wklej.org/id/1040111/

http://wklej.org/id/1040112/
http://wklej.org/id/1040113/
http://wklej.org/id/1040114/
http://wklej.org/id/1040115/
http://wklej.org/id/1040116/
http://wklej.org/id/1040118/
http://wklej.org/id/1040119/
http://wklej.org/id/1040120/

0

Program jest za długi aby go analizować. Jedna rzecz rzuca się w oczy od razu, setVisible(true); należy wywołać po dodaniu wszystkich komponentów. GUI dział koszmarnie, pewne komponenty są początkowo niewidoczne, pojawiają się po przesunięciu kursora myszy w odpowiednie miejsce lub po kliknięciu w przypadkowe miejsce.

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