package elte.java2_utikalauz5.swing; /** Táblázatok használata Swingben.

A felhasználói felület tetején a naplózó komponens látható, ahol a táblázat adatmodelljének, valamit a kiválasztás változását követhetjük nyomon. Alatta egy 10*50-es táblázat látható, amely kezdetben az adott cella sor- és oszlopszámának szorzatát reprezentáló számot tartalmazza minden cellájában. A táblázatban található egy logikai értékeket tartalmazó oszlop is, melynek kiválasztott értéke az adott sor pirossal történő kiemelését eredményezi. Ezen táblázat különlegessége, hogy bármely kiválasztott oszlop lefixálható, ami azt jelenti, hogy az oszlop sötétebb háttérrel a táblázat elejére kerül és mindig látható marad, tehát vízszintesen nem fog a látótérből kigördülni. A táblázat sorai egy adott oszlop értékei alapján ABC rendbe rendezhetőek, ha rákattintunk valamely oszlop fejlécére. A táblázat mezői szerkeszthetőek (duplakattintás hatására), valamint minden négyzetszámot ábrázoló mezőjében zöld háttéren külön ikon is megjeleníttethető. Legalul a vezérlő panel látható, melynek gombjai lehetővé teszik a táblázat jellemzőinek szabályozását, kiválasztott oszlopok fixálást, illetve oszlopok fixálásának feloldását, valamint a megjelenítési stílus váltását. A táblázat megjelenítése nyomkövethető.

Oszlopok fix megjelenítéséhez tulajdonképp két táblázatot használunk. Az eredeti táblázaton kívül a lefixált oszlopokat egy külön táblázat tartalmazza, amely a táblázatot tartalmazó görgethető panel sorfejléceként kerül felhasználásra. Mindkét táblázat adat- és kiválasztási modellje azonos, csak az oszlopmodellek különböznek.

A táblázat adatmodellje lehetővé teszi a táblázat sorainak rendezését egy adott oszlop értékei alapján.

A táblázat fejlécének megjelenítését végző névtelen osztály az őse funkcionalitását csak annyival egészíti ki, hogy a rendezés alapját megadó oszlop fejlécében a rendezés irányát jelző kis nyilacskát is megjeleníti. @link.forrásfájl {@docRoot}/../data/swing/src JTableTeszt.java @link.letöltés {@docRoot}/../data/swing JTableTeszt.jar @since Java 2 Útikalauz programozóknak */ public class JTableTeszt extends SwingTeszt implements javax.swing.event. ChangeListener,javax.swing.event.TableColumnModelListener,javax.swing.event. ListSelectionListener,java.awt.event.ItemListener,java.awt.event.MouseListener{ /** 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 JTableTeszt().init(argumentumok); } /** Applet leírása. @return A példaprogram leírása */ @Override public String getAppletInfo() { return "Táblázatok használatát bemutató tesztprogram"; } /** Táblázat adatmodellje */ private Modell modell; /** Görgethető oszlopok modellje */ private javax.swing.table.DefaultTableColumnModel oszlopmodell; /** Görgethető táblázat */ private javax.swing.JTable tábla; /** Fix oszlopok modellje */ private javax.swing.table.DefaultTableColumnModel fixoszlopmodell; /** Fix táblázat */ private javax.swing.JTable fixtábla; /** Sorok kiválasztási módja */ private javax.swing.JComboBox sorkiválasztás; /** Oszlopok kiválasztási módja */ private javax.swing.JComboBox oszlopkiválasztás; /** Táblázat szerkeszthetőségének kapcsolója */ private javax.swing.JCheckBox szerkeszthető; /** Ikonok megjelenítésének kapcsolója */ private javax.swing.JCheckBox ikonok; /** Logikai értéket megjelenítő oszlop */ private javax.swing.table.TableColumn booleanoszlop; /** GUI felépítése */ @Override protected void felépít() { modell = new Modell(50,10); oszlopmodell = new javax.swing.table.DefaultTableColumnModel(); tábla = new javax.swing.JTable(modell, oszlopmodell); fixoszlopmodell = new javax.swing.table.DefaultTableColumnModel(); fixtábla = new javax.swing.JTable(modell, fixoszlopmodell); szerkeszthető = new javax.swing.JCheckBox("szerkeszthető?"); ikonok = new javax.swing.JCheckBox("ikonok?", true); fixtábla.setBackground(java.awt.Color.lightGray); //fixtábla megjelölése fixtábla.setColumnSelectionAllowed(true); //sorkiválasztás figyelése tábla.setDefaultRenderer(Object.class, new javax.swing.table. DefaultTableCellRenderer() { //alapértelmezett megjelenítő /** Verziószám. */ private final static long serialVersionUID = 15L; /** Felhasznált ikon */ private javax.swing.Icon ikon = ikonbetöltés("img/wood.jpg"); /** Táblázatelem megjelenítésének konfigurálása. @param táblázat A megjelenítendő táblázat. @param érték A megjelenítendő érték. @param kiválasztva Cella kiválasztásának jelzője. @param fókuszált Cella fókuszálásának jelzője. @param sor Megjelenítendő cella sora. @param oszlop Megjelenítendő cella oszlopa. @return A megjelen1tést végző grafikus komponens. */ @Override public java.awt.Component getTableCellRendererComponent( javax.swing.JTable táblázat, Object érték, boolean kiválasztva, boolean fókuszált, int sor, int oszlop) { setIcon(null); //négyzetszámoknál ikon megjelenítése, ha kell setBackground(null); setHorizontalTextPosition(CENTER); boolean négyzet = false; //négyszetszám-e if (érték instanceof Integer) { setHorizontalAlignment(CENTER); int gyök=(int)Math.sqrt(((Integer)érték).doubleValue()); négyzet = gyök*gyök==((Integer)érték).intValue(); } else setHorizontalAlignment(LEFT); if (((Boolean)modell.getValueAt(sor, booleanoszlop. getModelIndex())).booleanValue()) setBackground( java.awt.Color.red); if (négyzet) { if (ikonok.isSelected()) setIcon(ikon); setBackground(java.awt.Color.green); } return super.getTableCellRendererComponent( táblázat, érték, kiválasztva, fókuszált, sor, oszlop); } }); fixtábla.setDefaultRenderer(Object.class, tábla.getDefaultRenderer( Object.class)); tábla.setDefaultEditor(Object.class,new javax.swing.DefaultCellEditor( new javax.swing.JTextField()) { /** Verziószám. */ private final static long serialVersionUID = 15L; /** Táblázatelem bevitelének konfigurálása. @param táblázat A megjelenítendő táblázat. @param érték A megjelenítendő érték. @param kiválasztva Cella kiválasztásának jelzője. @param sor Megjelenítendő cella sora. @param oszlop Megjelenítendő cella oszlopa. @return A bevitelt végző grafikus komponens. */ @Override public java.awt.Component getTableCellEditorComponent( javax.swing.JTable táblázat, Object érték, boolean kiválasztva, int sor, int oszlop) { final javax.swing.JTextField mező = (javax.swing.JTextField) super.getTableCellEditorComponent(táblázat,érték,kiválasztva, sor,oszlop); javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { mező.selectAll();//szerkesztés megkezdésekor kiválasztás } }); return mező; } /** Szerkeztett érték lekérdezése. @return Szám esetén {@code Integer}, különben szöveg. */ @Override public Object getCellEditorValue() { String szöveg = (String)super.getCellEditorValue(); try { return new Integer(szöveg); } catch (Exception e) {} return szöveg; } }); fixtábla.setDefaultEditor(Object.class, tábla.getDefaultEditor( Object.class)); //oszlopkiválasztás figyelése tábla.getSelectionModel().addListSelectionListener(this); fixtábla.setSelectionModel(tábla.getSelectionModel()); oszlopmodell.getSelectionModel().addListSelectionListener(this); oszlopmodell.addColumnModelListener(this); //oszlopmodell figyelése javax.swing.JScrollPane görgetőpanel=new javax.swing.JScrollPane(tábla); görgetőpanel.setRowHeaderView(fixtábla); //felkonfigurálása görgetőpanel.getRowHeader().addChangeListener(this); //görgetés görgetőpanel.setCorner(görgetőpanel.UPPER_LEFT_CORNER, fixtábla. getTableHeader()); //fix rész fejléce látszódjon fixtábla.getTableHeader().addMouseListener(this); //fejlécben az egér tábla.getTableHeader().addMouseListener(this); //figyelése add(görgetőpanel); modell.addColumn("pirossor"); //modell felépítése tábla.createDefaultColumnsFromModel(); booleanoszlop = oszlopmodell.getColumn(oszlopmodell.getColumnCount()-1); booleanoszlop.setCellRenderer(new BooleanTableElem()); //különválasztás booleanoszlop.setCellEditor(new BooleanTableElem()); //armed state miatt for (int i=oszlopmodell.getColumnCount()-1; --i>=0;) //oszlopok oszlopmodell.getColumn(i).setHeaderValue( //fejlécszövege (i+1)+" ("+oszlopmodell.getColumn(i).getHeaderValue()+")"); fixtábla.setMaximumSize(new java.awt.Dimension(0, 0)); //kezdetben nem ((javax.swing.JViewport)fixtábla.getParent()).setPreferredSize(//látszik fixtábla.getMaximumSize()); for (int i = tábla.getRowCount(); --i>=0;) { //adatmodell feltöltése for (int j = tábla.getColumnCount()-1; --j>=0;) tábla.setValueAt(new Integer((i+1)*(j+1)), i, j); tábla.setValueAt(new Boolean(false), i, tábla.getColumnCount()-1); } add(new javax.swing.JScrollPane(napló), java.awt.BorderLayout.NORTH); javax.swing.JPanel panel = new javax.swing.JPanel(); //vezérlő panel panel.setPreferredSize(new java.awt.Dimension(850, 165)); javax.swing.AbstractButton gomb = new javax.swing.JButton( "oszlopok fixálása"); panel.add(gomb); //oszlopok fixálása gomb.setActionCommand("fix"); gomb.addActionListener(this); //nyomógomb figyelése gomb = new javax.swing.JButton("oszlopok visszavétele"); panel.add(gomb); //oszlopok visszavétele gomb.setActionCommand("defix"); gomb.addActionListener(this); //nyomógomb figyelése javax.swing.JLabel címke = new javax.swing.JLabel( "oszlopszélesség igazítási mód:"); panel.add(címke); címke.setToolTipText("JTable.setAutoResizeMode"); javax.swing.JComboBox legördülőlista = new javax.swing.JComboBox(new Object[] {"SUBSEQUENT_COLUMNS", "ALL_COLUMNS", "OFF", "NEXT_COLUMN", "LAST_COLUMN"}); panel.add(legördülőlista); legördülőlista.setToolTipText("AUTO_RESIZE_"); legördülőlista.addItemListener(this); //kiválasztás figyelése gomb = new javax.swing.JCheckBox("mező kiválasztható?", tábla. getCellSelectionEnabled()); panel.add(gomb); //mező kiválasztható gomb.setToolTipText("cellSelectionEnabled"); gomb.setActionCommand("cell"); gomb.addActionListener(this); //gomb kiválasztásának figyelése gomb = new javax.swing.JCheckBox("oszlop kiválasztható?", tábla. getColumnSelectionAllowed()); panel.add(gomb); //oszlop kiválasztható gomb.setToolTipText("columnSelectionAllowed"); gomb.setActionCommand("column"); gomb.addActionListener(this); //gomb kiválasztásának figyelése gomb = new javax.swing.JCheckBox("sor kiválasztható?", tábla. getRowSelectionAllowed()); panel.add(gomb); //sor kiválasztható gomb.setToolTipText("rowSelectionAllowed"); gomb.setActionCommand("row"); gomb.addActionListener(this); //gomb kiválasztásának figyelése címke = new javax.swing.JLabel("sorkiválasztási mód"); panel.add(címke); címke.setToolTipText("JTable.setSelectionMode"); Object[] elemek = {"MULTIPLE_INTERVAL", "SINGLE_INTERVAL", "SINGLE"}; sorkiválasztás = new javax.swing.JComboBox(elemek); panel.add(sorkiválasztás); sorkiválasztás.setToolTipText("_SELECTION"); sorkiválasztás.addItemListener(this); //kiválasztás figyelése címke = new javax.swing.JLabel("oszlopkiválasztási mód"); panel.add(címke); címke.setToolTipText("TableColumnModel.setSelectionMode"); oszlopkiválasztás = new javax.swing.JComboBox(elemek); panel.add(oszlopkiválasztás); oszlopkiválasztás.setToolTipText("_SELECTION"); oszlopkiválasztás.addItemListener(this); //kiválasztás figyelése gomb = new javax.swing.JCheckBox("vízszintes vonalak?", tábla. getShowHorizontalLines()); panel.add(gomb); //vízszintes vonalak gomb.setToolTipText("showHorizontalLines"); gomb.setActionCommand("horizontal"); gomb.addActionListener(this); //gomb kiválasztásának figyelése gomb = new javax.swing.JCheckBox("függőleges vonalak?", tábla. getShowVerticalLines()); panel.add(gomb); //függőleges vonalak gomb.setToolTipText("showVerticalLines"); gomb.setActionCommand("vertical"); gomb.addActionListener(this); //gomb kiválasztásának figyelése gomb = new javax.swing.JCheckBox("oszlopok mozgathatók?", tábla. getTableHeader().getReorderingAllowed()); panel.add(gomb); //oszlopok mozgathatók gomb.setToolTipText("JTableHeader.reorderingAllowed"); gomb.setActionCommand("reorder"); gomb.addActionListener(this); //gomb kiválasztásának figyelése gomb = new javax.swing.JCheckBox("oszlopok méretezhetők?", tábla. getTableHeader().getResizingAllowed()); panel.add(gomb); //oszlopok méretezhetők gomb.setToolTipText("JTableHeader.resizingAllowed"); gomb.setActionCommand("resize"); gomb.addActionListener(this); //gomb kiválasztásának figyelése panel.add(ikonok); ikonok.setActionCommand("ikon"); ikonok.addActionListener(this); //gomb kiválasztásának figyelése panel.add(szerkeszthető); for (javax.swing.Action váltás : stílusváltások) panel.add(new javax.swing.JButton(váltás)); //stílusváltásgombok add(panel, java.awt.BorderLayout.SOUTH); nyomkövetés(tábla); //nyomkövethető a megjelenítés nyomkövetés(fixtábla); } /** Fixtábla függőleges görgetésekor a táblázat függőleges szinkronizálása. @param ce Görgetést jelző esemény. */ public void stateChanged( javax.swing.event.ChangeEvent ce ) { final java.awt.Point tető = ((javax.swing.JViewport)tábla.getParent()). getViewPosition(); final java.awt.Point fixtető = ((javax.swing.JViewport)fixtábla. getParent()).getViewPosition(); if (tető.y != fixtető.y) javax.swing.SwingUtilities.invokeLater( new Runnable() { //történt görgetés public void run() { tető.y = fixtető.y; ((javax.swing.JViewport)tábla.getParent()).setViewPosition(tető); } }); } /** Rendezendő oszlop */ private javax.swing.table.TableColumn rendezőoszlop; /** Oszloprendezés iránya */ private boolean növekvő = true; /** Rendezési fejléc megjelenítője */ private javax.swing.table.DefaultTableCellRenderer fejléc = new javax.swing. table.DefaultTableCellRenderer() { /** Verziószám. */ private final static long serialVersionUID = 15L; /** Táblázatelem megjelenítésének delegálása. @param táblázat A megjelenítendő táblázat. @param érték A megjelenítendő érték. @param kiválasztva Cella kiválasztásának jelzője. @param fókuszált Cella fókuszálásának jelzője. @param sor Megjelenítendő cella sora. @param oszlop Megjelenítendő cella oszlopa. @return A megjelen1tést végző grafikus komponens. */ @Override public java.awt.Component getTableCellRendererComponent( javax.swing.JTable táblázat, Object érték, boolean kiválasztva, boolean fókuszált, int sor, int oszlop) { tábla.getTableHeader().getDefaultRenderer(). getTableCellRendererComponent(táblázat, érték, kiválasztva, fókuszált, sor, oszlop); return this; } /** Rendezési irány megjelenítése. @param g Aktuális rajzolási környezet. */ public void paint(java.awt.Graphics g) { java.awt.Component régi=(java.awt.Component)tábla.getTableHeader(). getDefaultRenderer(); régi.setBounds(getBounds()); régi.paint(g); //delegálás az eredeti megjelenítéshez int x = getWidth()-5; //rendezettségi nyil megrajzolása int y = (getHeight() - 10) / 2; if (!növekvő) y+=10; for (int xx=0; xx<10; xx++) { g.drawLine(x-xx/2, y, x+xx/2, y); if (növekvő) y++; else y--; } } }; /** Egérkattintás a fejlécre az adott oszlop szerinti rendezést eredményezi. @param me Egéresemény. */ public void mousePressed(java.awt.event.MouseEvent me) { int index = -1; boolean fix = false; if (me.getSource().equals(tábla.getTableHeader())) index = oszlopmodell. getColumnIndexAtX(me.getX()); else if (me.getSource().equals(fixtábla.getTableHeader())) { index = fixoszlopmodell.getColumnIndexAtX(me.getX()); fix = true; } if (index==-1) return; if ((fix ? fixoszlopmodell : oszlopmodell).getColumn(index)== booleanoszlop) return; if ((fix? fixoszlopmodell:oszlopmodell).getColumn(index)==rendezőoszlop) növekvő = !növekvő; else { //rendezés másik oszlop szerint if (rendezőoszlop!=null) rendezőoszlop.setHeaderRenderer(null); rendezőoszlop=(fix ? fixoszlopmodell:oszlopmodell).getColumn(index); rendezőoszlop.setHeaderRenderer(fejléc); növekvő = true; } if (fixtábla.getCellEditor()!=null) fixtábla.getCellEditor(). cancelCellEditing(); //rendezés előtt a szerkesztés befejezése if (tábla.getCellEditor()!=null) tábla.getCellEditor(). cancelCellEditing(); //rendezés előtt a szerkesztés befejezése modell.rendez(); //rendezés tábla.getTableHeader().repaint(); //rendezettség megjelenítése fixtábla.getTableHeader().repaint(); //a fejlécben } /** Fix oszlopok átméretezését jelző egérfelengedés figyelése. @param me Egérfelengedési esemény. */ public void mouseReleased(java.awt.event.MouseEvent me) { if (!me.getSource().equals(fixtábla.getTableHeader())) return; fixtábla.setMaximumSize(new java.awt.Dimension( fixoszlopmodell. getTotalColumnWidth(), 0)); //fix méret beállítása ((javax.swing.JViewport)fixtábla.getParent()).setPreferredSize( fixtábla.getMaximumSize()); ((javax.swing.JScrollPane)fixtábla.getParent().getParent()).revalidate(); } public void mouseClicked(java.awt.event.MouseEvent me) {} public void mouseEntered(java.awt.event.MouseEvent me) {} public void mouseExited(java.awt.event.MouseEvent me) {} /** Kiválasztások naplózása. @param lse Kiválasztási esemény. */ public void valueChanged(javax.swing.event.ListSelectionEvent lse) { if (lse.getValueIsAdjusting()) return; if (lse.getSource()==fixoszlopmodell.getSelectionModel()) //fixtábla naplóz("Kiválasztott fix oszlopok száma="+fixtábla. getSelectedColumnCount()); else if (lse.getSource()==oszlopmodell.getSelectionModel()) //tábla naplóz("Kiválasztott oszlopok száma="+tábla.getSelectedColumnCount()); else naplóz("Kiválasztott sorok száma="+tábla.getSelectedRowCount()); } /** Gombnyomások kezelése. @param ae Gombnyomás esemény. */ public void actionPerformed(java.awt.event.ActionEvent ae) { javax.swing.AbstractButton gomb = (javax.swing.AbstractButton)ae. getSource(); if (ae.getActionCommand().equals("cell")) { //mező kiválasztható tábla.setCellSelectionEnabled(gomb.isSelected()); fixtábla.setCellSelectionEnabled(gomb.isSelected()); } else if(ae.getActionCommand().equals("column")){//oszlop kiválasztható tábla.setColumnSelectionAllowed(gomb.isSelected()); fixtábla.setColumnSelectionAllowed(gomb.isSelected()); } else if (ae.getActionCommand().equals("row")) { //sor kiválasztható tábla.setRowSelectionAllowed(gomb.isSelected()); fixtábla.setRowSelectionAllowed(gomb.isSelected()); } else if (ae.getActionCommand().equals("vertical")) { //függőleges tábla.setShowVerticalLines(gomb.isSelected()); //vonalak fixtábla.setShowVerticalLines(gomb.isSelected()); } else if (ae.getActionCommand().equals("horizontal")) { //vízszintes tábla.setShowHorizontalLines(gomb.isSelected()); //vonalak fixtábla.setShowHorizontalLines(gomb.isSelected()); //vonalak } else if (ae.getActionCommand().equals("fix")) {//kiválasztott oszlopok if (!tábla.getColumnSelectionAllowed()) return; javax.swing.ListSelectionModel szelekció = oszlopmodell. getSelectionModel(); for (int i=0; i