JList and JScrollPane don't respond/are inaccessible - java

I am trying to implement a basic GUI where a user can move objects from one JList to another. The JLists should be contained within a ScrollPane so size is not an issue. Basic functionality is good, items will move and remove with button presses. However, the JList and JScrollPane that items are added to will display correctly and detect if a ScrollBar is necessary but do not interact AT ALL with the user for some reason. The user cannot select from the JList nor scroll the ScrollPane. Rough idea of the code below;
public void createJList(Type[] dataToList){
someScrollPane = new JScrollPane(); //someScrollPane is private global
someScrollPane.setBounds(numbers here);
this.add(someScrollPane); //this is a custom frame class
aList = new JList<Type>(dataToList);
someScrollPane.setViewportView(aList);
This is a rough idea. I also add a listener at some stage but since the scrollpane isn't working either I may as well leave that for later. I use this code for both the working and non-responsive JLists and ScrollPanes exactly the same.
Of note, I call this method everytime the list I want to display is changed. I'm thinking maybe because the JList and ScrollPane keep getting created, something is broken?

Related

GridBagLayout readd components

I created an ArrayList of JLabels of size n and placed the JLabels inside an JInternalFrame with the help of a GridBagLayout manager so that the grid fits my purpose.
Now I want to replace some of those JLabels or even remove them.
Removing the k-th JLabel does work well with
innerframe.remove( ListOfLabels.get(k) );
ListOfLabels.remove(k);
(By the way if I'm using only one of those the JLabel is not removed from the internal frame -- why ? If I remove other objects like Checkboxes, it sufficies to use only innerframe.remove(ListOfCBoxes.get(k));)
Even the other JLabels stay at their position, what did not work, when I placed the JLabels inside the surrounding JFrame.
But I'm not able to readd a JLabel after editing it's content. I'm trying
//Initialization
ArrayList<JLabel> ListOfLabels = new ArrayList<JLabel>(n);
GridBagLayout GridBLayout_innerframe = new GridBagLayout();
GridBagConstraints GridBConstraints_innerframe = new GridBagConstraints();
JInternalFrame innerframe = new JInternalFrame();
innerframe.setLayout(GridBLayout_innerframe);
// Creating components of innerframe, arranging them in a grid and adding them.
// This seems to work.
innerframe.remove( ListOfLabels.get(k) );
ListOfLabels.remove(k);
labelk = new JLabel("New content");
ListOfLabels.add(labelk);
GridBConstraints_innerframe.gridy = k ;
GridBLayout_innerframe.setConstraints(ListOfLabels.get(n-1), GridBConstraints_innerframe) ;
innerframe.add(ListOfLabels.get(n-1)) ;
Of course the same constraints were used for the k-th JLabel before and I did not
erase this information. I hoped I can overwrite it.
However the result is that the JLabels that I removed stay removed and the ones I want to
add do not appear. Even after ''refreshing'' the window. There is also no error message from Eclipse.
Can someone please find my mistake and explain how to readd components into a hopefully already existing grid :/
You are removing the JLabel without saying the Component that you did this. You need to call the revalidate() method just after adding/removing a Component when it's already visible.
So, in case innerframe is visible and you called innerframe.remove(...), you need to call:
innerframe.revalaidate();
Then innerframe notices that Components where added or removed and re-assigns the Components that are now in the Component (calling the LayoutManager, repainting, ...).
It's a bad idea to remove/add components in a complex layout. In such cases I would provide a full relayout: clear the container (use the method removeAll()) and add all the required components again. Of course you must call revalidate() and repaint() for the top changed container.

How do I create a JScrollPane within a JTabbedPane?

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

How to keep a swing component updated

One of my classes is returning a JPanel which is added on a JFrame by some other class.
The JPanel contains a JTree and some buttons. On some events the panel is created again and returned to the JFrame.
My problem is that I have to add the JPanel to the Container of the JFrame again and then resize the frame for changes to be visible. I can't figure how to have the frame update without resizing.I tried removing old objects and adding updated ones but still doesn't work.
What is the best way to deal with this issue? Ideally I would have a reference to the JPanel and when the JPanel is changed, the frame will also be updated.
The whole model is changing not just its data. I will probably change this in the future but for now when data change a new JTree is created
Then your code should be something like:
JTree tree = new JTree( theNewModel );
scrollPane.setViewportView( tree );
That is you need to add the new JTree to the GUI, you can't just change the reference to the tree variable.
Or even easier, you don't need to create a new JTree, just replace the model in the existing tree using:
tree.setModel( theNewModel );
If this still doesn't help then you need to post your SSCCE that demonstrates the problem because your question still isn't clear.
try JFrame.invalidate() first, then call JFrame.validate()
http://docs.oracle.com/javase/6/docs/api/java/awt/Container.html#invalidate%28%29

Dynamic fields addition in java/swing form

I'm pretty new to java, and using netbeans for design a UI.
What I am trying to do is...
in the form. there are a jComboBox and a JTextField, where user can input the service he is choosing and an observation. So far so good. JComboBox is populated from database entries.
The problem is, a user can input N different services at once (there are too much to be a bunch of checkboxes). I was thinking into add a "[+]" button (along with a "[-]" for removal). Thus, users click on [+] and another new line with a jcombobox + jtextfield appear right below the previous ones.
I'm stucked at this point. On [+] button ActionPerformed I just can't clone and add previous nodes. Any idea on how proceed.
My background is webdev. Doing this with javascript would be really quick. Well, I think you already know what I'm trying to do. Waiting for some light. Thx.
You're on the right track. Here's some source code to give you some ideas
The basic idea is that the EntryList is responsible for keeping track of the rows to display; each row has a plus/minus button, and then delegates out the actual adding/removing to this EntryList. It also exposes methods to disable the minus/plus button so that the list view can ensure that you don't remove a single entry (so that you don't have an empty display)
This doesn't work perfectly; you'll notice you need to resize the frame to get the new rows to show up correctly. But this should be enough to get you started.
Create your main panel to use a layout manager that displays component horizontally. The Box class is easy to use for this. Then you just create a new panel with the components you want to display and add this panel to your main panel. Something like:
JComboBox checkBox = new JComboBox(...);
JTextField textField = new JTextField(...);
JPanel row = new JPanel();
row.add( comboBox );
row.add( textfield );
mainPanel.add( row );
mainPanel.revalidate();

Java Swing Scrollpane in NetBeans

I have Java application which adds JTextFields # runtime to JPanel. Basically user clicks a button and new JTextField is added, clicks again added again...
Each new JTextField is directly below the previous one. Obviously I run out of space pretty soon so I'm trying to use JScrollPane and thats where the hell begins, because it just doesnt work no matter what I try.
Right click on JPanel and Enclose in Scroll Pane. Didnt work.
After reading some examples I realized I must have JPanel as an argument for JScrollPane constructor. Which I did via right clicking on ScrollPane and CustomizeCode. Because apparently auto-generated code is protected in NetBeans and I cannot just change all those declarations, etc. manually. Still doesnt work.
I did try to set PreferedSize to null for JPanel and/or JScrollPane, didnt help.
JScrollPane is a child of lets call it TabJPanel (which in turn is a tab of TabbedPane). I tried to mess with their relationships, basically trying every possible way of parentship between JFrame, JPanel(holding textfields), TabJPanel and JScrollPane, but nothing worked.
I also made VerticalScrollBar "always visible" just in a case. So I see the scrollbar, it's just that populating that JPanel with JTextFields does not affect it.
When there are too many JTextFields I they go "below" the bottom border of JPanel and I cannot see them anymore.
Code for adding new JTextFields is like this, in a case it's relevant.
JTextField newField = new JTextField( columns );
Rectangle coordinates = previousTextField.getBounds();
newField.setBounds(coordinates.x , coordinates.y + 50, coordinates.width, coordinates.height);
JPanel.add(newField);
JPanel.revalidate();
JPanel.repaint();
Sorry for a long post I'm just trying to provide as much info as possible, because being newbie I dont know whats exactly relevant and whats not. Thanks in advance :)
As there is another answer now, I'm adding my suggestion too.
This sounds exactly like a problem to use a JTable with a single column. JList is not yet editable (and might never be).
JTable would handle the layout problems for you, and you can easily access the values via the table.
Use your own TableModel (a simple Vector should be sufficient in your case), and add values to it.
An option you have is to utilize a LayoutManager, instead of setting the bounds directly on the components. To test this, a simple single column GridLayout with the alignment set to vertical should prove the concept.
panel.setLayout(new GridLayout(0,1));
zero in the rows param allows for rows to be added to the layout as needed.
I do this way to add a scrollpane, create a panel and fill it with few components, then create a scrollpane in the component you want to add it, cut and paste the panel in which all your details will fall in and resize the scrollpane.Because the components take a larger space than the one visible right click on the scrollpane and select design this container, there you can increase the size of the scrollpane and add as many components as you have.

Categories