I know there are a lot of questions similar to this one, but unfortunately they are all about auto scrolling a scrollBar inside of a TextArea.
I use a JScrollPane to simulate a JList: I add small JPanels to a JScrollPane with GridLayout, and they stack verically.
I want the scroll bar to follow the last added element (down), but I can't get it to work.
I tried to adapt some of the answers for the Text, such as:
.autoScrolls(true);
or
JScrollBar vertical = scollPan.getVerticalScrollBar();
vertical.setValue( vertical.getMaximum() );
and even one on changing the updatePolicy, but nothing works for a JScrollPane that isn't bound to a text area, I can only scroll the bar manually.
vertical.setValue( vertical.getMaximum() );
did do something, it scrolls the bar down, but just about 2/3 of the way, and only because I added .revalidate() on the scrollPane after calling it.
Any idea?
After add components to the panel you need to do revalidate() and repaint() to make sure the layout manager is invoked.
JScrollBar vertical = scollPan.getVerticalScrollBar();
vertical.setValue( vertical.getMaximum() );
Then wrap the above code in a SwingUtilities.invokeLater() to make sure the code is added to the end of the Event Dispatch Thread (EDT) so it is executed after all the layout code.
Related
I know that this question might have been asked before, but I just can't get by head around this, and hopefully we could produce a complete answer to a somewhat tricky interface.
The GUI could be described as follows:
Application extends JFrame. Application adds a JPanel mPanel. mPanel adds a JScrollPane ml containing a MoviePanel extending JPanel.
The JScrollPane ml has vertical scrolling. My goal is that once the content of MoviePanel changes, and a run a revalidate() on it, the scroll pane should not, as it currently does, scroll to the bottom. Rather I'd like it to scroll to what ever position it had before the change to MoviePanel. Giving the feel that it never scrolled at all.
I have tried to manually set the scroll position after I run the revalidate() method:
removeAll(); // Removes all components from the JPanel MoviePanel
add(mList()); // Adds a bunch of content (other JPanels) to MoviePanel
revalidate();
ml.getVerticalScrollBar().setValue(0); // Scroll to top (don't work) - and I'd like this value to be the position of the scroll before these lines started to run
but it seems it really doesn't do anything.
I would be so grateful if someone might help me with this!
Add the scrolling code to a SwingUtilities.invokeLater:
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
ml.getVerticalScrollBar().setValue(0);
}
});
I have created a GUI in Java which looks as shown below -
'panel_mid' is the white panel in the middle. I have added it to a scrollpane called 'panel_mid_scrollpane'.
Apart from 'panel_mid' there are more panels -
panel_left (containing 'back' button)
panel_right (visible on right hand side)
Revelant code for this gui is -
panel_mid.setBorder(grayborder);
panel_mid.setBounds(0, 0, 1100, 1060);
panel_mid.setBackground(Color.white);
panel_mid.add(obj.create_test_add_section);
panel_mid_scrollpane = new JScrollPane(panel_mid);
panel_mid_scrollpane.setLocation(150, 20);
panel_mid_scrollpane.setSize(1000, 660);
panel_mid_scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
The Add Section button shown in panel_mid, adds a section to the middle panel, every time it is clicked. When this button is clicked multiple times, the gui looks like -
As you could see, the scrollbar does not appear automatically as panels are added, the last panel is thus only half visible. What could be causing this problem ?
Thanks !
Scrollbars appear automatically when the preferred size of the component added to the scrollpane is greater than the size of the scroll pane.
You appear to be using a null layout.
//panel_mid.setBounds(0, 0, 1100, 1060);
panel_mid.setBackground(Color.white);
panel_mid.add(obj.create_test_add_section);
panel_mid_scrollpane = new JScrollPane(panel_mid);
//panel_mid_scrollpane.setLocation(150, 20);
//panel_mid_scrollpane.setSize(1000, 660);
Don't use a null layout with setSize() and setLocation. Swing was designed to be used with layout managers. If you use layout managers then the scrollbar will work automatically and the size and location will be calculated automatically for you.
Read the Swing tutorial on Layout Mangers.
You must tell the GUI to refresh, so that the containers are laid out again. This will show the container that it also has to show a scrollbar.
So in the ActionListener or whatever you use to add a section, add code like:
container_with_sections.validate();
container_with_sections.repaint();
where container_with_sections is the container (JContainer) which contains the JScrollPane, or a container which contains a container which contains the JScrollPane, and so on.
I'm trying to put a vertical JScrollBar on top of a JPanel. I can add the scoll bar easily enough, but when I run the program, my scroll bar doesn't have any effect. I can drag it up and down, but the contents of the JPanel don't move. I've read all what I can find about how to do this, and it seems very straightforward, but I'm obviously missing something.
Please note that my JPanel layout is set to NULL. Here is the relevant code. Thanks!
public JDlgResults(ArrayList<AnsweredProblem> probList) {
initComponents();
pnlResults.setLayout(null); //allows free form placing of JLabels
/* Iterate over the ArrayList and add each problem to the results table */
Iterator iter = probList.iterator();
int row = 1;
while(iter.hasNext()) {
addRow(row, iter.next());
row++;
}
JScrollBar jScrollResults = new javax.swing.JScrollBar();
pnlResults.add(jScrollResults);
jScrollResults.setBounds(590, 0, 17, 196);
}
I assume that your initComponents() method sets up a bunch of components and adds them to your contentPane and establishes your dialog (whether it be dialog or a frame).
Simply adding your JScrollPane to that panel wont do the trick.
Instead, add your pnlResults to the JScrollPane instance and make that your contentPane.
That's by design. It would be kind of bad if the scroll bar magically tried to pick up panels in its vicinity and started scrolling them.
On a low level, you can add listeners to the scroll bar and implement scrolling yourself. You would also have to tell the scroll bar how much there is to scroll.
However, this is not what you want. You want a JScrollPane that you wrap around your panel. In that way, you never instantiate the scroll bars directly and do not have to deal with the low-level mechanics of scrolling (which is quite complicated).
I'm actually having no problem when dealing with the JScrollPane with JTextArea...
But here... I have a JPanel. And I wanted to use Scroll on it.
Take a look on my JPanel here Image Preview.
I wonder how to do it in netbeans. I think I should do a bit of customized coding.
So, I tried to do like this;
1) Right Click on jPanel2, Customize Code.
2) Using This modified code;
Initialization Code:
jPanel2 = new javax.swing.JPanel();
scrb = new javax.swing.JScrollPane(jPanel2);
// Code of sub-components - not shown here
// Layout setup code - not shown here
scrb.setPreferredSize(jPanel2.getPreferredSize());
jPanel1.add(jPanel2, "card2");
Variable Declaration Code:
private javax.swing.JPanel jPanel2;
private javax.swing.JScrollPane scrb;
Then re-run my Project again....
but,... sigh. THe Scroll didn't came up into the running app.
Is there anything I forget over here?
I tried to manipulate the Size of the jPanel2, but hence not work....
The Scroll didn't appeared.
The problem is in this line:
jPanel1.add(jPanel2, "card2");
Instead of this write this:
jPanel1.add(scrb, "card2");
What you are doing is adding jPnael2 to a scrollpant but then instead of adding that scrollpane to jPanel1 you add jPanel2 to jPanel1 so scrollPane doesn't even come to picture.
Try adding the scrb to jpanel1.
Here's a nice tutorial in scroll panes;
http://download.oracle.com/javase/tutorial/uiswing/components/scrollpane.html
In addition to the other suggestions to add the scrollpane to the panel, I'm not sure if it will work because of the following line of code:
scrb.setPreferredSize(jPanel2.getPreferredSize());
Scrollbars only appear when the preferred size of the component added to the the scrollpane is greater than the size of the scrollpane. So if you layout manager respects the preferred size of the components this condition will never be true.
If you are using NetBeans IDE, it is better to use GUI designer to create scroll pane. Use the below steps to implement a scroll pane:
1. In Netbeans GUI editor, select all panels which requires scroll pane using CTRL+left click
2. Right click on the highlighted panels, select the option 'Enclose in' -> Scroll Pane. This will add a scroll pane for the selected panels.
3. If there are other elements than Panel(say JTree), select all the elements ->Enclose in ->Panel. Then enlose the new parent panel to scroll pane
4. Make sure that 'Auto Resizing' is turned on for the selected parent panel(Right click on panel -> Auto resizing -> Tick both Horizontal and vertical)
I am trying to initialize a JScrollPane to start life at the bottom. I do not want it to scroll automatically after it is initially shown. The scroll pane does not contain a subclass of JTextComponent, but rather a JPanel(GridLayout(0, 1)) containing many JPanels.
I tried using JViewport.scrollRectToVisible() inside an event handler on the parent Window (addComponentListener:componentShown), but it did not seem to work.
Any ideas?
The scroll pane does not contain a
subclass of JTextComponent, but rather
a JPanel(GridLayout(0, 1)) containing
many JPanels.
Then you need to scroll the panel:
panel.scrollRectToVisible(...);
Or you should be able to use:
JScrollBar sb = scrollPane.getVerticalScrollBar();
sb.setValue( sb.getMaximu() );
Also, this code needs to be executed "after" the GUI is visible.