Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Polestar 3 Performance, test drive: comodità e potenza possono convivere
Polestar 3 Performance, test drive: comodità e potenza possono convivere
Abbiamo passato diversi giorni alla guida di Polestar 3, usata in tutti i contesti. Come auto di tutti i giorni è comodissima, ma se si libera tutta la potenza è stupefacente
Qualcomm Snapdragon X2 Elite: l'architettura del SoC per i notebook del 2026
Qualcomm Snapdragon X2 Elite: l'architettura del SoC per i notebook del 2026
In occasione del proprio Architecture Deep Dive 2025 Qualcomm ha mostrato in dettaglio l'architettura della propria prossima generazione di SoC destinati ai notebook Windows for ARM di prossima generazione. Snapdragon X2 Elite si candida, con sistemi in commercio nella prima metà del 2026, a portare nuove soluzioni nel mondo dei notebook sottili con grande autonomia
Recensione DJI Mini 5 Pro: il drone C0 ultra-leggero con sensore da 1 pollice
Recensione DJI Mini 5 Pro: il drone C0 ultra-leggero con sensore da 1 pollice
DJI Mini 5 Pro porta nella serie Mini il primo sensore CMOS da 1 pollice, unendo qualità d'immagine professionale alla portabilità estrema tipica di tutti i prodotti della famiglia. È un drone C0, quindi in un peso estremamente contenuto e che non richiede patentino, propone un gimbal rotabile a 225 gradi, rilevamento ostacoli anche notturno e autonomia fino a 36 minuti. Caratteristiche che rendono il nuovo drone un riferimento per creator e appassionati
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 30-10-2006, 00:55   #1
julianross1983
Junior Member
 
Iscritto dal: Oct 2006
Messaggi: 25
[JAVA]

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
julianross1983 è offline   Rispondi citando il messaggio o parte di esso
Old 30-10-2006, 13:27   #2
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Come dissi nell'altro thread, passare per l'editor è una delle soluzioni. L'altra, che propongo qui, usa l'intera tabella come sorgente e destinazione di eventi drag and drop.

L'esempio è molto specifico e meccanicamente inutile al tuo problema. Inutile perchè il trasferimento dipende dai componenti concretamente coinvolti e, in particolare, dalla distribuzione degli spazi nella tabella e nei pannelli contenuti come celle di quella tabella.

Dovresti comunque essere in grado di applicare un modello simile alla tua situazione concreta.

Codice:
package tab;

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

/** Proietta una cella il cui valore è un JPanel usando lo stesso
JPanel come proiettore */
public class PanelRenderer implements TableCellRenderer {

	public Component getTableCellRendererComponent(
		JTable table,
		Object value,
		boolean isSelected,
		boolean hasFocus,
		int row,
		int column)  
	{
		return (JPanel)value;
	}
}

package tab;

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

/** Un pannello che contiene tre JLabel */
public class TriLabel extends JPanel {
	private JLabel nameLabel = new JLabel();
	private JLabel surnameLabel = new JLabel();
	private JLabel roleLabel = new JLabel();
	
	/** Inizializza un TriLabel assegnando alle tre etichette
	i testi name, surnam e role */
	public TriLabel(String name, String surname, String role) {
		super(new GridLayout(3, 1, 2, 2));
		nameLabel.setText(name);
		surnameLabel.setText(surname);
		roleLabel.setText(role);
		add(nameLabel);
		add(surnameLabel);
		add(roleLabel);
	}
	
	/** Restituisce l'etichetta che occupa la regione di
	spazio a cui appartiene il punto p. */
	public JLabel getLabelAt(Point p) {
		/* Il layout è un GridLayout. L'altezza di ogni
		etichetta è uguale a circa un terzo dell'altezza
		di tutto il pannello. */
		Dimension dim = getPreferredSize();
		/* La divisione intera p.y / (altezza di un singolo elemento)
		restituisce l'indice (da 0 a 2 estremi inclusi) dell'etichetta.
		0 è nameLabel (perchè è la prima inserita nel pannello)
		1 è surnameLabel(perchè è la seconda inserita nel pannello)
		2 è roleLabe (perchè è la terza inserita nel pannello) */
		int labelIndex = p.y / (dim.height / 3);
		return
			labelIndex == 0 ?
			nameLabel :
			labelIndex == 1 ?
			surnameLabel :
			roleLabel;
	}
}

package tab;

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

public class MyTable extends JTable {
	private PanelRenderer panelRenderer = new PanelRenderer();

	/** Se la cella in posizione (row, column) contiene un JPanel,
	restituisce un panelRenderer (uno per tutte). Altrimenti
	restituisce il proiettore predefinito da JTable */
	public TableCellRenderer getCellRenderer(int row, int column) {
		Object value = getValueAt(row, column);
		return
			value instanceof JPanel ?
			panelRenderer :
			super.getCellRenderer(row, column);
	}
	
	/** L'altezza delle righe è pari all'altezza della più alta
	delle righe. Alcune celle possono (dovrebbero) contentere
	dei componenti. In questo caso l'altezza esaminata è l'altezza
	preferita di quel componente. Il conto è particolarmente
	dispendioso e andrebbe affrontato in modo diverso (un caching
	del valore ed un nuovo calcolo solo se intervengano mutazioni
	di un componente appartenente al modello sarebbe già meglio) */
	public int getRowHeight() {
		int height = super.getRowHeight();
		/* Non sapendo in che colonna ed in quali righe si trovino
		i JPanel devo esaminarle tutte. */
		for(int row = 0; row < getRowCount(); row++) {
			for(int col = 0; col < getColumnCount(); col++) {
				Object value = getValueAt(row, col);
				if(value instanceof Component) {
					Component comp = (Component)value;
					Dimension dim = comp.getPreferredSize();
					if(dim.height > height) {
						height = dim.height;
					}
				}
			}
		}
		return height;
	}
	
	/** Per semplicità rendo insensibili tutte le celle al
	sistema predefinito di mutazione del valore (il doppio click) */
	public boolean isCellEditable(int row, int col) {
		return false;
	}
}

package tab;

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

public class DNDManager {
	private JTable table;
	
	/* Il metodo dragGestureRecognized di questo
	DragGestureListener è invocato quando la piattaforma
	rilevi un tentativo di trascinamento */
	private DragGestureListener dragHandler = new DragGestureListener() {
		
		public void dragGestureRecognized(DragGestureEvent e) {
			/* Il componente registrato come "attivatore" del trascinamento
			è la tabella intera. Noi dobbiamo verificare se il punto da cui
			parte il trascinamento corrisponda ad una cella che contiene un
			TriLabel */
			Point origin = e.getDragOrigin();
			int row = table.rowAtPoint(origin);
			int col = table.columnAtPoint(origin);
			TriLabel component = getTriLabelAt(row, col);
			
			if(component != null) {
				/* Nel punto di trascinamento c'è un TriLabel */
				/* Ora dobbiamo prendere l'etichetta del TriLabel che
				si trova nel punto di trascinamento */
				Point p = convertToCellPoint(origin, row, col);
				JLabel label = component.getLabelAt(p);
				/* Trovata l'etichetta trasciniamo il suo testo */
				startTextDrag(e, label.getText());
			}
		}
	};
	
	/* Il metodo drop di questo DropTargetAdapter è invocato quando la
	piattaforma rilevi un tentativo di rilascio */
	private DropTargetListener dropHandler = new DropTargetAdapter() {
		public void drop(DropTargetDropEvent e) {
			/* Il componente registrato come "attivatore" del rilascio è
			la tabella. Noi dobbiamo verificare se il punto in cui si
			verifica il rilascio corrisponda ad una cella che contiene
			un TriLabel */
			Point destination = e.getLocation();
			int row = table.rowAtPoint(destination);
			int col = table.columnAtPoint(destination);
			TriLabel component = getTriLabelAt(row, col);
			if(component != null && e.isDataFlavorSupported(DataFlavor.stringFlavor)) {
				/* Nel punto di rilascio c'è un TriLabel e i dati rilasciati
				sono di un tipo testo: possiamo iniziare il rilascio */
				e.acceptDrop(DnDConstants.ACTION_COPY);
				/* Dal punto di rilascio relativo alla tabella passiamo
				al punto di rilascio relativo al pannello contenuto nella
				cella della tabella */
				Point p = convertToCellPoint(destination, row, col);
				/* Iniziamo il trasferimento del testo */
				startTextDrop(e, p, component, row, col);
			} else {
				/* Nel punto di rilascio non c'è un TriLabel o i dati non sono
				di tipo testo: rifiutiamo il rilascio */
				e.rejectDrop();
			}
		}
	};
	
	/* Restituisce un punto che rappresenta le coordinate di p
	nello spazio di coordinate della cella (row, col) */
	private Point convertToCellPoint(Point p, int row, int col) {
		Rectangle cellRect = table.getCellRect(row, col, true);
		return new Point(
			p.x - cellRect.x,
			p.y - cellRect.y);
	}
	
	/* Restituisce il TriLabel corrispondente alla cella (row, col)
	o null se quella cella non contenga un TriLabel */
	private TriLabel getTriLabelAt(int row, int col) {
		TriLabel result = null;
		Object value = table.getValueAt(row, col);
		if(value instanceof TriLabel) {
			result = (TriLabel)value;
		}
		return result;
	}
	
	/* Tenta di rilasciare il testo contenuto nel transferable
	associato a dropEvent. Il punto dropPoint è relativo
	all'origine del componente destination. I valori row e col
	sono gli indici della cella in cui è contenuto il componente
	destination e servono per costringere la tabella ad aggiornare
	il contenuto di quella cella una volta che il trascinamento
	sia completato. L'invocazione di questo metodo presuppone che
	il tipo di dato trasferito sia compatibile con
	DataFlavor.stringFlavor */
	private void startTextDrop(DropTargetDropEvent dropEvent,
		Point dropPoint, TriLabel destination, int row, int col)
	{
		/* Un "drop" termina con una notifica di completamento
		avvenuto con o senza successo. Questo valore è usato al
		termine di questo metodo per notificare l'esito del
		rilascio. */
		boolean success = false;
		try {
			/* Ottiene la capsula dei dati che si vorrebbero
			rilasciare */
			Transferable t = dropEvent.getTransferable();
			/* In accordo alla precondizione di compatibilità con
			DataFlavor.stringFlavor, ottiene i dati trasferiti. Qui
			può (ma non dovrebbe) prodursi un UnsupportedFlavorException
			ed un ClassCastException. */
			String text = (String)t.getTransferData(DataFlavor.stringFlavor);
			/* Ottiene dal TriLabel destination l'etichetta che si
			trova nel punto dropPoint (che è relativo alla posizione del
			componente nella tabella e non all'origine della tabella) */
			JLabel label = destination.getLabelAt(dropPoint);
			/* Imposta il testo di quell'etichetta */
			label.setText(text);
			/* A questo punto deve far si che la tabella aggiorni la
			proiezione della cella (row, col). Per farlo passa attraverso
			il modello: imposta per la cella (row, col) lo stesso valore
			che c'era prima (lo stesso TriLabel). Come conseguenza di un
			setValueAt, anche se il valore è lo stesso di prima, il modello
			notifica alla vista-tabella che qualcosa è cambiato e la
			vista-tabella è responsabile dell'aggiornamento visivo
			di quella cella. */
			Object value = table.getValueAt(row, col);
			DefaultTableModel model = (DefaultTableModel)table.getModel();
			model.setValueAt(value, row, col);
			/* A questo punto possiamo ritenere completato con
			successo il trasferimento */
			success = true;
		} catch(UnsupportedFlavorException ex) {
			success = false;
		} catch(ClassCastException ex) {
			success = false;
		} catch(java.io.IOException ex) {
			success = false;
		} finally {
			dropEvent.dropComplete(success);
		}
	}
	
	/* Crea uno StringSelection (un Transferable per String) e
	notifica l'inizio di un evento di trascinamento che trasporta
	il testo text */
	private void startTextDrag(DragGestureEvent e, String text) {
		StringSelection transferable = new StringSelection(text);
		e.startDrag(DragSource.DefaultCopyDrop, transferable);
	}

	/** Attiva questo gestore del drag and drop per il MyTable in
	argomento. */
	public void bind(MyTable table) {
		/* Crea e connette un attivatore degli eventi "drag". Questo
		fa sì che quando la piattaforma rilevi un tentativo di trascinamento
		che interessi (per posizione) la tabella "table" sia invocato il metodo
		dragGestureRecognized del DragGestureListener "dragHandler" */
		DragSource ds = DragSource.getDefaultDragSource();
		ds.createDefaultDragGestureRecognizer(
			table,
			DnDConstants.ACTION_COPY,
			dragHandler);
			
		/* Crea e connette un attivatore degli eventi "drop". Questo
		fa sì che quando la piattaforma rilevi un tentativo di
		rilascio che interessi (per posizione) la tabella "table" 
		sia invocato il metodo "dropt" del DropTargetListener
		"dropHandler" */
		DropTarget dt = new DropTarget(table, dropHandler);
		this.table = table;
	}
}

package tab;

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();
			}
		});
	}
	
	public static void start() {
		/* Un po' di stringhe e un po di JPanel con etichette */
		Object[][] data = {
			{ "Barcamena Spa", new TriLabel("Mario", "Rossi", "Scafista"), },
			{ new TriLabel("Franco", "Neri", "Estorsore"), "Taglieggio Srl", },
			{ "Zompo scarl", "Nessuno", },
		};
		Object[] headers = {
			"A", "B", 
		};
		
		/** Creo una tabella con un DefaultTableModel contenente
		i dati su generati */
		MyTable table = new MyTable();
		TableModel model = new DefaultTableModel(data, headers);
		table.setModel(model);
		
		/* JTable usa il mouse per selezionare le celle. Il DragAndDrop
		usa gli stessi eventi per il trascinamento, lo spostamento e il
		rilascio. Uno dei due sistemi deve essere modificato. Escludo
		in toto quelli di JTable */
		table.setCellSelectionEnabled(false);
		table.setRowSelectionAllowed(false);
		
		/** Creo un gestore del drag and drop per questo particolare
		tipo di tabella e lo "attivo" */
		new DNDManager().bind(table);
		
		JScrollPane scroller = new JScrollPane(table);
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frame.add(scroller, BorderLayout.CENTER);
		frame.pack();
		frame.setVisible(true);
	}
}
L'esempio propone una tabella in cui alcune celle sono dei TriLabel. Un TriLabel è un JPanel che contiene tre JLabel. Le stringhe presentate dalle etichette contenute in questi TriLabel sono mutabili attraverso il drag and drop.
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Polestar 3 Performance, test drive: comodità e potenza possono convivere Polestar 3 Performance, test drive: comodit&agra...
Qualcomm Snapdragon X2 Elite: l'architettura del SoC per i notebook del 2026 Qualcomm Snapdragon X2 Elite: l'architettura del...
Recensione DJI Mini 5 Pro: il drone C0 ultra-leggero con sensore da 1 pollice Recensione DJI Mini 5 Pro: il drone C0 ultra-leg...
ASUS Expertbook PM3: il notebook robusto per le aziende ASUS Expertbook PM3: il notebook robusto per le ...
Test ride con Gowow Ori: elettrico e off-road vanno incredibilmente d'accordo Test ride con Gowow Ori: elettrico e off-road va...
ESA: rilevati 40 mila asteroidi vicino a...
La batteria salva fabbriche di EQORE ott...
SpaceX Starship: iniziati i test della t...
Datacenter IA nello spazio entro 5 anni,...
Telescopio spaziale James Webb: rilevato...
Ericsson Mobility Report: nel 2025 il 5G...
PLAI DEMO DAY: si chiude il secondo cicl...
Google rilascia Nano Banana Pro: il nuov...
ChatGPT si rinnova ancora: disponibile l...
Ring lancia super sconti di Black Friday...
Black Friday 2025: 450 euro di sconto su...
Tutte le offerte Blink in un unico posto...
OpenAI e Foxconn uniscono le forze per r...
Ricarica delle auto elettriche in 3 minu...
Lucid presenta Gravity Touring, il SUV e...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 23:30.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v