Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    Problema Con Model Per Jtable

    Salve a tutti, ho creato un model da associare ad una JTable, vi posto il codice:
    codice:
    public class DataModel extends AbstractTableModel implements ActionListener {
    
        private String[] headers = {"", Main.ls.getValue("rilevaprod_commessa"), Main.ls.getValue("rilevaprod_articolo"), Main.ls.getValue("rilevaprod_sezione"), Main.ls.getValue("rilevaprod_operazione"), Main.ls.getValue("rilevaprod_taglia"), Main.ls.getValue("rilevaprod_capi")};
        private Class[] columnTypes = {JButton.class, String.class, String.class, String.class, String.class, String.class, String.class};
        private Vector<Vector<Object>> data = new Vector<Vector<Object>>();
        ImageIcon cancicon = new ImageIcon(getClass().getResource("/programmatunisia/GraphicalUserInterface/images/del16x16.png"));
    
        public void appendRow(String a, String b, String c, String d, String e, String f) {
            Vector<Object> row = new Vector<Object>();
            JButton cancel = new JButton();
            cancel.setIcon(cancicon);
            cancel.setContentAreaFilled(false); // no riempimento
            cancel.setBorder(null); // no bordo
            cancel.setFocusPainted(false); // no focus
            cancel.setFocusable(false);
            cancel.addActionListener(this);
            cancel.repaint();
            row.add(cancel);
            row.add(a);
            row.add(b);
            row.add(c);
            row.add(d);
            row.add(e);
            row.add(f);
            data.add(row);
            fireTableStructureChanged();
            RilevaProduzione.labLav.setText(String.valueOf(getRowCount()));
            RilevaProduzione.labNum.setText(String.valueOf(getPezziCount(getRowCount())));
        }
    
        public int getRowCount() {
            return data.size();
        }
    
        public int getColumnCount() {
            return headers.length;
        }
    
        public void setValueAt(Object v, int row, int col) {
            data.get(row).set(col, v);
        }
    
        public Class getColumnClass(int col) {
            return columnTypes[col];
        }
    
        public String getColumnName(int col) {
            return headers[col];
        }
    
        public boolean isCellEditable(int row, int col) {
            return col==0;
        }
    
        public Object getValueAt(int row, int col) {
            return data.get(row).get(col);
        }
    
        public int getPezziCount(int numrow) {
            int total = 0;
            for (int i = 0; i < numrow; i++) {
                total = total + Integer.parseInt(getValueAt(i, 6).toString());
            }
            return total;
        }
    
        public void actionPerformed(ActionEvent e) {
            int row = getRowForButton(e.getSource());
            if (row == -1) {
                throw new RuntimeException("DataModel, no row for button!!!???");
            }
            data.remove(row);
            fireTableStructureChanged();
            RilevaProduzione.labLav.setText(String.valueOf(getRowCount()));
            RilevaProduzione.labNum.setText(String.valueOf(getPezziCount(getRowCount())));
        }
    
        private int getRowForButton(Object o) {
            for (int k = 0; k < data.size(); k++) {
                if (data.get(k).get(0) == o) {
                    return k;
                }
            }
            return -1;
        }
    };
    e le relative classi per l'editing e il rendering:

    codice:
    public class ButtonEditor implements TableCellEditor {
    	public Component getTableCellEditorComponent(JTable t, Object value,
    		boolean isSelected, int row, int column)
    	{
    		return (JButton)value;
    	}
    
    	public Object getCellEditorValue() { return null; }
    	public void cancelCellEditing() {}
    	public boolean stopCellEditing() { return true;	}
    	public boolean shouldSelectCell(EventObject o) { return true; }
    	public boolean isCellEditable(EventObject o) { return true;	}
    	public void addCellEditorListener(CellEditorListener l) {}
    	public void removeCellEditorListener(CellEditorListener l) {}
    };
    codice:
    public class ButtonRenderer implements TableCellRenderer {
    	public Component getTableCellRendererComponent(JTable t, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    	{
    		return (JButton)value;
    	}
    }
    fin qui tutto ok, la tabella viene creata correttemente e funge tutto alla perfezione.
    codice:
    DataModel model = new DataModel();
    JTable tableProd = new JTable(model);
    
    tableProd.setRowHeight(24);
    tableProd.setDefaultRenderer(JButton.class, new ButtonRenderer());
    tableProd.setDefaultEditor(JButton.class, new ButtonEditor());
    Ora quello che vorrei fare è di settare alcuni parametri sulla tabella, e faccio nel seguente modo, ma non ottengo nessun effetto.
    codice:
            tableProd.getColumnModel().getColumn(0).setResizable(false);
            tableProd.getColumnModel().getColumn(1).setResizable(false);
            tableProd.getColumnModel().getColumn(2).setResizable(false);
            tableProd.getColumnModel().getColumn(3).setResizable(false);
            tableProd.getColumnModel().getColumn(4).setResizable(false);
            tableProd.getColumnModel().getColumn(5).setResizable(false);
            tableProd.getColumnModel().getColumn(6).setResizable(false);
            tableProd.setFocusable(false);
            tableProd.getColumnModel().getColumn(0).setMinWidth(50);
            tableProd.getColumnModel().getColumn(0).setMaxWidth(50);
            tableProd.getColumnModel().getColumn(1).setMinWidth(80);
            tableProd.getColumnModel().getColumn(1).setMaxWidth(80);
            tableProd.getColumnModel().getColumn(1).setCellRenderer(new CenterCellRenderer());
            tableProd.getColumnModel().getColumn(2).setMinWidth(40);
            tableProd.getColumnModel().getColumn(2).setMaxWidth(40);
            tableProd.getColumnModel().getColumn(2).setCellRenderer(new CenterCellRenderer());
            tableProd.getColumnModel().getColumn(3).setMinWidth(90);
            tableProd.getColumnModel().getColumn(3).setMaxWidth(90);
            tableProd.getColumnModel().getColumn(3).setCellRenderer(new CenterCellRenderer());
            tableProd.getColumnModel().getColumn(4).setMinWidth(90);
            tableProd.getColumnModel().getColumn(4).setMaxWidth(90);
            tableProd.getColumnModel().getColumn(5).setMinWidth(30);
            tableProd.getColumnModel().getColumn(5).setMaxWidth(30);
            tableProd.getColumnModel().getColumn(6).setMinWidth(30);
            tableProd.getColumnModel().getColumn(6).setMaxWidth(30);
    Qualcuno ha qualche idea su come settare la larghezza delle colonne..ecc...ecc...

    n.b. Notavo invece che la riga di codice tableProd.setRowHeight(24); funziona perfettamente!!

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Problema Con Model Per Jtable

    Originariamente inviato da fabiolinux85
    Qualcuno ha qualche idea su come settare la larghezza delle colonne..ecc...ecc...
    Se vuoi poter impostare in modo preciso la larghezza delle colonne, devi anche invocare setAutoResizeMode(int mode) di JTable per impostare il modo AUTO_RESIZE_OFF.


    P.S. Invece di fare una marea di tableProd.getColumnModel().getColumn(n)...., visto che imposti resizable/minWidth/maxWidth per tutte le colonne 0...6, fai un metodo apposito!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3

    Niente non va!!

    Ho seguito il tuo consiglio andbin, soltanto che l'effetto che ottengo è:

    inizialmente all'apertura del JInternalFrame contenente la JTable, le colonne vengono settate della larghezza scelta da me, non ridimensionabili, con 0 righe;

    poi quello che faccio è leggere dei barcode con un lettore ottico e ad ogni lettura mi viene inserita una nuova riga sulla JTable attraverso questo metodo:
    codice:
    private void addRow(String commessa, String articolo, String sezione, String operazione, String taglia, String pezzi) {
            model.appendRow(commessa, articolo, sezione, operazione, taglia, pezzi);
            labLav.setText(String.valueOf(tableProd.getRowCount()));
    }
    ecco che però all'inserimento della riga le colonne della tabella vengono allargate automaticamente, inoltre viene tolto il settaggio che imposto alla creazione della JTable del non consentirne il ridimensionamento manuale delle suddette.

    Ti faccio notare, non so se c'hai già fatto caso, che sulla prima colonna di ogni riga ho un JButton che mi serve per rimuovere quella riga nel caso io lo prema.

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Niente non va!!

    Originariamente inviato da fabiolinux85
    ecco che però all'inserimento della riga le colonne della tabella vengono allargate automaticamente
    Quando si inserisce una riga nel model, il fire più appropriato non è fireTableStructureChanged() ma bensì fireTableRowsInserted()!

    E per il remove di una riga, idem, il fire appropriato è fireTableRowsDeleted(). Se li hanno forniti.... un motivo c'è ...


    E altra cosa da notare: in un "table model", che dovrebbe occuparsi solo ed esclusivamente della struttura e della gestione di "dati", fare cose tipo RilevaProduzione.labLav.setText(String.valueOf(get RowCount())); cioè il set di un componente che non centra nulla (direttamente) con i dati e con la tabella, oltretutto con tale design (un campo di un'altra classe acceduto direttamente!), è a mio avviso molto discutibile.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5

    Grazie provo subito!!

    Perfetto, sei un grande!!!
    Riguardo a quelle due cose discutibili di cui mi parlavi, cerco di ovviare subito...scusami se ti disturbo ancora ma vedo che sei preparatissimo e ne approfitto, mi sapresti dire qual'è il metodo che attiva/disattiva lo spostamento delle colonne da una parte all'altra della tabella? Non lo ricordo e non riesco a ritrovarlo su web. Grazie

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Grazie provo subito!!

    Originariamente inviato da fabiolinux85
    Riguardo a quelle due cose discutibili di cui mi parlavi, cerco di ovviare subito...
    Visto che i valori in quelle label li imposti ad un insert/delete di una riga, una soluzione pulita e semplice è registrare un TableModelListener. Quando ricevi un evento di insert o delete, imposti quelle label.

    Originariamente inviato da fabiolinux85
    mi sapresti dire qual'è il metodo che attiva/disattiva lo spostamento delle colonne da una parte all'altra della tabella?
    Il trascinamento degli header delle colonne per cambiarne l'ordine è attivato di default e si può impostare true/false con setReorderingAllowed() di JTableHeader (lo ottieni da JTable).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7

    USO INDICI DI RIGA CON METODI

    Forse sbaglio nell'uso degli indici delle righe della tabella ma ho qualche problema con i due metodi sopra citati:

    codice:
    public void appendRow(String a, String b, String c, String d, String e, String f) {
            Vector<Object> row = new Vector<Object>();
            JButton cancel = new JButton();
            cancel.setIcon(cancicon);
            cancel.setContentAreaFilled(false); // no riempimento
            cancel.setBorder(null); // no bordo
            cancel.setFocusPainted(false); // no focus
            cancel.setFocusable(false);
            cancel.addActionListener(this);
            cancel.repaint();
            row.add(cancel);
            row.add(a);
            row.add(b);
            row.add(c);
            row.add(d);
            row.add(e);
            row.add(f);
            data.add(row);
    
            System.out.println("RIGA AGGIUNTA: "+getRowCount());
            fireTableRowsInserted(getRowCount()-1,getRowCount()-1);
        }
    e l'inserimento pare che funge anche se quel system out stampa valori assurdi, cioè in pratica:

    AGGIUNGO PRIMA RIGA ----->RIGA AGGIUNTA: 1
    AGGIUNGO SECONDA RIGA ----->RIGA AGGIUNTA: 2
    AGGIUNGO TERZA RIGA ----->RIGA AGGIUNTA: 3

    CANCELLO TUTTE LE RIGHE TRANNE UNA (che non mi è consentita cancellare, ci sarà qualche errore negli indici passati all'algoritmo)

    provo ad AGGIUNGERE NUOVA RIGA e magia ----->RIGA AGGIUNTA: 2
    RIGA AGGIUNTA: 1
    Anche se in realtà li me ne inserisce correttamente una.
    PERCHE'!?!?

    Per quanto riguarda la cancellazione delle righe, devo aver toppato anche li, come ti dicevo posso cancellarle tutte, in ordine sparso, e tutto fila liscio fino a che non mi ritrovo solo una riga in tabella, a quel punto nada...ed esce il messaggio: "DataModel, no row for button!!!???"

    Il codice è questo:
    codice:
    public void actionPerformed(ActionEvent e) {
            int row = getRowForButton(e.getSource());
            if (row == -1) {
                throw new RuntimeException("DataModel, no row for button!!!???");
            }
            System.out.println("RIGA CANCELLATA: "+row);
            data.remove(row);
            fireTableRowsDeleted(row,row+1);
        }

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: USO INDICI DI RIGA CON METODI

    Originariamente inviato da fabiolinux85
    codice:
    public void actionPerformed(ActionEvent e) {
            int row = getRowForButton(e.getSource());
            if (row == -1) {
                throw new RuntimeException("DataModel, no row for button!!!???");
            }
            System.out.println("RIGA CANCELLATA: "+row);
            data.remove(row);
            fireTableRowsDeleted(row,row+1);
        }
    In fireTableRowsDeleted i due indici sono "inclusivi". Passando row,row+1 notifichi che hai rimosso 2 righe ... non 1.


    Poi altre solite cose che ti segnalo ma giusto solo per precisione e chiarezza:
    - Implementare un ActionListener in un table model può essere discutibile. Ma lo è ancora di più la implementazione di quel getRowForButton() ... una ricerca lineare perché hai JButton distinti nella struttura dati (vedi punto sotto). "Distinzione" che tra l'altro non ti serve ... poiché i pulsanti sono esattamente tutti uguali!

    - Un table model dovrebbe "esporre" solo ed unicamente "dati" ... non "componenti" AWT/Swing (al massimo degli ImageIcon). Quindi mettere dei JButton nella struttura dati è altrettanto molto discutibile.
    È il renderer(/editor) che fornisce il componente (es. JButton).

    Tra i miei Java Examples (vedi firma) ci sono esempi di tabelle con pulsanti.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.