package elte.java2_utikalauz5.swing; /** Listák használata Swingben.

A felhasználói felület tetején egy legördíthető lista látható. Ugyanezen listaelemeket jeleníti meg a bal oldalon látható lista is. A lista kezdetben a rendelkezésre álló megjelenítési stílusok nevét és ikonját tartalmazza, ezen elemek bármelyikének kiválasztása a megfelelő megjelenítési stílus beállítását vonja maga után. A felső legördíthető lista szerkeszthető, annak szerkesztőmezője segítségével új listaelemeket lehet felvenni. A felhasználói felület jobb oldalán látható vezérlőpanel gombjaival a kiválasztott listaelemeket lehet törölni, elrejteni, az összes elrejtett listaelemet újra megjeleníteni, valamint a legördíthető lista szerkeszthetőségét és a bal oldali lista kiválasztási modelljét lehet megadni. A felület közepén a naplózó komponensben a lista adatmodelljének változása, valamint a listaelemek kiválasztása kerül naplózásra. Az alsó részen három pörgethető mező látható, az elsővel a bal oldali lista elemei közül választhatunk, a másik kettővel pedig egy időpontot, valamint egy egész számot lehet megadni. A lista és a legördülő lista, valamint a pörgethető mezők megjelenítése nyomkövethető. @link.forrásfájl {@docRoot}/../data/swing/src ListaTeszt.java @link.letöltés {@docRoot}/../data/swing ListaTeszt.jar @since Java 2 Útikalauz programozóknak */ public class ListaTeszt extends SwingTeszt implements javax.swing.event. ChangeListener, java.awt.event.ItemListener, javax.swing.event. ListSelectionListener { /** Verziószám. */ private final static long serialVersionUID = 15L; /** Indítás alkalmazásként. @param argumentumok Az indításkor megadott paraméterek. */ public static void main(String argumentumok[]) { new ListaTeszt().init(argumentumok); } /** Applet leírása. @return A példaprogram leírása */ @Override public String getAppletInfo() { return "Listák használatát bemutató tesztprogram"; } /** Adatmodell */ private ListaModell modell; /** Legördülő lista */ private javax.swing.JComboBox legördülőlista; /** Lista */ private javax.swing.JList lista; javax.swing.JSpinner pörgető; /** GUI felépítése */ @Override protected void felépít() { modell = new ListaModell(); lista = new javax.swing.JList(modell); legördülőlista = new javax.swing.JComboBox(modell); add(new javax.swing.JScrollPane(napló)); add(new javax.swing.JScrollPane(lista), java.awt.BorderLayout.WEST); for (javax.swing.Action váltás : stílusváltások) //stílusváltások modell.felvesz(váltás); lista.setSelectionModel( new javax.swing.DefaultListSelectionModel() { /** Verziószám. */ private final static long serialVersionUID = 15L; /** Maximálisan megengedett kiválasztások száma */ int maximum = stílusváltások.size()-1; /** Kiválasztás megadása. @param index0 Kezdő kiválasztási index. @param index1 Vég kiválasztási index. */ @Override public void setSelectionInterval(int index0, int index1) { int min = Math.min( index0, index1 ); int max = Math.max( index0, index1 ); super.setSelectionInterval( min, Math.min(max, min+maximum) ); } /** Kiválasztási intervallum hozzáadása. @param index0 Kezdő kiválasztási index. @param index1 Vég kiválasztási index. */ @Override public void addSelectionInterval(int index0, int index1) { int min = Math.min( index0, index1 ); int max = Math.min( min+maximum, Math.max( index0, index1 )); if (isSelectionEmpty()||max==min+maximum||getMinSelectionIndex() >=min && getMaxSelectionIndex()<=max || getSelectionMode()==SINGLE_SELECTION || getSelectionMode()== SINGLE_INTERVAL_SELECTION && (maxgetMaxSelectionIndex()+1)) super.setSelectionInterval(min, max); else if (getSelectionMode()==SINGLE_INTERVAL_SELECTION) { if(min<=getMinSelectionIndex()) super.setSelectionInterval( min, Math.min(min+maximum, getMaxSelectionIndex())); else if(max>=getMaxSelectionIndex()) super. setSelectionInterval( Math.max(max-maximum, getMinSelectionIndex()), max); } else { int marad = maximum-(max-min); for (int index = min; --index>=getMinSelectionIndex();) if (isSelectedIndex(index)) if (marad>0) marad--; else removeIndexInterval(index, index); for (int index = max; ++index<=getMaxSelectionIndex();) if (isSelectedIndex(index)) if (marad>0) marad--; else removeIndexInterval(index, index); super.addSelectionInterval(min, max); } } }); lista.addListSelectionListener(this); //kiválasztás figyelése lista.setCellRenderer(new javax.swing.DefaultListCellRenderer() { /** Verziószám. */ private final static long serialVersionUID = 15L; /** Megjelenítés konfigurálása. @param lista A megjelenítendő lista. @param listaelem A megjelenítésre kerülő listaelem. @param index A megjelenítendő listaelem indexe. @param kiválasztott A megjelenítendő elem kiválasztottsága. @param fókuszált A megjelenítendő elem fókuszáltsága. */ @Override public java.awt.Component getListCellRendererComponent( javax.swing.JList lista, Object listaelem, int index, boolean kiválasztott, boolean fókuszált) { java.awt.Component komponens=super.getListCellRendererComponent( lista, listaelem, index, kiválasztott, fókuszált); if (listaelem instanceof javax.swing.AbstractAction)//stílusvált setIcon((javax.swing.Icon)((javax.swing.AbstractAction) listaelem).getValue(javax.swing.Action.SMALL_ICON)); else setIcon(null); return komponens; } }); add(legördülőlista, java.awt.BorderLayout.NORTH); legördülőlista.addItemListener(this); //kiválasztás figyelése legördülőlista.addActionListener(this); //szerkesztés vége figyelése legördülőlista.setRenderer(lista.getCellRenderer()); //megjelenítő javax.swing.JPanel panel = new javax.swing.JPanel(); //vezérlő panel panel.setPreferredSize(new java.awt.Dimension(150, 70)); add(panel, java.awt.BorderLayout.EAST); javax.swing.AbstractButton gomb = new javax.swing.JButton("töröl"); panel.add(gomb); gomb.setActionCommand("remove"); gomb.addActionListener(this); //nyomógomb figyelése gomb = new javax.swing.JButton("mind"); //minden listaelem megmutatása panel.add(gomb); gomb.setActionCommand("show"); gomb.addActionListener(this); //nyomógomb figyelése gomb = new javax.swing.JButton("elrejt"); //listaelem elrejtése panel.add(gomb); gomb.setActionCommand("hide"); gomb.addActionListener(this); //nyomógomb figyelése gomb = new javax.swing.JCheckBox("szerkeszthető?", legördülőlista.isEditable()); panel.add(gomb); gomb.setActionCommand("edit"); gomb.setToolTipText("editable"); gomb.addActionListener(this); //gomb figyelése javax.swing.JLabel címke = new javax.swing.JLabel("Kiválasztási mód"); panel.add(címke); címke.setToolTipText("selectionMode"); javax.swing.JComboBox mód = new javax.swing.JComboBox(new Object[] { "MULTIPLE_INTERVAL", "SINGLE_INTERVAL", "SINGLE"}); panel.add(mód); mód.setToolTipText("selectionMode"); mód.addItemListener(this); //kiválasztás figyelése nyomkövetés(lista); //nyomkövethető a megjelenítés nyomkövetés(legördülőlista); panel = new javax.swing.JPanel(); add(panel, java.awt.BorderLayout.SOUTH); pörgető = new javax.swing.JSpinner(modell); panel.add(pörgető); pörgető.setEditor( new javax.swing.JLabel("Stíluspörgető") ); modell.addChangeListener( this ); javax.swing.JSpinner pörget = new javax.swing.JSpinner(new javax.swing. SpinnerDateModel()); panel.add(pörget); pörget.addChangeListener( this ); pörget = new javax.swing.JSpinner(new javax.swing.SpinnerNumberModel()); panel.add(pörget); pörget.addChangeListener( this ); } /** Pörgetőmezők változásának jelzése. @param ce Változást jelző esemény */ public void stateChanged(javax.swing.event.ChangeEvent ce) { naplóz("Pörgetett érték megváltozott!"); if (ce.getSource()==modell) { Object aktuális = modell.getValue(); ((javax.swing.JLabel)pörgető.getEditor()).setText(aktuális==null? "" : aktuális.toString()); if (aktuális instanceof javax.swing.Action)((javax.swing.Action) aktuális).actionPerformed(null); } else ((javax.swing.JSpinner)ce.getSource()).revalidate(); } /** Listaelemek kiválasztása. @param lse Kiválasztási esemény. */ public void valueChanged(javax.swing.event.ListSelectionEvent lse) { naplóz("ListSelectionEvent: valueIsAdjusting="+lse.getValueIsAdjusting() +", firstIndex="+lse.getFirstIndex()+", lastIndex="+lse.getLastIndex()); if (!lse.getValueIsAdjusting()) modell.setSelectedItem(lista. getSelectedValue()); } /** Kiválasztási állapotváltozás. @param ie Kiválasztási esemény. */ public void itemStateChanged(java.awt.event.ItemEvent ie) { boolean kiválasztás = ie.getStateChange()==ie.SELECTED; naplóz("JComboBox ItemEvent("+ (kiválasztás ? "SELECTED" : "DESELECTED") +") : "+ie.getItem()); if (legördülőlista.equals(ie.getSource()) || !kiválasztás) return; int mód = 0; String választás = (String)ie.getItem(); if (választás.equals("MULTIPLE_INTERVAL")) //tetszőleges mód = javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION; else if (választás.equals("SINGLE_INTERVAL")) //intervallum mód = javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION; else if (választás.equals("SINGLE")) //egyszeres mód = javax.swing.ListSelectionModel.SINGLE_SELECTION; lista.clearSelection(); //választási mód állítása lista.setSelectionMode(mód); } /** Gombnyomások kezelése. @param ae Gomblenyomási esemény */ public void actionPerformed(java.awt.event.ActionEvent ae) { if ("comboBoxEdited".equals(ae.getActionCommand())) { naplóz("JComboBox ActionEvent"); String elem = legördülőlista.getEditor().getItem().toString(); modell.felvesz(elem); lista.clearSelection(); //új elem kiválasztása lista.setSelectedValue(elem, true); legördülőlista.getEditor().selectAll(); } else if ("remove".equals(ae.getActionCommand())) { //törlés Object[] kiválasztva = lista.getSelectedValues(); lista.clearSelection(); for (Object elem : kiválasztva) modell.töröl(elem); } else if ("hide".equals(ae.getActionCommand())) { //elrejtés Object[] kiválasztva = lista.getSelectedValues(); lista.clearSelection(); for (Object elem : kiválasztva) modell.elrejt(elem); } else if ("show".equals(ae.getActionCommand())) { //minden elem lista.clearSelection(); //mutatása modell.megmutat(); } else if ("edit".equals(ae.getActionCommand())) { //szerkeszthető legördülőlista.setEditable(((javax.swing.JCheckBox)ae.getSource()). isSelected()); } } /** Listaelemek elrejtését biztosító adatmodell */ class ListaModell extends javax.swing.DefaultComboBoxModel implements javax.swing.ListModel, javax.swing.event.ListDataListener, javax.swing.SpinnerModel { /** Verziószám. */ private final static long serialVersionUID = 15L; /** Elrejtett elemek */ java.util.Vector nemlátható = new java.util.Vector(); /** Alapkonstruktor */ ListaModell() { addListDataListener(this); //modellesemények figyelése } /** Megelőző elem lekérdezése. @return A lista megelőző eleme, vagy {@code null}. */ public Object getPreviousValue() { int index = getIndexOf(getSelectedItem())-1; return index>=0 ? getElementAt(index) : null; } /** Kiválasztott elem lekérdezése. @return A lista első kiválasztott eleme. */ public Object getValue() { return getSelectedItem(); } /** Következő elem lekérdezése. @return A lista következő eleme, vagy {@code null}. */ public Object getNextValue() { int index = getIndexOf(getSelectedItem())+1; return index> 1; while (végindex>kezdőindex) { if (collator.compare(elem.toString(), getElementAt(újindex).toString())>0) kezdőindex = újindex + 1; else végindex = újindex; újindex = (kezdőindex + végindex) >> 1; } insertElementAt(elem, újindex); //beszúrás a megfelelő helyre } /** Elem törlése. @param elem A törlendő adat. */ public void töröl(Object elem) { nemlátható.removeElement(elem); removeElement(elem); } /** Elem elrejtése. @param elem Az elrejtendő adat. */ public void elrejt(Object elem) { removeElement(elem); nemlátható.addElement(elem); } /** Minden rejtett elem megmutatása */ public void megmutat() { for (Object elem : nemlátható) felvesz( elem ); nemlátható.removeAllElements(); } /** Intervallum felvételének naplózása. @param le Felvételi esemény. */ public void intervalAdded(javax.swing.event.ListDataEvent le) { naplóz("ListDataEvent intervalAdded: index0="+le.getIndex0()+ ", index1="+le.getIndex1()); } /** Intervallum törlésének naplózása. @param le Törlési esemény. */ public void intervalRemoved(javax.swing.event.ListDataEvent le) { naplóz("ListDataEvent intervalRemoved: index0="+le.getIndex0()+ ", index1="+le.getIndex1()); } /** Adatváltozás naplózása. @param le Változási esemény. */ public void contentsChanged(javax.swing.event.ListDataEvent le) { naplóz("ListDataEvent felületsChanged: index0="+le.getIndex0()+ ", index1="+le.getIndex1()); } /** Adatváltozás figyelőinek felvétele. @param cl A felvevendő adatváltozás figyelő. */ public void addChangeListener(javax.swing.event.ChangeListener cl) { listenerList.add(javax.swing.event.ChangeListener.class, cl); } /** Adatváltozás figyelőinek törlése. @param cl A törlendő adatváltozás figyelő. */ public void removeChangeListener(javax.swing.event.ChangeListener cl) { listenerList.remove(javax.swing.event.ChangeListener.class, cl); } /** Kiválasztás változását jelző esemény */ private transient javax.swing.event.ChangeEvent esemény = new javax.swing. event.ChangeEvent( this ); /** Kiválasztott elem változásának jelzése. */ protected void fireStateChanged() { Object[] figyelők = listenerList.getListenerList(); for (int i = figyelők.length - 2; i >= 0; i -=2 ) if (figyelők[i] == javax.swing.event.ChangeListener.class) ((javax.swing.event.ChangeListener)figyelők[i+1]).stateChanged( esemény); } } }