I am implementing a program for a Component Design course and am currently struggling with what should be simple use of a Jlist. The program draws shapes and should display them in a JList in a ScrollPane in the BorderLayout.West of the frame.
The current program shows the ScrollPane but will not display objects I add to the shapeListModel like it should. I am wondering it I am missing something or if something is flat out wrong with my code. Currently this is all the code that partains to the JList creation, assigning, and updating.
//Class Variable Declaration
protected ArrayList<Shape> shapes = new ArrayList<Shape>();
private JScrollPane shapeScrollPane = new JScrollPane();
private JList<String> shapeList;
protected DefaultListModel<String> shapeListModel;
//Creation of JList objects and what not
shapeListModel = new DefaultListModel<String>();
//This element is added aimply to try and get one to show up on my JList,
shapeListModel.addElement("SERIOUSLY FRUSTRATED");
//It does not just so you know
shapeList = new JList<String>(shapeListModel);
shapeList.setModel(shapeListModel);
//Adding JList to ScrollPane and setting size
shapeScrollPane.add(shapeList);
shapeScrollPane.setPreferredSize(new Dimension(250,600));
//Clarifying JList actions
shapeList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
shapeList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
shapeList.setVisibleRowCount(-1);
shapeList.addListSelectionListener(this);**
//This is called everytime a new shape is created and adds it to the Arraylist
//shapes and the DefaultListModel shapeListModel
shapes.add(newShape);
shapeListModel.addElement(newShape.toString());
I apologize for my poorly formatted question a few moments ago. I have been stuck on this for approximately 4 hours, the last two hours spent searching for answers online. I am now resulting to asking anyone if they see an issue within the code I have.
You don't "add" components a scroll pane. You need to set it's view ports view instead.
Don't do this...
shapeScrollPane.add(shapeList);
Do this...
shapeScrollPane.setViewportView(shapeList);
Check out
How to use Scroll Panes
JScrollPane#setViewportView
Also, this shapeList.setVisibleRowCount(-1) scares me to no end.
Updated
You also don't need to this...
shapeList = new JList<String>(shapeListModel);
shapeList.setModel(shapeListModel);
This is more then sufficient...
shapeList = new JList<String>(shapeListModel);
Updated
Also, if this is the same code that was used in a previously closed question...
This canvas.getGraphics() terrifies me!! If your instructor gave you this code, then they shouldn't be teaching you!
Related
I am developing an application in Netbeans using Java and have been told to use the GUI creation features that Netbeans offer. Due to this I cannot edit the initComponents(); method to edit the creation of the JList and add a default list model to it.
I have tried creating a new JList but that resulted in an infinite loop. I haven't ever created controls through coding them myself, only by an IDE's GUI creation tools.
This is what I have currently:
private void formWindowActivated(java.awt.event.WindowEvent evt) {
//String to hold current patients data
String patientDetails;
//Take the arraylist from the model
ArrayList<IAccountStrategy> unapprovedPatients;
unapprovedPatients = model.getObservers();
//Create default list model to store the patients details
DefaultListModel<String> unapprovedPatientModel = new DefaultListModel<>();
IAccountStrategy xx;
//For loop to iterate through each element of unapprovedPatients
for(int i = 0; i < unapprovedPatients.size(); i++){
//get the current patients details and store them in a string variable
xx = unapprovedPatients.get(i);
patientDetails = xx.getAccountID() + xx.getUsername() + xx.getFirstname() + xx.getLastname();
//Add string variable to list model
unapprovedPatientModel.addElement(patientDetails);
}
//add list model to existing JList
listPatients.addElement(unapprovedPatientModel);
}
I would like to output all the elements from the list model into the actual JList and then let the user interact with the list itself.
Thanks in advance!
is it not possible to use the list as I want
You just wrote code to create the DefaultListModel.
So now all you need is to add:
list.setModel( unapprovedPatientModel );
so the JList can use the newly created model.
Although the problem with this code is that the code will be executed every time the window is activated.
But the point is that all you need to do is update the list using the setModel() method. How you do this in the IDE is up to you.
I have googled on this and there is nothing on the internet similar to what I'm trying to do. I'm actually now thinking if I'm tackling this issue in the right way as I have spent so much of time to resolve it.
Here is what I'm trying to do. I have a JFrame on which I have a JTabbedMenu assigned to the left of the frame. When I click on the menu item it displays the relevant JPanel on the right.
To create the tabs on the left hand menu, I loop through a HashMap like this:
for (Entry<String, AbstractBasePanelView> menu : menuItems.entrySet()) {
addTab(menu.getKey(), menu.getValue());
}
the menuItems HashMap is constructed like this:
for (Menu menu : Menu.values()) {
menuItems.put(menu.getName(), Menu.lookup(menu.getName()).getInstance());
}
where Menu is an Enum class and the getInstance() method returns a new instance of the class extending the AbstractBasePanelView. The AbstractBasePanelView class extends JPanel.
Now my question is how can I add JScrollPane to each panel on the right. So that it displays a vertical scrollbar only for the JPanel where elements of that Panel stretch beyond the dimension of the JFrame.
I thought I could do something like this when I create my tabs:
JScrollPane[] scrollPane = new JScrollPane[menuItems.size()];
int i = 0;
for (Entry<String, AbstractBasePanelView> menu : menuItems.entrySet()) {
scrollPane[i].getViewport().add(menu.getValue());
addTab(menu.getKey(), scrollPane[i]);
++i;
}
But I get a runtime exception as soon as I run my application:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
The exception is thrown on the line when I add the JPanel: scrollPane[i].getViewport().add(menu.getValue());
when I don't use an array of JScrollPane, I don't get any NullPointerException.
The below works fine but doesn't solve my purpose because the left menu appears fine but the JPanels are all empty.
for (Entry<String, AbstractBasePanelView> menu : menuItems.entrySet()) {
JScrollPane scrollPane = new JScrollPane();
scrollPane.getViewport().add(menu.getValue());
addTab(menu.getKey(), scrollPane);
}
Any idea what I'm doing wrong here and how I can resolve it? A code snippet would be highly appreciated.
I'm having difficulty changing unselected options in a JList table to set them to setEnable(false). The method that is receiving the values is an ActionListener button method that, once pressed, receives the selected values from the JList. Here is the method and the buildEnemySelectionPanel() method is creating the JList with the appropriate JPanel for later placement:
private String[] enemies = {"Goblin", "Skeleton"};
private void buildEnemySelectionPanel()
{
enemyPanel = new JPanel();
enemyListPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
enemyListPanel.setPreferredSize(new Dimension(180, 85));
enemyListPanel.setBackground(Color.WHITE);
enemyPanel.setLayout(new BoxLayout(enemyPanel, BoxLayout.Y_AXIS));
enemyList = new JList(enemies);
enemyList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
enemyList.addListSelectionListener(new EnemyListListener());
enemyListPanel.add(enemyList);
enemyPanel.add(enemyListPanel);
}
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("Select Enemy"))
{
indexEnemy = enemyList.getSelectedIndex();
indexEnemyWeapon = weaponList.getSelectedIndex();
/*
here is where I'm having problems
*/
}
}
So far I've tried to take all of the items from the JList and, matching them with the references from the original String[] list items that I sent to the JList, parsed the indexes and if they didn't match set to false. Unfortunately as you are all probably well aware, compilation errors came up as result due to the fact that the JList is not actually a list. Here is a sample of my for loop that I tried to use in my method above:
for(int x = 1; x < enemyList.length(); x++)
{
if (!(enemies[x] == indexEnemy))
{
enemyList[x].setEnable(false);
}
}
I've read the http://docs.oracle.com/javase/8/docs/api/ , (tried to link 'setEnable') among some examples but don't seem to be making the connection.
Ideally, what I wish to happen is that when the ActionEvent of my button is triggered, all non-selected options in my JList will be disabled. I understand that the end-user will still be able to change his/her mind and make a different selection. But I'd like to still receive some help on how I can set the non-selected items in my JList to false if they are not the indexEnemy from my method above.
I have the following class ReviewPanel in which i have created a JList and trying to populate it with Vector passed to it. the vector already has its values filled but when i add it to JList it doesn't shows anything.
following is my class
public class ReviewPanel extends JPanel
{
private Vector bookList;
private JList jl;
private JRadioButton poor,fair,avg,good,exlnt;
private JButton jb;
public ReviewPanel(Vector bookList)
{
this.bookList = bookList;
jl = new JList<String>(this.bookList);
String tmp=null;
for(int i=0;i<bookList.size();i++){
tmp = tmp + bookList.get(i) + "\n";
System.out.println(tmp); //here it is showing the values in booklist vector
}
add(jl);
ButtonGroup bg =new ButtonGroup();
poor = new JRadioButton("1 Poor");
fair = new JRadioButton("2 Fair");
avg = new JRadioButton("3 Average");
good = new JRadioButton("4 Good");
exlnt = new JRadioButton("5 Excellent");
bg.add(poor);
bg.add(fair);
bg.add(avg);
bg.add(good);
bg.add(exlnt);
add(poor);
add(fair);
add(avg);
add(good);
add(exlnt);
jb = new JButton("Submit Review");
add(jb);
}
//more code
}
below is the pic for what it looks like. even though i have added the Jlist already. it doesn't show anything
not savvy to jlist and vectors, any help appreciated.
In the past I have had simular issues with the FlowLayout, which is the default layout for a JPanel.
It sometimes does not show one of the items added (in my case it was often the last).
You can test if the use of your layout manager is your problem by starting you function with setLayoutManager(null). This turns is off, which will place the elements on their default locations and sizes. If the JList does show this is your problem.
A very good example for your program is the Button Demo. This also shows the use of SwingUtils to make sure you create your program on the 'Event Dispatch Thread', which is required for all interaction with Swing objects.
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.