I have a JList, wich must display more than 3000 items. I wish to have "visible" around 100 items in the list, and when you scroll and getting close to the end (or begining) of the "visible" items the next portion (around 50) must be loaded in the list. Is there any simple way of doing this?
The list is rendering only the visible part. So there is no overhead from this point of view. If you want lazy loading - use custom models.
From this page :
You can write your own class that extends AbstractListModel or AbstractTableModel so that you can provide the needed data when necessary. The following example shows the usage of AbstractTableModel.
no there are no simple way for that, you have to implements Pagination(s)
easiest job when is managed by Databases engine, most of then support paginations directly
in the Model, but I never seen workaround for XxxListModel, use JTable with one Colum instead, there are some good workaround for Pagination for JTable
I have a JList, wich must display more than 3000 items.
Huh. You make that sound like a big number. Here is a list holding (and displaying just fine), more than 30 thousand items.
import javax.swing.*;
class BigList {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
int bigNumber = 30001;
String[] bigData = new String[bigNumber];
for (int ii=0; ii<bigNumber; ii++) {
bigData[ii] = "String " + (ii+1);
}
JList list = new JList(bigData);
list.setVisibleRowCount(5);
JOptionPane.showMessageDialog(null, new JScrollPane(list));
}
});
}
}
Related
I have a main class where the UI is located and that it instantiates another class, where the logic is located. I create the instance of the logic only when a button is clicked.
private void computeActionPerformed(java.awt.event.ActionEvent evt) {
//A STAR MISPLACED
EightPuzzle ep2 = new EightPuzzle(stringToInt(initial),"mis");
solution = ep2.getSolution();
aMisplacedSpace.setText(ep2.getNodesTraversed()+" nodes"); // I would like to display this during the search and not just after
setCurrentTilesAStarMisplaced(solution.size()-1);
}
The problem is that I have to display the number of nodes traversed during a particular instance into some JLabel in the UI. I guess my current structure does not allow me to do so. Is there a work around on this?
I'm not sure how to ask this question, and I'm certain that there's some kind of other solution to the problem I'm having so if anyone can point me in the right direction, I'd appreciate it.
In any case, the issue I'm having is that I have a String[] list (called "projects") that I'm using to populate a combo box. I want to use the selection from the combo box to dynamically change the form fields listed in a GUI panel.
My approach, so far, isn't dynamic enough because I will have nearly 100 possible selections from the combo box when I'm done. So far, I've been testing with 3 options in the box, but scaling it up to 100 will involve a lot of code, and I think there MUST be some other solution, right? I just don't know what that solution is.
String[] projects = {"Select a project...", "Option1", "Option2", "Option3"};
String[] Option1= {"phone", "maxphv"};
String[] Option2= {"address1", "address2", "house", "predir", "street", "strtype", "postdir", "apttype", "aptnbr"
, "city", "state", "zip"};
String[] Option3= {"phone"};
ArrayList<String> fieldslist, fieldslbllist;
Ideally, I'd like to take the name of the project selected from the projects String[] combo box and reference that name as the name of another list that contains the fields I want to display in the panel.
But I gather from reading on other questions that the name of a variable is irrelevant once the code is compiled.
At this point, I have a set of code to clear the panel and dynamically select the fields, but I still have to manually code the replacement for each of the 100 options. That's not terrible, I suppose, but I think that there is probably a better way that I am unaware of.
public void resetFields() {
fieldslist.clear();
fieldslbllist.clear();
}
public void setFields() {
if (project.getSelectedIndex() == 0) {
resetFields();
}
else if (project.getSelectedIndex() == 1) {
resetFields();
for (int i = 0; i <= Option1.length; i++) {
fieldslist.add(Option1[i]);
fieldslbllist.add(Option1[i]+"lbl");
}
}
else if (project.getSelectedIndex() == 2) {
resetFields();
for (int i = 0; i <= Option2.length; i++) {
fieldslist.add(Option2[i]);
fieldslbllist.add(Option2[i]+"lbl");
}
}
//... onward to 100
The above is just a loop that resets the display on selection of a new option in the combo box and then loops through the options in the OptionX String[] list and adds the values to the fields Array.
Is this a viable way to handle dynamic UI coding? And, is there any way to set it up so I will only have to specify which fields belong to each value and then not have to code a section for each possible project.getSelectedIndex() value in setFields()?
Use CardLayout, seen here, to change the form dynamically. Given the large number of alternatives, look for a hierarchical breakdown among the choices that might allow you to use two related controls, as shown here.
I have JList that grows in size along with the JFrame. I have the following code:
defaultListModel = new DefaultListModel<SData>();
for (String string: listOfStrings) {
defaultListModel.addElement(string);
}
jList = new JList<String>(defaultListModel);
jList.setCellRenderer(jListCellRenderer);
jList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent arg0) {
//codes to go
}
});
jList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
jList.setLayoutOrientation(JList.VERTICAL_WRAP);
scrollPane = new JScrollPane(jList);
If I set some value for setVisibleRowCount method, the row number becomes fixed and If I don't set value, default value of 8 comes to play. I want to have this value dynamically changing.
I just found that jList.setVisibleRowCount(0) makes it self adjustable, when resizing JList.
Echoing #kleopatras's comment, it's not clear what controls setVisibleRowCount(). This example grows the enclosing Window as rows are added, up to a predefined limit, then the scrollbar takes over. It might give you some ideas, or you can use it as the basis of your sscce as #Andrew suggests.
Addendum: If the size of JList will control the count, I'd start with half of the model's size(). Then add one visible row for every n added to the model, in a fixed ratio that is pinned to a predefined limit. To maintain a reliable count, you'll have to implement your own ListModel or override the mutators in DefaultListModel.
I am using LWUIT for getting a search facility for selection in the List.
Now I want to know how can I display the list with CheckBoxes?
list=new List(vector);
cform.addComponent(list);
cform.addComponent(t);
cform.show();
I don't know if there is a more simple solution then mine, but mine is highly customizable and can serve for a lot of purposes.
List l = new List;
Vector v = new Vector();
for(int i = 0; i < 10; ++i){
v.addElement(new CheckItem("itemtekst"));
}
l.setListCellRenderer(new CheckItemRenderer());
l.setModel(new CheckItemModel(v));
the code above makes it work. As you can guess you have to make a new class and override two to make it work.
CHECKITEM: this class has a string and an image. as well as setters and getters. it also has a boolean that shows if it is checked or not.
CHECKITEMRENDERER: has a label for the string and the image of the checkitem it extends Container and implements ListCellRenderer
CHECKITEMMODEL: this extends the defaultlistmodel. it has methods to get the checkeditems and setthem checked or unchecked.
to recap:
set the correct items in the vector
set the correct renderer
set the correct model
and to use it add an actionlistener or it will al be for nothing.
There is a jbutton in my Jpanel. When I clicked it, it loads up my Jtable, sometimes a query return so many records (500 rows). So I want to restrict it to 5 records.
When query return I want to count it; if it's higher than 5 then Jtable shows up only first 5 record, when user click Forward button it will shows up next 5 record. When user click Back button it will show previous 5 record.
How can I do this? Is there any example for this with TableModel?
I suggest implementing a "Paged" TableModel which provides a window onto the entire dataset and methods for moving forwards and backwards throughout the data. This way you do not require two Lists to store the data but rather a single List holding all data along with a marker to your current position; e.g.
public class ImmutablePagedTableModel extends AbstractTableModel {
private final List<MyBusinessObject> allData;
private final int pageSize;
private int pos;
public ImmutablePagedTableModel(List<MyBusinessObject> allData) {
// Copy construct internal list. Use ArrayList for random access look-up efficiency.
this.allData = new ArrayList<MyBusinessObject>(allData);
}
/**
* Returns true if the model has another page of data or false otherwise.
*/
public boolean hasNextPage() {
return pos + pageSize < allData.size();
}
/**
* Flips to the next page of data available.
*/
public void nextPage() {
if (hasNextPage()) {
pos += pageSize;
// All data in the table has effectively "changed", so fire an event
// causing the JTable to repaint.
fireTableDataChanged();
} else {
throw new IndexOutOfBoundsException();
}
}
public int getRowcount() {
return Math.min(pageSize, allData.size() - pos);
}
// TODO: Implement hasPreviousPage(), previousPage();
}
As 00rush mentions a more ambitious approach would be to use a SwingWorker to stream in the data in the background. You could still use the paged TableModel approach for this; you'd just need to ensure that appropriate TableModelEvents are fired as you append to the end of the allData list.
If you wish to load a large table, you may want to use a SwingWorker (details here) thread to load the table in the background. Loading a table with 500 rows should not be a problem. You can then put the data into a suitable object format and pass it to your TableModel.
If you decide to use a List for example, in your table model you could have two lists:
List allData
List viewData
int startIndex
The viewData list is what is referenced by the getValueAt(..) method in your implementation of the TableModel interface. The viewData list is always a subset (bound by startIndex, of length 5) of allData. When the user clicks "Next", your action listener could call a method on the Table model that increments startIndex by 5 (or whatever). You then regenerate your viewData instance so that it is the appropriate 5 row subset of allData, and call fireTableChanged(). This will be easy if you have extended AbstractTableModel in the first place.
This should be pretty straightforward to implement. I think its better than making a database call every time you want to get the next set of data. IMHO, its better to take a little bit more time upfront to preload the data.