Home > Back-end >  JList not behaving as I expected
JList not behaving as I expected

Time:10-26

I'm practicing with a JList which gets populated with random numbers as the "Add Numbers" button is being clicked, and I have run into a few issues I have not been able to fix.

In the code below, I've placed a button to toggle the visibility state of the list but it turns out it does not work unless the list is visible initially.

Then I've set the list to show 8 rows but only 7 are displayed.

Finally, why is the horizontal scroll pane showing up at all if only 3 decimal places are used so there's enough room at the right?

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class JListTest {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        listFrame myFrame=new listFrame();
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        myFrame.setVisible(true);
    }
}

class listFrame extends JFrame {
    private static DecimalFormat df3 = new DecimalFormat("#.###");
    public listFrame() {
        setTitle("List demo");
        setBounds(400,300,400,300);
        listModel = new DefaultListModel();
        randomNumberList=new JList(listModel);
        //**********************************************************************
        // the number of elements visible in the list turns out to be
        // one less than the specified below
        randomNumberList.setVisibleRowCount(8);
        //**********************************************************************
        randomNumberList.setFixedCellWidth(100);
        JScrollPane scrollPanel=new JScrollPane(randomNumberList);
        //**********************************************************************
        // if this line is uncommented the button fails to make the list visible
        // scrollPanel.setVisible(false);
        //**********************************************************************
        JPanel listPanel=new JPanel();
        listPanel.add(scrollPanel);
        JPanel textPanel=new JPanel();      
        toggle=new JButton("Toggle Visible");
        toggle.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                scrollPanel.setVisible(!scrollPanel.isVisible());
            }
        });
        textPanel.add(toggle);
        addNumber=new JButton("Add Numbers");
        addNumber.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                double min=0;
                double max=1000;
                double x= Math.random()*(max-min 1) min;
                listModel.addElement(df3.format(x));
                randomNumberList.ensureIndexIsVisible(listModel.getSize()-1);
            }
        });
        textPanel.add(addNumber);
        add(listPanel,BorderLayout.NORTH);
        add(textPanel,BorderLayout.SOUTH);
    }
    private JButton toggle,addNumber;
    private JList randomNumberList;
    private DefaultListModel listModel;
}

UPDATE: here's some code I've mentioned in a comment below where the setVisibleRowCount does work:

import java.awt.BorderLayout;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class JList_ShowMonths {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        JFrame myLFrame=new MonthFrame();
        myLFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
        myLFrame.setVisible(true);
    }
}

class MonthFrame extends JFrame {
    private JList<String> monthList;
    private JPanel listPanel,txtPanel;
    private JLabel selectionLabel;
    public MonthFrame() {
        setTitle("Display the month names");
        setBounds(400,300,400,300);
        String [] months= {"January","February","March","April","May","June",
                "July","August","September","October","November","December"};
        monthList=new JList<String>(months);
        monthList.setVisibleRowCount(4);
        JScrollPane monthScroll=new JScrollPane(monthList);
        listPanel=new JPanel();
        listPanel.add(monthScroll);
        monthList.addListSelectionListener(new ListSelectionListener(){
            public void valueChanged(ListSelectionEvent e) {
                List<String> values=monthList.getSelectedValuesList();
                StringBuilder text=new StringBuilder("Selected month: ");
                for (String element:values) {
                    String word=element;
                    text.append(word);
                    text.append(" ");
                }
                selectionLabel.setText(text.toString());
            }
        });
        txtPanel=new JPanel();
        selectionLabel=new JLabel("Mes seleccionado:");
        txtPanel.add(selectionLabel);
        add(listPanel,BorderLayout.NORTH);
        add(txtPanel,BorderLayout.SOUTH);
    }
}

CodePudding user response:

First the code. Explanations after the code.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;

import java.text.DecimalFormat;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class LstFrame extends JFrame {
    private static DecimalFormat df3 = new DecimalFormat("#.###");

    private JButton toggle, addNumber;
    private JList<Object> randomNumberList;
    private DefaultListModel<Object> listModel;

    public LstFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("List demo");
        listModel = new DefaultListModel<Object>();
        randomNumberList = new JList<>(listModel);
        randomNumberList.setVisibleRowCount(8);
        randomNumberList.setFixedCellWidth(100);
        JScrollPane scrollPanel = new JScrollPane(randomNumberList);
        scrollPanel.setPreferredSize(new Dimension(110, 100));
        scrollPanel.setVisible(false);
        JPanel textPanel = new JPanel();
        toggle = new JButton("Toggle Visible");
        toggle.addActionListener(e -> {
            scrollPanel.setVisible(!scrollPanel.isVisible());
            revalidate();
        });
        textPanel.add(toggle);
        addNumber = new JButton("Add Numbers");
        addNumber.addActionListener(e -> {
            double min = 0;
            double max = 1000;
            double x = Math.random() * (max - min   1)   min;
            listModel.addElement(df3.format(x));
            randomNumberList.ensureIndexIsVisible(listModel.getSize() - 1);
        });
        textPanel.add(addNumber);
        add(scrollPanel, BorderLayout.CENTER);
        add(textPanel, BorderLayout.SOUTH);
        setSize(260, 240);
        setLocationByPlatform(true);
        setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new LstFrame());
    }
}

If a component is initially invisible, it is not painted, nor are the rest of the components painted in such a way as to leave space for the invisible component. Hence, in the above code, I set the size of the JFrame. I simply played around with the numbers until I found suitable values.

Yes, the default layout manager for [the content pane of] JFrame is initially

After pressing Toggle Visibe

list visible

After adding ten [random] numbers – since the preferred height of the JScrollPane is enough to display nine numbers.

scrollbar

CodePudding user response:

Hi you have got answer above so sorry, I think It is easy to read if we have 4 import Statements That is

import java.awt.*;
import java.awt.event.*;
import java.text.*;
import javax.swing.*;

Here (.*) Imports all classes of the Package.

  • Related