This shows you the differences between two versions of the page.
swing:lists [2015/05/10 19:47] gthanos created |
swing:lists [2016/02/26 11:15] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Lists ====== | ||
- | |||
- | Μία λίστα αποτελείται από μία σειρά επιλογών τις οποίες μπορείτε να παραθέσετε σε μία ή περισσότερες γραμμές ή στήλες. Η λίστα υλοποιείται από την κλάση [[http://docs.oracle.com/javase/7/docs/api/javax/swing/JList.html|javax.swing.JList]]. | ||
- | |||
- | Για την δημιουργία μίας λίστας είναι απαραίτητη η δημιουργία ενός αντικειμένου τύπου [[https://docs.oracle.com/javase/8/docs/api/javax/swing/ListModel.html|javax.swing.ListModel]], το οποίο αποθηκεύει τα δεδομένα που θα εμφανιστούν στην λίστα. Η Java παρέχει την default υλοποίηση [[https://docs.oracle.com/javase/8/docs/api/javax/swing/DefaultListModel.html|DefaultListModel]] η οποία είναι ικανοποιητική για την διαχείριση των δεδομένων της λίστας. | ||
- | |||
- | Εκτός από την χρήση ενός αντικειμένου τύπου ListModel, μπορείτε να χρησιμοποιήσετε και έναν πίνακα αντικειμένων ή ένα αντικείμενο τύπου [[http://docs.oracle.com/javase/7/docs/api/java/util/Vector.html|java.util.Vector]] (δείτε τους κατασκευαστές της κλάσης). Σε αυτή την περίπτωση η λίστα των αντικειμένων είναι σταθερή και δεν μπορεί να μεταβληθεί. Η χρήση ενός αντικειμένου τύπου ListModel επιτρέπει την πρόσθεση ή την αφαίρεση επιλογών από την λίστα. | ||
- | |||
- | Κάθε λίστα έχει τις παρακάτω δυνατότητες απεικόνισης. | ||
- | | {{ :swing:jlist_horizontal_wrap.png |}} | Η λίστα εμφανίζει τα αντικείμενα από αριστερά προς τα δεξιά και αναδιπλώνεται στη επόμενη γραμμή | | ||
- | | {{ :swing:jlist_vertical_wrap.png |}} | Η λίστα εμφανίζει τα αντικείμενα από πάνω προς τα κάτω και αναδιπλώνεται στην επόμενη στήλη | | ||
- | | {{ :swing:jlist_vertical.png |}} | Η λίστα εμφανίζει τα αντικείμενα από πάνω προς τα κάτω σε μία στήλη | | ||
- | |||
- | Επίσης κάθε λίστα έχει τις παρακάτω επιλογές όσον αφορά των τρόπο επιλογής | ||
- | |||
- | | {{ :swing:jlist_simple_selection.png |}} | Επιλογή μόνο ενός αντικειμένου | | ||
- | | {{ :swing:jlist_single_interval_selection.png |}} | Επιλογή ενός ή πολλών συνεχόμενων αντικειμένων | | ||
- | | {{ :swing:jlist_multiple_interval_selection1.png |}} | Επιλογή πολλαπλών αντικειμένων χωρίς περιορισμούς | | ||
- | |||
- | <WRAP tip 80% center round> | ||
- | Η κλάση JList δεν έχει την δυνατότητα scrolling. Αν θέλετε να προσθέσετε scrolling θα πρέπει να το κάνετε δημιουργώντας ένα αντικείμενο του [[http://docs.oracle.com/javase/7/docs/api/javax/swing/JScrollPane.html|javax.swing.JScrollPane]]. | ||
- | </WRAP> | ||
- | |||
- | ==== Listening Interface ==== | ||
- | |||
- | Αντικείμενα του τύπου JList μπορούν να κάνουν register Listening objects του τύπου [[http://docs.oracle.com/javase/7/docs/api/javax/swing/event/ListSelectionListener.html|javax.swing.event.ListSelectionListener]]. Η βασική μέθοδος που υλοποιεί το συγκεκριμένο interface είναι η παρακάτω. | ||
- | <code java> | ||
- | void valueChanged(ListSelectionEvent e) | ||
- | //Called whenever the value of the selection changes. | ||
- | </code> | ||
- | |||
- | ==== Παράδειγμα ==== | ||
- | |||
- | Δείτε το παραπάνω παράδειγμα από το site της Oracle. | ||
- | |||
- | <code java ListDemo.java> | ||
- | |||
- | import java.awt.*; | ||
- | import java.awt.event.*; | ||
- | import javax.swing.*; | ||
- | import javax.swing.event.*; | ||
- | |||
- | /* ListDemo.java requires no other files. */ | ||
- | public class ListDemo extends JPanel | ||
- | implements ListSelectionListener { | ||
- | private JList list; | ||
- | private DefaultListModel listModel; | ||
- | |||
- | private static final String hireString = "Hire"; | ||
- | private static final String fireString = "Fire"; | ||
- | private JButton fireButton; | ||
- | private JTextField employeeName; | ||
- | |||
- | public ListDemo() { | ||
- | super(new BorderLayout()); | ||
- | |||
- | listModel = new DefaultListModel(); | ||
- | listModel.addElement("Jane Doe"); | ||
- | listModel.addElement("John Smith"); | ||
- | listModel.addElement("Kathy Green"); | ||
- | |||
- | //Create the list and put it in a scroll pane. | ||
- | list = new JList(listModel); | ||
- | list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); | ||
- | list.setSelectedIndex(0); | ||
- | list.addListSelectionListener(this); | ||
- | list.setVisibleRowCount(5); | ||
- | JScrollPane listScrollPane = new JScrollPane(list); | ||
- | |||
- | JButton hireButton = new JButton(hireString); | ||
- | HireListener hireListener = new HireListener(hireButton); | ||
- | hireButton.setActionCommand(hireString); | ||
- | hireButton.addActionListener(hireListener); | ||
- | hireButton.setEnabled(false); | ||
- | |||
- | fireButton = new JButton(fireString); | ||
- | fireButton.setActionCommand(fireString); | ||
- | fireButton.addActionListener(new FireListener()); | ||
- | |||
- | employeeName = new JTextField(10); | ||
- | employeeName.addActionListener(hireListener); | ||
- | employeeName.getDocument().addDocumentListener(hireListener); | ||
- | String name = listModel.getElementAt( | ||
- | list.getSelectedIndex()).toString(); | ||
- | |||
- | //Create a panel that uses BoxLayout. | ||
- | JPanel buttonPane = new JPanel(); | ||
- | buttonPane.setLayout(new BoxLayout(buttonPane, | ||
- | BoxLayout.LINE_AXIS)); | ||
- | buttonPane.add(fireButton); | ||
- | buttonPane.add(Box.createHorizontalStrut(5)); | ||
- | buttonPane.add(new JSeparator(SwingConstants.VERTICAL)); | ||
- | buttonPane.add(Box.createHorizontalStrut(5)); | ||
- | buttonPane.add(employeeName); | ||
- | buttonPane.add(hireButton); | ||
- | buttonPane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); | ||
- | |||
- | add(listScrollPane, BorderLayout.CENTER); | ||
- | add(buttonPane, BorderLayout.PAGE_END); | ||
- | } | ||
- | |||
- | class FireListener implements ActionListener { | ||
- | public void actionPerformed(ActionEvent e) { | ||
- | //This method can be called only if | ||
- | //there's a valid selection | ||
- | //so go ahead and remove whatever's selected. | ||
- | int index = list.getSelectedIndex(); | ||
- | listModel.remove(index); | ||
- | |||
- | int size = listModel.getSize(); | ||
- | |||
- | if (size == 0) { //Nobody's left, disable firing. | ||
- | fireButton.setEnabled(false); | ||
- | |||
- | } else { //Select an index. | ||
- | if (index == listModel.getSize()) { | ||
- | //removed item in last position | ||
- | index--; | ||
- | } | ||
- | |||
- | list.setSelectedIndex(index); | ||
- | list.ensureIndexIsVisible(index); | ||
- | } | ||
- | } | ||
- | } | ||
- | |||
- | //This listener is shared by the text field and the hire button. | ||
- | class HireListener implements ActionListener, DocumentListener { | ||
- | private boolean alreadyEnabled = false; | ||
- | private JButton button; | ||
- | |||
- | public HireListener(JButton button) { | ||
- | this.button = button; | ||
- | } | ||
- | |||
- | //Required by ActionListener. | ||
- | public void actionPerformed(ActionEvent e) { | ||
- | String name = employeeName.getText(); | ||
- | |||
- | //User didn't type in a unique name... | ||
- | if (name.equals("") || alreadyInList(name)) { | ||
- | Toolkit.getDefaultToolkit().beep(); | ||
- | employeeName.requestFocusInWindow(); | ||
- | employeeName.selectAll(); | ||
- | return; | ||
- | } | ||
- | |||
- | int index = list.getSelectedIndex(); //get selected index | ||
- | if (index == -1) { //no selection, so insert at beginning | ||
- | index = 0; | ||
- | } else { //add after the selected item | ||
- | index++; | ||
- | } | ||
- | |||
- | listModel.insertElementAt(employeeName.getText(), index); | ||
- | //If we just wanted to add to the end, we'd do this: | ||
- | //listModel.addElement(employeeName.getText()); | ||
- | |||
- | //Reset the text field. | ||
- | employeeName.requestFocusInWindow(); | ||
- | employeeName.setText(""); | ||
- | |||
- | //Select the new item and make it visible. | ||
- | list.setSelectedIndex(index); | ||
- | list.ensureIndexIsVisible(index); | ||
- | } | ||
- | |||
- | //This method tests for string equality. You could certainly | ||
- | //get more sophisticated about the algorithm. For example, | ||
- | //you might want to ignore white space and capitalization. | ||
- | protected boolean alreadyInList(String name) { | ||
- | return listModel.contains(name); | ||
- | } | ||
- | |||
- | //Required by DocumentListener. | ||
- | public void insertUpdate(DocumentEvent e) { | ||
- | enableButton(); | ||
- | } | ||
- | |||
- | //Required by DocumentListener. | ||
- | public void removeUpdate(DocumentEvent e) { | ||
- | handleEmptyTextField(e); | ||
- | } | ||
- | |||
- | //Required by DocumentListener. | ||
- | public void changedUpdate(DocumentEvent e) { | ||
- | if (!handleEmptyTextField(e)) { | ||
- | enableButton(); | ||
- | } | ||
- | } | ||
- | |||
- | private void enableButton() { | ||
- | if (!alreadyEnabled) { | ||
- | button.setEnabled(true); | ||
- | } | ||
- | } | ||
- | |||
- | private boolean handleEmptyTextField(DocumentEvent e) { | ||
- | if (e.getDocument().getLength() <= 0) { | ||
- | button.setEnabled(false); | ||
- | alreadyEnabled = false; | ||
- | return true; | ||
- | } | ||
- | return false; | ||
- | } | ||
- | } | ||
- | |||
- | //This method is required by ListSelectionListener. | ||
- | public void valueChanged(ListSelectionEvent e) { | ||
- | if (e.getValueIsAdjusting() == false) { | ||
- | |||
- | if (list.getSelectedIndex() == -1) { | ||
- | //No selection, disable fire button. | ||
- | fireButton.setEnabled(false); | ||
- | |||
- | } else { | ||
- | //Selection, enable the fire button. | ||
- | fireButton.setEnabled(true); | ||
- | } | ||
- | } | ||
- | } | ||
- | |||
- | /** | ||
- | * Create the GUI and show it. For thread safety, | ||
- | * this method should be invoked from the | ||
- | * event-dispatching thread. | ||
- | */ | ||
- | private static void createAndShowGUI() { | ||
- | //Create and set up the window. | ||
- | JFrame frame = new JFrame("ListDemo"); | ||
- | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | ||
- | |||
- | //Create and set up the content pane. | ||
- | JComponent newContentPane = new ListDemo(); | ||
- | newContentPane.setOpaque(true); //content panes must be opaque | ||
- | frame.setContentPane(newContentPane); | ||
- | |||
- | //Display the window. | ||
- | frame.pack(); | ||
- | frame.setVisible(true); | ||
- | } | ||
- | |||
- | public static void main(String[] args) { | ||
- | //Schedule a job for the event-dispatching thread: | ||
- | //creating and showing this application's GUI. | ||
- | javax.swing.SwingUtilities.invokeLater(new Runnable() { | ||
- | public void run() { | ||
- | createAndShowGUI(); | ||
- | } | ||
- | }); | ||
- | } | ||
- | } | ||
- | </code> | ||
- | |||