Swing-es JScrollPane probléma

Fórumok

Üdv!

Bele is csapok a lecsóba:

Van egy JPanelem (nevezzük main-nek) ez a main JPanel tartalmaz egy "body" JPanel-t. Azt szeretném, hogy minden tartalom ami ebben a body JPanel-ben van scrollozható legyen, ha a tartalom túl nagy. A tartalom lehet JTable, egy kép, JLabel, JTextArea stb...

Erre azt a megoldást találtam ki, hogy a body-t bele raktam egy JScrollPane-ba, a JScrollPante-t a main-be. Ekkora ha a body-ba tartalmat teszek ami túl hosszú, akkor megjelenik a scrollbar. Igen ám, de ha belerakok egy JTextArea-t a body-ba a scrollbar mögé is befolyik a szöveg.

Az igazi megoldás az lenne, ha direkt kapna a JTextArea egy JScrollPane-t, de mint mondtam a tartalom változhat, ezért inkább az egész body-t scrollozhatóvá akarom tenni.
Az érdekes az, hogy ha fogom a JTextArea tartalmát és mögé rakok még 4-5 entert akkor nem folyik a scrollbar alá, foggalmam sincs, hogy miért.

Itt egy kis kód, hátha ez jobban szemlélteti a dolgot:


class Display:

JPanel main = new JPanel();

JPanel setBodyBox{
...
/* BOX BODY BEGIN */
bodyBox = new JPanel(new GridBagLayout());
GridBagConstraints boxBody_gbc = new GridBagConstraints();
boxBody_gbc.gridx = 0;
boxBody_gbc.gridy = 2;
boxBody_gbc.weightx = 1.0;
boxBody_gbc.weighty = 1.0;
boxBody_gbc.anchor = GridBagConstraints.FIRST_LINE_START;
boxBody_gbc.fill = GridBagConstraints.BOTH;
boxBody_gbc.insets = new Insets(TerminalConstants.FLOW_BOX_BODY_MARGIN_TOP, 0, 0, 0);
bodyBox.setBackground(TerminalConstants.FLOW_BOX_BODY_BG);
/* BOX BODY END */

JScrollPane scrollPane = new JScrollPane(bodyBox);
scrollPane.setBorder(BorderFactory.createEmptyBorder());
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

main.add(scrollPane, boxBody_gbc);

return bodyBox;
}

class Valami extends Display:

valamiInitGui{
JPanel bodyBox = setBodyBox();

GridBagConstraints boxBody_gbc = new GridBagConstraints();
boxBody_gbc.gridx = 0;
boxBody_gbc.gridy = 0;
boxBody_gbc.weightx = 1.0;
boxBody_gbc.weighty = 1.0;
boxBody_gbc.anchor = GridBagConstraints.FIRST_LINE_START;
boxBody_gbc.fill = GridBagConstraints.HORIZONTAL;
boxBody_gbc.insets = new Insets(TerminalConstants.FLOW_FORM_PADDING, 0, 0, 0);

setupPictures(bodyBox , flowBox_gbc);

boxBody_gbc.gridx = 0;
boxBody_gbc.gridy = 1;
boxBody_gbc.gridwidth = 2;
boxBody_gbc.fill = GridBagConstraints.BOTH;
boxBody_gbc.anchor = GridBagConstraints.LINE_START;
boxBody_gbc.insets = new Insets(40, 20, 0, 0);

JTextArea textArea = new JTextArea();
textArea.setOpaque(false);
textArea.setEditable(false);
textArea.setFont(TerminalConstants.FONT_BOX_BODY_HINT2);
textArea.append("Sok sok szöveg");
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);

bodyBox.add(textArea, boxBody_gbc);
}

Hozzászólások

Szia,
nekem az a tapasztalatom, hogy a scrollpane nem igazán szereti a weight alapú layoutokkal ellátott tartalmakat (a viewport és a tartalom nem tudják eldönteni, ki legyen a főnök).
Illetve sok olyan komponens van a swingben, amik figyelik, hogy a parentjük scroll pane-e, pl. a table és ha jól emlékszem a textarea is és eszerint határozzák meg a preferred size méretüket, illetve a LAF is beleszólhat.

Talán jobban járnál, ha a megjelenítendő tartamat tennéd meg a scrollpane viewportjának.
Tehát megvan a tartalmad, meghatározod mekkora is az valójában, aztán beteszed a scroll viewportjába. Ha változik a mérete, akkor gondoskodnod kell róla, hogy a scroll erről tudomást szerezzen. Ez az amit a text, meg table elintéznek neked, egyébiránt erre figyelned kell.

Köszönöm a választ! Igen sajnos a body-nak GridBagLayout-nak kell lennie ezen nem tudok változtatni.

"Talán jobban járnál, ha a megjelenítendő tartamat tennéd meg a scrollpane viewportjának."
A scrollPane momentán nem elérhető a Valami osztályból, persze láthatóvá tudom tenni, de nem értem, hogy utána mit kell vele csinálnom. Megtudnád mutatni az én példámon, hogy hogy kell a viewportot beállítani?

Azt még mindig nem értem, hogy az üres sorokkal a szöveg végén miért javul meg a dolog.

Szia!
Arra nem vállalkoznék, hogy a példádon keresztül mutassam meg, mert egyrészt, ha valamit ide kódot bemásolok, akkor azt előtte szeretem ellenőrizni, hogy ne blamáljam magam :), másrészt ez annyira helyzet függő, hogy inkább általánosan írnék: a lényeg, hogy a tartalom, ami bekerül a viewportba annak a mérete legyen meghatározott. Ha esetleg változik a méret, akkor informálni kell a scrollviewt, hogy újra tudja magát kalkulálni. A problémád hasonló az image megjelenítéshez, mikor scrollozni szeretnél egy képet, de annak betöltés után a mérete változhat. Ekkor a betöltés után meg kell mondania scrollnak, hogy mekkora amit scrollozni kell, szvsz hasonló a Te esetedhez, holott itt nem egy kép, hanem bármi más lehet a tartalom. Nézd meg ezt a linket:http://www.coderanch.com/t/338732/GUI/java/JScrollPane-resizing-compone….
Bocsi, ennél sokkal többet nem tudok segíteni, a swing néha megtréfálja az embert.