I'm having this strange issue with Swing. I have a main JPanel to which I am adding a JTabbedPane. Inside of this JTabbedPane I am adding another panel:
myTabbedPane.add(innerPanel, "Title", 0);
outerPanel.add(myTabbedPane);
Now, I no longer want myTabbedPane to be JTabbedPane, I want it to be a JPanel. When I change its type (and remove the extra params from its add() method), nothing within the outerPanel is visible anymore. (I am using setBounds() and I set the layouts to null).
Why does it work when using a tabbed pane but suddenly stop when switching to a JPanel? I know that this can be done differently (such as adding the innerPanel directly to the outerPanel), but please don't just tell me to do it differently. I'd just like to know why it suddenly doesn't work when using a JPanel instead. Is there an issue with adding a JPanel to a JPanel? Thanks!
Stop using null layout. Use BorderLayout and then use add inner panel to the center.
Tabbed pane used it own layered layout - that is why it worked before.
Related
I want to create a shop by having a main JPanel that each component inside it is a JPanel with an image, label and button.
I did tried using a JList but the problem with the JList its only holds the rendering of the component and because of that the button isn't working and its only an image. I can walk around and use MouseEvent but it feels wrong for me and I am sure that there is a better solution for it.
I want that the components will change their positions depend on the frame size, like in the JList.
For example, if I change from the width of the screen the positions of the components will change from this:
to this:
I do have an idea by using GridLayout or GridBagLayout in the paintComponent (because it calls every rendering. If you know another method that calls every rendering int the JPanel I would like to know) and changing the positions of the components by changing the layout variables inside the paintComponent.
I did surfed the internet to find a solution but I only found that people used JTable but I don't see it working here.
each component inside it is a JPanel with an image, label and button.
Makes sense.
changing the positions of the components by changing the layout variables inside the paintComponent.
The paintComponent() method has nothing to do with changing the layout of the panels. You should not be playing with the paintComponent() method.
I do have an idea by using GridLayout or GridBagLayout
You are correct to use a layout manager, but unfortunately, none of the default layout managers will wrap automatically at a random number of components.
The layout managers are invoked automatically as the frame is resized.
So you can use the Wrap Layout which is an extension to the FlowLayout that will allow random wrapping.
I am adding a JTextArea to my JPanel and setting it to a specific place but for some reason it does not move at all.
I have used both setBounds() and setLocation(), but to no avail. Here is what I stopped on:
JTextArea name_field=new JTextArea(1,10);
name_field.setBackground(color);
name_field.setBounds(100,100,600,420);
name_field.setLineWrap(true);
add(name_field);
It keeps creating the text field at the same spot: at the top of the screen in the middle. The only thing I managed to do is change it's width by adding name_field.setLineWrap(true) which only confused me even further. If this for some reason isn't supposed to work, is there another way of moving and possible resizing my JTextArea?
default layout of a jpanel is flowlayout .in order to work setBounds() it should be null layout.but it's highly discourage to use null layout[no layout].you should use layouts there are lot of layouts flow,grid,box,..etc.you first decide appropriate layout for your panel and then use it.
if you set layout to null then your code should work .[but dooont!]
setLayout(null); //change jpanel layout to null
JTextArea name_field=new JTextArea(1,10);
name_field.setBackground(color);
name_field.setBounds(100,100,600,420);
name_field.setLineWrap(true);
add(name_field);
I would like to scroll through the contents of my JFrame up and down, preferably with a scroll bar. I don't want to wrap the contents inside a JPanel or JScrollPane, because this causes some visual glitches with my application.
Any idea on how to do this?
JScrollPane would be the easiest way; you say there are glitches, but that probably indicates a problem in your code that will still be a problem even without using a JScrollPane.
If you're absolutely set on not using a JScrollPane, you should create a JPanel using BorderLayout, add a JPanel (call it 'center') with BorderLayout.CENTER and layout set to null. Add your content within 'center', and add another JScrollBar to BorderLayout.EAST, add an AdjustmentListener to the JScrollBar. When the adjustmentListener triggers, you need to move your content (Component.setLocation(...)) that's in center to the relative y offset of the JScrollBar and call repaint on 'center'
I am adding lots of components (JPanels, JLabels etc.) into a JScrollPane programagically at the start of my program based on some stuff from a database.
It seems that this procedure is too fast for the GUI(?), so the JScrollPane does not always update correctly, i.e the scroll bars are not visible even though the inner JPanel is bigger than the visible area.
Resizing the Window (JFrame) fixes the problem, as I assume Java is re-printing the components when they are resized.
As a test, I have added a debug-button that I can click after the startup of the program has finished. I am trying to force the JScrollPane to "refresh" itself.
I have tried doing:
scrollpane.repaint();
scrollpane.validate();
scrollpane.revalidate();
None of them seems to work. However, if I change the border (or any other layout related to the JScrollPane), it refreshes correctly.
scrollpane.setBorder(new LineBorder(Color.RED));
So I basically have 2 questions.
What is the command for forcing the scrollpane to "refresh"? Obviously it is doing some kind of "repaint" thing when I am adding the border. How can I run that only?
Is there a way of "pausing" the printing of components as they are added and resume it again after I added all the wanted components? As it is now, I basically "see" the components being added on the screen (even though it is really fast). It would be better if I can add all the components I want and THEN tell the program to print it to the screen/JFrame.
The basic code for adding components to a visible panel is:
panel.add(...);
panel.add(...);
panel.revalidate();
panel.repaint();
Adding a component does nothing because the component still has a zero size so there is nothing to paint. When you invoke the revalidate() method the layout manager gets invoked so components will now have a location/size. The repaint() will then paint the components. The revalidate() will also cause the scrollbars to show when required. This of course assumes you are using layout managers.
The components are added to the panel so you invoke the methods on the panel, not the scrollpane.
In my case only
frame.pack();
helped to get the scrollbars on the JScrollPane, when the enclosed JPanel was resized dynamically.
I am trying to create a JScrollPane within one of the tabs to my JTabbedPane. I tried what I though would work which was this:
pane.add("Main", mainGame);// These are my other tabs
pane.add("Upgrades", upgradeScreen); //the JTabbedPane
pane.add("Credits", creditsTab);
upgradeScreen.setLayout(null); //The null layout
lblMoney2.setBounds(10, 11, 277, 22);
upgradeScreen.add(lblMoney2); // A simple JLabel
scrollPane.add(upgradeScreen); //my JScrollPane
Where pane is my JTabbedPane and scrollPane is my JScrollPane. This simply got rid of my upgradesScreen tab. I kind of expected this but I did not know what else to do. If more code is needed for you to figure it out, tell me and i'll put it in, otherwise, thanks for the help!
Don't us JScrollPane#add, instead you want to use JScrollPane#setViewportView
Check out How to use ScrollPane more details.
Advise- Don't use null layouts, they limit the ability for your application to run on multiple platforms. Instead take the time to learn how layout managers work
This simply got rid of my upgradesScreen tab.'
yes, because no component can have two parents at once. You added upgradeScreen to JTabbedPane first and then again added it to a JScrollPane. The Component's add(component) function will eventually call the addImpl(component) function: which will remove the component from it's old parent and add it to the new parent.
However:
You need to add the JScrollPane to the JTabbedPane instance.
The component which you wish to scroll set it as a view to JScrollPane using the setViewportView(component) function. for your context it is the upgradeScreen