PDA

View Full Version : [JAVA] Jpanel come cella di JTable?


julianross1983
24-10-2006, 17:11
Sarebbe possibile inserire come cella di una JTable una JPanel?

PGI-Bis
24-10-2006, 17:22
Si.

Ciò che appare come cella di un JTable è il prodotto dell'applicazione del metodo getTableCellRendererComponent al contenuto di quella cella. Se il contenuto della cella è un JPanel il proiettore, che definisce il metodo in esame, può limitarsi a restituire quel JPanel.

julianross1983
24-10-2006, 19:15
Un esempio tipico?Ho notato parecchie classi che bisogna modificare o gestire?grazie tante

PGI-Bis
24-10-2006, 20:19
Pronti!.

Faccio un esempio di proiezione di un pannello.

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
start();
}
});
}

private static void start() {
/* Crea il pannello che andrà nella cella (1,1) */
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createLoweredBevelBorder());
panel.setBackground(Color.PINK);
panel.setOpaque(true);
/* Dati usati dalle righe della tabella */
Object[][] tableData = {
{ "Pino", "Beppe" },
{ "Giusi", panel },
};
/* Intestazioni delle colonne della tabella */
Object[] tableHeaders = {
"A", "B",
};
/* Crea il modello della tabella */
TableModel tableModel = new DefaultTableModel(tableData, tableHeaders);
/* Crea la tabella */
JTable table = new CustomTable();
/* Assegna un modello alla tabella */
table.setModel(tableModel);
/* Mette la tabella in un pannello a scorrimento */
JScrollPane tableScroller = new JScrollPane(table);
/* Crea la finestra, aggiunge il pannello a scorrimento che contiene la
tabella al pannello del contenuto della finestra e spara quest'ultima
sullo schermo */
JFrame window = new JFrame("PanelRenderer Sample");
window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
window.add(tableScroller, BorderLayout.CENTER);
window.pack();
window.setVisible(true);
}
}

/** Proietta il contenuto delle celle della tabella */
class PanelRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
/* value è il valore conservato nel modello della tabella in corrispondenza
della cella (row, column). Se quel valore è un JPanel restituisco direttamente
quel JPanel come vista del contenuto, altrimenti uso la definizione standard di
questo metodo */
return value instanceof JPanel ?
(JPanel)value :
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}

/** Ridefinisce il metodo getCellRenderer in modo che restituisca un
PanelRenderer per la cella (1,1) */
class CustomTable extends JTable {
private PanelRenderer panelRenderer = new PanelRenderer();

/** Tutto standard tranne il caso in cui la cella sia la (1,1): lì deve
esserci un JPanel e per quella cella restituisco un proiettore ad hoc */
public TableCellRenderer getCellRenderer(int row, int column) {
return row == 1 && column == 1 ?
panelRenderer :
super.getCellRenderer(row, column);
}

/** Questo metodo è invocato quando un certo tipo di interazione utente
segnali un tentativo di mutare il valore di una cella della tabella. Rendiamo
il valore della cella (1,1) "non interagibile". Per tutti gli altri rinviamo
al meccanismo standard. */
public boolean isCellEditable(int row, int column) {
return row == 1 && column == 1 ?
false :
super.isCellEditable(row, column);
}
}

Noterai che il pannello assume le dimensioni delle altre celle e che, per esplicita volontà, non è passibile di interazione. Per le dimensioni passi per i metodi getRowHeight(int row) di JTable e getColumnWidth(int col) di JTableHeader. Per l'interazione crei un tuo TableCellEditor.

julianross1983
24-10-2006, 21:39
sei davvero un grande!

julianross1983
26-10-2006, 12:34
Nella cella della JTable ho un oggetto complesso (Plane) composto da: un JPanel che contiene 3 JLabel....ora...vorrei poter gestire il drag and drop tra le JLabel di due oggetti Plane contenuti nella JTable.E' possibile?e quali metodi bisogna gestire..grazie

PGI-Bis
26-10-2006, 16:41
Non è difficile ma potrebbe richiede un po' di maneggiamenti.

Io proverei ad associare il drag and drop alla tabella. Gli eventi di trascinamento e rilascio iniziano e finiscono in un "Point". Attraverso quel Point puoi risalire alla cella della tabella in cui il rilascio inizia o termina. Banalmente, per il drag, se il punto corrisponde ad una cella che contiene un valore JPanel e, fatte le opportune conversioni dell'origine degli assi, in quel punto il JPanel ha un'etichetta, inizi il trascinamento – spostando l'etichetta o la stringa... quello che devi trascinare.

Lo stesso vale per il rilascio. Se nel punto di rilascio c'è una cella il cui valore è un JPanel e, fatte le opportune conversioni, in quel punto del pannello c'è un'etichetta, rilasci... quello che devi rilasciare.

Alternativamente puoi far si che il controllo passi al JPanel contenuto nella tabella alla pressione del mouse o al suo rilascio (lo stabilisci creando un TableCellEditor ad hoc). A quel punto gestisci il trascinamento e il rilascio direttamente dai JPanel. In teoria :D. Non so poi se possano esserci interferenze tra gli eventi del mouse che attivano la modifica di una cella e il fatto che gli stessi eventi debbano anche attivare le azioni di trascinamento e rilascio. Direi che questa seconda soluzione potrebbe essere un po' più complicata.

Ricorda che affinchè la tabella mostri il cambiamento di valori dovuti al drag and drop, dovrai dire alla tabella, passando per il suo modello, di ricaricare il contenuto delle celle interessate dal drag and drop.

julianross1983
26-10-2006, 19:01
NON RIESCO AD IMPLEMENTARE IL "TABLECELLEDITOR",PER GESTIRE IL TRASCINAMENTO DI UNA JLABEL CONTENUTA IN PANNELLO CHE A SUA VOLTA E' CONTENUTO IN UNA CELLA DI UNA JTABLE.....COME SI PUO' RISOLVERE?ESEMPIO!GRAZIE