JTree does not display inside JScrollPane - java

I need to display account names for my program and I want to do this using JTree inside a JScrollPane.
Here is my code:
public void loadAccounts() {
accountsRoot = new DefaultMutableTreeNode("Accounts"); //create root
accountsRoot.add(new DefaultMutableTreeNode("Fred")); //add one element
//for testing
accounts = new JTree(accountsRoot);
accountsPane = new JScrollPane(accounts);
accountsPane.add(accounts); //don't think this is necessary
canvas.add(accountsPane);
accounts.setBounds(0, 0, accountsPane.getWidth(), accountsPane.getHeight());
accountsPane.setBounds(460, 270, 240, 410);
accounts.setVisible(true);
accountsPane.setVisible(true);
}
Because I am not using a layout I set the bounds manually.
I can't seem to get it to show. I want to eventually end up loading the accounts from a while so I figure JTree would be pretty easy for that,

accountsPane = new JScrollPane(accounts);
accountsPane.add(accounts); //don't think this is necessary
Not only is that not necessary but it will mess things up as this in effect adds your accounts JTree to multiple containers -- to the JScrollPane's viewport (good) and to the JScrollPane itself (bad). Don't do that. Add it to the JScrollPane's viewport only either through the JScrollPane's constructor as shown on the first line above, or by calling setViewportView(...) on the JScrollPane object after creating it.
Edit: another problem is your use of setBounds(...). You shouldn't be doing this but rather should be using layout managers to allow the proper viewing of your components. You will also need to call revalidate() and repaint() on whatever container is accepting the JScrollPane.

Related

JScrollPane and JPanel

I have a simple JPanel so defined:
JPanel listObject = new JPanel(null);
listObject.setBounds(0, 350, 300, 100);
I would insert this into a JScrollPanel
I tried to define it so:
JScrollPane scroll = new JScrollPane(listObject);
scroll.setBounds(0, 375, 270, 100);
mainPanel.add(scroll);
The problem is that with this code the panel is not show inside the scrollPane. How can i do for that?
Thank you.
Note some problems with your code:
JPanel listObject = new JPanel(null);
You're adding this to a JScrollPane and note that JScrollPanes don't handle null layout-using viewport views well at all. It in fact can completely mess up the scrollpane's ability to scroll.
listObject.setBounds(0, 350, 300, 100);
By calling setBounds(...) you're in effect saying try to put this component at the [0, 350] position of the container that holds it and size it to [300, 100]. Note that the container that you're adding it to is the JScrollPane's viewport. So if the viewport follows this request, and since you're trying to make your JScrollPane and its viewport have a width of 270 with this code here:
scroll.setBounds(0, 375, 270, 100);
You're in effect asking the JScrollPane to add a JPanel way off to the right beyond the bounds of the JScrollPane itself. Ignoring that the viewport is likely not even using a null layout, this really makes little sense.
You will want to get rid of the setBounds(...) business to start with. JScrollPanes use their own layouts, and so there is no need or good effect by trying to set the bounds of a component being added to it. Instead consider overriding the JPanel's getPreferredSize. Also, a component held by a JScrollPane should not use a null layout as this will usually prevent the JScrollPane from working correctly, from knowing how to scroll the container.
The bottom line here is that you will want to avoid null layouts in general as they lead to the creation of rigid GUIs that are very difficult to enhance or debug, that may look OK on one platform but will definitely look bad on all other platforms or screen resolutions. It's a newbie trap to think that null layout is the way to go, one that you'll quickly learn to avoid the more experience you gain.
If you're still stuck after reading the answers, please consider creating and posting your minimal example program, a small compilable and runnable program that shows for us your problem.

JPane inside JScrolledPane. No vertical scrollbar when needed

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.

Replace Component in GridBagLayout

I created a Class that extends from JPanel which layout property is GridBagLayout. I basically need to display an array of JLabels (grid) but i'm not able to replace a component once it's created. I've tried to remove the component that I want to change, and then place the new one but the result is weird. For example i've created an array of 10x10 JLabels and want to replace position[0][0] and position[9][9] with this code:
//At first i have the jpanel layout completely filled
this.remove(0);
this.add((JLabel) start, 0); //This was created with GridBagLayout.gridx = 0 and GridBagLayout.gridy = 0 and it's fine
this.remove(99);
this.add((JLabel) end, 99); //This was created with GridBagLayout.gridx = 9 and GridBagLayout.gridy = 9 and it's out of grid
this.revalidate();
But only position[0][0] looks fine. What should i do to replace a component?
In GridBagLayout, each component is associated with GridBagConstraints. Simple removing a component and replacing it with a component at the same position won't work, as the new component will receive a new GridBagConstraints
What you can do, however, is get the constraints associated with a give component.
Component toRemove = getComponent(0);
GridBagLayout layout = (GridBagLayout)getLayout();
GridBagConstraints gbc = layout.getConstraints();
remove(toRemove);
add(new JLabel("Happy"), gbc, 0);
This will add the component using the same constraints as those used by the component you are removing.
This of course all assumes that you are assigning the gridx/gridy constraints...
I solve my problem by using:
this.setComponentZOrder(newItem, 0);
So, I actually didn't remove the object on Jpanel but I placed the new one over the old object.

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)

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