JPane inside JScrolledPane. No vertical scrollbar when needed - java

ive got a JPane within a JScrolledPane. When i add content to JPane , JScrollPane doesnt show scrollbar. I tried repaint() and revalidate() but it didnt help.
static void ladowaniePaneli()
{
int b;
for(b=0;b<o;b++)
{
bgPanel[b] = new JBackgroundPanel();
nowyPanel[b] = new JPanel();
((FlowLayout)bgPanel[b].getLayout()).setVgap(0);
nowyPanel[b].setPreferredSize(new Dimension(790,518));
nowyPanel[b].setOpaque(false);
vertical[b] = new JScrollPane(nowyPanel[b]);
vertical[b].setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
vertical[b].setPreferredSize(new Dimension(789,517));
vertical[b].setOpaque(false);
vertical[b].getViewport().setOpaque(false);
bgPanel[b].add(vertical[b]);
}
}

It makes sense that scrollbars are never seen since you restrict the size of the contained component so that it's always trivially larger than the scrollopane's viewport:
nowyPanel[b].setPreferredSize(new Dimension(790,518));
Solution: don't do that.

if i dont use setPreferredSize method components wont warp to another line
You can try the Wrap Layout.
pairs should be warped to new line if they exceed JScrollPane width
Components are layed out individually. I you want a group of components to wrap then you would need to add the components to a separate panel first. Then add the panel to the panel using the WrapLayout.

Related

How to use JScrollPane alongside JTextArea?

I have written this code. Here I want to make a JScrollPane work with JTextArea. But it is not working at all. Earlier I almost did the same thing. It used to work. Please provide a solution. Thanks in advance. I have posted the code.
protected void startServerProcess(int port) {
serverFrame = new JFrame("SERVER NOTIFICATIONS PANEL | Labyrinth Developers");
serverFrame.setSize(500, 500);
serverFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
serverFrame.setLocationByPlatform(true);
serverFrame.setLocationRelativeTo(null);
serverFrame.setVisible(true);
notificationsTA = new JTextArea();
notificationsTA.setBounds(0,0,466,500);
notificationsTA.setLineWrap(true);
notificationsTA.setRows(1000);
notificationsSP = new JScrollPane();
notificationsSP.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
notificationsSP.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
notificationsSP.setViewportView(notificationsTA);
notificationsSP.setWheelScrollingEnabled(true);
notificationsSP.setBounds(470, 0, 30, 500);
serverFrame.add(notificationsTA);
serverFrame.add(notificationsSP);
}
JTextArea is already added in JScrollPane so there is no need to add it again in JFrame as well. Remove below line:
serverFrame.add(notificationsTA);
You can add the component in the viewport of scroll pane using its Constructor as well that internally calls JScrollPane#setViewport() method.
notificationsSP = new JScrollPane(notificationsTA);
Some Points:
JFrame be default uses BorderLayout and you can add only single component in each section (North, South, East, West and Center).
Read more How to Use BorderLayout
Call serverFrame.setVisible(true); in the end after adding all the components.
Don't use setBounds() at all. Just leave it for Layout Manager to set the size and position of the components.
Use SwingUtilities.invokeLater() to make sure that EDT is initialized properly.
Read more
Why to use SwingUtilities.invokeLater in main method?
SwingUtilities.invokeLater

JScrollPane does not update scrollbar

I am trying to create a JScrollPane that contains a JPanel that will be increasing and decreasing in height. When it becomes larger than the size of the JScrollPane, it should create a vertical scroll bar which will allow me to scroll through the entire JPanel. However, I am having difficulty achieving this. Yes, I know I am not using LayoutManagers. No, I will not be using them, and I need a solution that does not involve their usage.
Here are the two button's AbstractActions that add and subtract from the JPanel:
class AddACT extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
info.setSize(420,info.getHeight() + 40);
info.add(new SubPanel); // Adds another JPanel into the main JPanel (for content input)
gui.repaint();
infoS.validate();
}
}
class RemoveACT extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
info.remove(subPanel()); // This would remove the last JPanel added to the main JPanel
info.setSize(420,info.getHeight() - 40);
gui.repaint();
infoS.validate();
}
And here is the code for the main JPanel and the JScrollPane:
final JPanel info = new JPanel();
final JScrollPane infoS = new JScrollPane(info, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
info.setLayout(null);
info.setSize(420,600);
infoS.setLocation(10,80);
infoS.setSize(420,490);
gui.add(infoS); // gui is the frame's content pane (the overall JPanel)
This is the second project I've been trying to learn GUI by doing. I am a complete novice in Swing and am only intermediate in Java. Sorry if I am making a blindingly obvious mistake.
1) Use LayoutManagers (+1 to #kleopatra and #GagandeepBali comments)
The absence of LayoutManagers only guarantees your GUI's will look very trashy (especially when run on other OSes/builds) and being a Novice you should rather learn the correct way than learn the wrong way and get into bad habits like calling setSize() etc.
Have a read on these links to get you started:
A Visual Guide to Layout Managers
Concurrency in Swing
2) See this example for how to use a JScrollPane, it simply adds a JPanel with buttons to a JScrollPane which in-turn is added to the JFrame.
3) Also see this example for how to make the JScrollPane vertically scroll-able only.
4) For more on JScrollPanes have a look here: How to Use Scroll Panes.
5) As for how it interacts with LayoutManager, if you do not explicitly set its size via setPreferredSize(Dimension d) the scroll pane computes it based on the preferred size of its nine components (the viewport, and, if present, the two scroll bars, the row and column headers, and the four corners)
6) On your usage of validate():
validate() is used when new JComponents are added to a visible component
revalidate() is used when JComponent is removed/added from a visible component
revalidate() covers validate() too
Thus always use this:
//add or remove component(s)
revalidate();
repaint();
References:
http://www.daniweb.com/software-development/java/threads/405568/validate-vs-revalidate
LayoutManager is not required to solve the problem. The problem in Thrfoot's example is in these lines:
final JScrollPane infoS = new JScrollPane(info, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
info.setLayout(null);
info.setSize(420,600);
The program appears to recognize there is a need for scroll bars (it would show the scroll bar if your setting was VERTICAL_SCROLLBAR_AS_NEEDED), but the actual scrolling does not work (the scroll bar slider is not there).
To fix this, first set the preferred size of info, then construct the infoS.
Example:
info.setPreferredSize(420,600);
final JScrollPane infoS = new JScrollPane(info, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
The idea is to set the preferred size of the info panel before it is used for the scroll pane. This is the same reason to set the size and location of infoS before adding to the gui:
infoS.setLocation(10,80);
infoS.setSize(420,490);
gui.add(infoS); // gui is the frame's content pane (the overall JPanel)

Resizing a JPanel inside of a JScrollPane clears the things I've drawn on the JPanel

I've got a JPanel inside a JScrollPane. I draw things in the JPanel, and at some point I might draw past the width of the JScrollPane. In this case, I'd like the horizontal scroll bar to appear, and I'd like to be able to scroll around to view different parts of the JPanel. However, I end up clearing the JScrollPane.
frame = new JFrame();
frame.setBounds(100, 100, 1000, 800);
localScrollPane = new JScrollPane();
localScrollPane.setBounds(768, 6, 226, 350);
frame.getContentPane().add(localScrollPane);
localView = new JPanel();
localScrollPane.setViewportView(localView);
drawSomeThings(localView.getGraphics());
// wait for user input
int newWidth = drawThingsPastTheWidth(localView.getGraphics());
// these next two lines clear it
localView.setPreferredSize(new Dimension(newWidth, localView.getHeight()));
localView.revalidate();
What am I doing wrong? Thanks!
drawSomeThings(localView.getGraphics());
Don't use the getGraphics() method to do painting. The painting will be lost the next time Swing determines the components needs to be repainted.
Instead custom painting is done by overriding the paintComponent() method of your component.
Do not use setPreferredSize method, here's a related thread.
Do not specify explicetly the size of the JScrollPane with setBounds. Let the LayoutManager of it's parent take care of this.
JScrollPane should use a
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED by default. So
the scrollbar should appear automatically when the preferred size of
the child component is higher than the displayed area. Try to
revalidate the JScrollPane instead of the JPanel.
It would appear that redraw is being called at some point, I've not used swing for a while so I'm not entirely sure what the problem is but try debugging and running through the code step by step to see where redraw is being called would be a good starting place.
you should certainly use repaint instead of revalidate. revalidate only marks all the container upto the top level as invalid.

How to limit dynamic addition of components within the borders of the form or a panel

I am trying to add components to a jpanel dynamically from a database, one after the other, however they extend beyond the limits of the form (and even the screen) horizontally. I am using a panel with BoxLayout which positions inner components on the x-axis. What I would like to do is limit the addition of components on the x-axis at the border of the form (or the border of the container panel) .
What I tried so far is:
To set the maximum size (width) of the
container jpanel but that did not
work.
To set the layout manager to
flowlayout, but it also expands
infinitely on the x-axis.
To position the container panel inside a
scrollpane. That makes a huge
horizontal scrollbar, which means that
it does not limit the components to
the border of the form.
Should I make a custom layout? Any ideas simpler than that?
My code looks like:
jpanelCases.setLayout(new BoxLayout(this.jpanelCases, BoxLayout.X_AXIS));
db = Database.getInstance();
List<Category> cats = db.getCategories();
for(Category c : cats){
JPanel jp = new JPanel();
//addition of other components to the newly created panel here
jpanelCases.add(jp);
}
however they extend beyond the limits of the form (and even the screen) horizontally.
So what do you want to do in this case:
a) just ignore the components and not add them to the frame
b) display the components on a new line
If the answer is "b", the try the WrapLayout.
Try to put 2 glues, one at first one at last:
jpanelCases.setLayout(new BoxLayout(this.jpanelCases, BoxLayout.X_AXIS));
jpanelCases.add(Box.createHorizontalGlue());
db = Database.getInstance();
List<Category> cats = db.getCategories();
for(Category c : cats){
JPanel jp = new JPanel();
//addition of other components to the newly created panel here
jpanelCases.add(jp);
}
jpanelCases.add(Box.createHorizontalGlue());
What about using JScrollPane on the JPanel? This will contain the elements within the panel without exceeding its physical boundaries. Otherwise, if you do not like the scroll idea I suggest that you somehow keep track of the total sum of width of elements added to the panel with respect to the panel physical width, and stop adding elements when the next element width added to the sum exceeds the panel width.
I hope this helps!

JScrollPane: How to resize automatically the JPanel contained in the scroll

I'm working on a little applet that has a list of items in a JScrollPane on the left.
the user will be able to add and remove elements from this list.
therefore I need to create a scrollable list.
this part is easy.
I'm usually tempted to do most of the GUI resizing by hand but I read in the doc of the JScrollPane that it is better to let swing handle it rather than manually changing the dimension.
the problem is that I keep adding element and the inside panel doesn't change size.
any ideas?
here is some of the code I'm using:
constructor:
public SideBarView(Dimension d) {
super(d);
Dimension d2 = new Dimension(100,300);
this.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
//INSIDE VIEW (zone that is being scrolled)
container = new SideBarContainer(d2);
// container.setSize(d2);
// container.setPreferredSize(d2);
// container.setMaximumSize(d2);
// container.setMinimumSize(d2);
scrollPane = new MyJScrollPane(container);
new ImageLoaderWorker(this,menuButton).execute();
Dimension d3 = new Dimension(d.width, d.height-d.width);
scrollPane.setSize(d3);
scrollPane.setMaximumSize(d3);
scrollPane.setMinimumSize(d3);
scrollPane.setPreferredSize(d3);
add(scrollPane,BorderLayout.PAGE_START);
setBorder(BorderFactory.createEmptyBorder());
}
Adding to container:
element = new JPanel();
Dimension d2 = new Dimension(100,100);
element.setSize(d2);
element.setPreferredSize(d2);
element.setMaximumSize(d2);
element.setMinimumSize(d2);
element.setBackground((panelcount++%2==0)?Color.BLUE:Color.RED);
cointainer.add(element);
any idea what I'm missing ? or should I just resize the container by hand as I go along?
You need to tell the container to lay out the components. This is done by revalidating the panel:
container.add(element);
container.revalidate();
panel.setSize(d2);
panel.setPreferredSize(d2);
panel.setMaximumSize(d2);
panel.setMinimumSize(d2);
This let's no option to resize for swing, since you tell the layout manager to use exactly the size of d2 (100/100).
Try without setMaximumSize and setPreferredSize. You might need to invalidate the panel or scrollpane after adding/removing content as well.
Edit:
I think I considered panelto be your containter. Could you provide the setup code for your scrollpane and the container?
Did you set a layout manager for the container?
Another possibility, if you don't have to do it yourself, could be to use some SwingX component (like TaskPane etc.). Unfortunately, they seem to be in a transition over to java.net and thus many resources are not available as of now. However, there's a basic download page.

Categories

Resources