I have an issue in my Java application where putting a JList inside a JScrollPane seems to disrupt the first drawing of the list items.
I have a list being populated with items
public void populateFormulaList(Iterator<String> iter)
{
list.setModel(new DefaultListModel<String>());
DefaultListModel<String> listModel = (DefaultListModel<String>) list.getModel();
while (iter.hasNext())
{
listModel.addElement(iter.next());
}
}
And the component initialization looks like this
list = new JList<String>();
list.setFont(new Font("Tahoma", Font.PLAIN, 14));
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
listPanel = new JScrollPane(list);
listPanel.setBounds(0, 40, 375, 550);
add(listPanel);
My problem is that when the application first runs, the list is populated with items, which I've debugged within eclipse and know the items exist within the JLists model, but if the JList is in the JScrollPane the items do not show the first time around. If I force the items to be repopulated the list shows all the items as expected.
I've tried using repaint() and revalidate() on the scrollpane, JList and their containing frame.
Any help would be greatly appreciated.
Related
I'm creating a list of bank movements with the following code. pane is a JPanel and array is an ArrayList that contains respectively amount and description data. Setting is a little icon that allow you to modify each movement.
MouseClass is a class that extends MouseAdapter that I've created to add "k" index to mouseClicked method. I'm new with java gui programming. I'd like to know if there is a quick method to add a scroll to my panel
JLabel[] movement = new JLabel[array.size()];
JLabel[] description = new JLabel[array.size()];
JLabel[] data = new JLabel[array.size()];
JLabel[] setting = new JLabel[array.size()];
System.out.println(array.size());
int i = 0;
for(int k=0; k<array.size(); k++){
movement[k] = new JLabel("");
movement[k].setForeground(SystemColor.text);
movement[k].setFont(new Font("Segoe UI", Font.PLAIN, 20));
movement[k].setBounds(17, i, 145, 30);
movement[k].setText(array.get(array.size() - k - 1).getAmount() + "€");
panel.add(movement[k]);
description[k] = new JLabel("");
description[k].setForeground(SystemColor.text);
description[k].setFont(new Font("Segoe UI", Font.PLAIN, 20));
description[k].setBounds(187, i, 274, 30);
description[k].setText(array.get(array.size() - k - 1).getDescription());
panel.add(description[k]);
data[k] = new JLabel("");
data[k].setForeground(SystemColor.text);
data[k].setFont(new Font("Segoe UI", Font.PLAIN, 20));
data[k].setBounds(478, i, 145, 30);
data[k].setText(array.get(array.size() - k - 1).getDate());
panel.add(data[k]);
setting[k] = new JLabel();
setting[k].setIcon(new ImageIcon(List.class.getResource("/it/andreavaiuso/financemanager/images/edit.png")));
setting[k].setForeground(SystemColor.text);
setting[k].setFont(new Font("Segoe UI", Font.PLAIN, 20));
setting[k].addMouseListener(new MouseClass(array.size() - k - 1) {
#Override
public void mouseClicked(MouseEvent arg0) {
Modify mdf = new Modify(this.index);
mdf.setVisible(true);
dispose();
}
});
setting[k].setBounds(640, i, 82, 30);
panel.add(setting[k]);
i += 40;
}
But I don't know how to scroll it. I've tried woth JScrollPane but don't work!
I'm sure there is a simplest way to add these items to my panel...
I've tried woth JScrollPane but don't work!
Well I see lots of code with setBounds(...) which implies you are using a null layout.
Don't use a null layout. Swing was designed to be used with layout managers. In fact the scroll pane will only work when used with a layout manager because the scroll pane needs to know the preferred size of the panel so it can determine when you use scrollbars.
I would also suggest you should also be using a JTable for something like this. It is more efficient because you don't need to create individual components for each row of data. Read the section from the Swing tutorial on How to Use Tables for more information and examples.
For a JScrollPane you need, 1 JScrollPane, 1 JList and one DefaultListModel.
First you add your items to DefaultListModel, then you add the model to the JList and then you make a JSCrollPane with passing as argument your JList
Example:
DefaultListModel model = new DefaultListModel<String>();
JList list = new JList<String>();
model.addElemenet("1");
model.addElemenet("3");
model.addElemenet("2");
list.setModel(model);
JScrollPane scrollPane = new JScrollPane(list);
I'm pretty new to Javas swings, so sorry if this is something trivial. This is the constructor, I excluded unnecessary form items. (I tried running the code as short as this, but the problem still appears)
//This just opens a connection to MySQL server, this doesn't create any problems.
bp = BazaPodataka.getBaza();
//Forming the main frame..
JFrame frame = new JFrame();
{
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setBounds(d.width/2 - sirina/2, d.height/2 - visina/2, sirina, visina);
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout(0, 0));
//Adding a layered pane so I can place items inside the form more 'freely'
JLayeredPane layeredPane = new JLayeredPane();
frame.getContentPane().add(layeredPane, BorderLayout.CENTER);
//Adding a table
JTable table = new JTable();
String[] rowData = {"Name:", "Price:", "Cathegory:", "Sum:"};
DefaultTableModel model = new DefaultTableModel(rowData, 0);
JScrollPane skrol = new JScrollPane(table);
table.setModel(model);
//The 2 lines below work as intended
ResultSet rs = (ResultSet) bp.query("SELECT * FROM table"); //This calls a query
popuniTabelu(rs, model); //This populates the table.
table.setBounds(10, 110, 500, 350);
table.setEnabled(false);
table.setShowHorizontalLines(false);
layeredPane.add(table);
Populating the table and displaying it isn't the problem, there's enough information inside the table 'table' that the user even needs to scroll down.
But that's where the problem begins, the scroll doesn't show up. How do I implement it from here. I tried following solutions I found on google, but they pretty much sum up on:
JScrollPane scroll = new JScrollPane(table);
Which simply doesn't work in my case.
The problem may be trivial, if it is, I'm sorry, I'm still learning swing. Also, sorry for my bad english, it's not my native language. :)
Also, if there's something I forgot to include, please let me know.
Thank you!
You add your table to 2 components :
JScrollPane skrol = new JScrollPane(table);
and
layeredPane.add(table);
Because of Swing component can have just one parent component second statment override first, so your JScrollPane is empty. Seems you need to remove layeredPane.add(table);
As mentioned here
Each GUI component can be contained only once. If a component is already in a container and you try to add it to another container, the component will be removed from the first container and then added to the second.
I used windowbuilder to create a GUI that should be a contact list. There are two lists: one of contacts, the other one of numbers. when you select a contact his number will appear.
But, when I add a lot of contacts, the scroll bar does not automatically appear, as it does to my friend, so I tried adding a JScrollPane. Still does not work.
Here is what it was:
DefaultListModel contact = new DefaultListModel();
JList contacts = new JList(contact);
contacts.setBounds(22, 64, 186, 135);
contentPane.add(contacts);
here is what I tried:
DefaultListModel contact = new DefaultListModel();
JList contacts = new JList(contact);
contacts.setBounds(22, 64, 186, 135);
JScrollPane scrollPane1 = new JScrollPane(contacts);
contentPane.add(contacts);
contentPane.add(scrollPane1, BorderLayout.WEST);
then I tried addind Bounds to the scrollPanel as well:
DefaultListModel contact = new DefaultListModel();
JList contacts = new JList(contact);
contacts.setBounds(22, 64, 186, 135);
JScrollPane scrollPane1 = new JScrollPane(contacts);
scrollPane1.setBounds(22, 64, 186, 135);
contentPane.add(contacts);
contentPane.add(scrollPane1, BorderLayout.WEST);
when I erased 'contacts.setBounds(22, 64, 186, 135);', the list stopped working.
I also tried not having the last line, I tried only having the last line and not having the second last line, I tried adding "scrollPane1.setViewportView(contacts);", I tried taking away the "BorderLayout.WEST" argument for all the other tries, so I basically tried every combination of "solutions" I could find on the internet
I have no idea what is going on and I have no idea how to fix it. All I want is to be able to see all my contacts by scrolling.
EDIT, SOLVED:
The problem was my panel was declared as contentPane.setLayout(null); therefore "BorderLayout.WEST" was unnecessary. In addition, the bounds should be applied to the scrollpane, not the list. Last, I should not have used add(contacts) to the panel. the solution was:
DefaultListModel contact = new DefaultListModel();
JList contacts = new JList(contact);
JScrollPane scrollPaneContact = new JScrollPane(contacts);
scrollPaneContact.setBounds(22, 64, 186, 135);
contentPane.add(scrollPaneContact);
I'm updating in case anyone have a similar problem.
You need to set the policies for JScrollPane using proper constructor.
JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
Creates a JScrollPane that displays the view component in a viewport whose view position can be controlled with a pair of scrollbars.
For instance:
new JScrollPane(COMPONENT, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
EDIT:
DefaultListModel model = new DefaultListModel();
JList contactsList = new JList(model);
JScrollPane scrollPane1 = new JScrollPane(contactsList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
JScrollPane scrollPane1 = new JScrollPane(contacts);
//contentPane.add(contacts); // get rid of this
contentPane.add(scrollPane1, BorderLayout.WEST);
First you add the contacts JList to the viewport of the scroll pane which is correct.
But then you add the contacts to the frame directly, which is wrong. A component can only have a single parent. By adding the contact JList to the frame you remove it from the scroll pane.
Also, don't use a null layout and don't use setBounds(...). Swing was designed to be used with Layout Managers.
If you need more help then post a proper SSCCE that demonstrates the problem. A SSCCE should be included with every question.
I am developing the Exam Registration System with MVC in java.I can add comboBox into big JPanel.However,when I push the JComboBox button , there is no element in the combobox.I can not solve this. ComboBox addition to my view is here ;
JPanel panel = new JPanel();
panel.setBounds(425, 494, 117, 39);
adminPanel.add(panel);
panel.setLayout(null);
panel.setVisible(true);
comboBox = new JComboBox();
comboBox.setBounds(0, 0, 117, 39);
panel.add(comboBox);
and ı try to add exams in here ;
admin_view.getComboBox().setVisible(true);
String s = "Exam1";
admin_view.getComboBox().addItem(s);
How can I show the elements into JComboBox. No action , no other things I just want to show elements.
admin_view.getComboBox().setVisible(true);
String s = "Exam1";
admin_view.getComboBox().addItem(s);
The problem is; you try to add an element to an already visible object. So if you add an element, you have to refresh the component/panel to see updated version of that component/panel. And if the elements don't have to be added dynamically, just add those elements before you make that combobox visible.
I have the following code:
JList<Song> list = new JList<Song>(this.lib);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setLayoutOrientation(JList.VERTICAL);
list.setVisibleRowCount(3);
list.setSize(1, 1);
JScrollPane listScroller = new JScrollPane();
listScroller.setViewportView(list);
list.setSize(10, 10);
setLayout(new FlowLayout(FlowLayout.LEFT,10,10));
add(list);
I am not sure what is wrong here. When I look at the JFrame, I see the list in a single box with all 9 items that I have in my list. I tried messing with the size to see if I could get that to work but it isn't. The size doesn't seem to change no matter what I set it to.
My goal is to have a vertical and horizontal scroll-bar when necessary and a JList that is of some fixed size (fixed compared to the frame size would be best if possible).
You're adding the list to the container, not the listScroller.
JScrollPane listScroller = new JScrollPane();
listScroller.setViewportView(list);
list.setSize(10, 10);
setLayout(new FlowLayout(FlowLayout.LEFT,10,10));
add(list);
You should try using something like...
JScrollPane listScroller = new JScrollPane();
listScroller.setViewportView(list);
setLayout(new FlowLayout(FlowLayout.LEFT,10,10));
//add(list);
add(listScroller);
I think you will also find list.setSize(10, 10); is pointless, as the JScrollPane (actually the viewport, but lets keep it simple) has it's own layout manager.
You should take a look at Jlist#setVisibleRowCount if you want to affect the number of visible rows a JList will show before it needs to be scrolled.
The actual width and height of each row is determined by the ListCellRenderer, but you can use JList#setPrototypeCellValue to affect how these might be calculated.