Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Plaud NotePin S, il registratore IA si fa indossabile (ma è facile da perdere)
Plaud NotePin S, il registratore IA si fa indossabile (ma è facile da perdere)
Quattro modi di indossarlo, stessa app del Plaud Note Pro e integrazione con il desktop. Il registratore IA da indossare di Plaud eccelle in mobilità, ma resta vincolato all'abbonamento ed è facile da perdere
Redmi Watch 6 in prova: lo smartwatch con ampio display da 2000 nit a meno di 100 euro
Redmi Watch 6 in prova: lo smartwatch con ampio display da 2000 nit a meno di 100 euro
Xiaomi ha portato Redmi Watch 6 anche sul mercato italiano, puntando su un display AMOLED da 2,07 pollici con picco di luminosità a 2000 nit, frame in alluminio da 9,9mm e un'autonomia dichiarata di 12 giorni. Lo smartwatch gira su HyperOS 3 e integra GPS, Bluetooth 5.4 e oltre 150 sport mode. Il tutto a meno di 100 euro
Mad Catz M.M.O. 7+: lo stesso DNA del R.A.T. 8+ ADV, ma con molti più pulsanti
Mad Catz M.M.O. 7+: lo stesso DNA del R.A.T. 8+ ADV, ma con molti più pulsanti
Con 22 tasti, il pulsante 5D, lo Shift Mode e il sensore PixArt 3395 da 26.000 DPI, il nuovo mouse wireless di Mad Catz si rivolge in modo preciso ai giocatori di MMO e RPG. Ma chi conosce già il R.A.T. 8+ ADV si accorgerà subito di quanto i due prodotti condividano, e di dove invece divergono
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 29-10-2006, 23: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, 12: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


Plaud NotePin S, il registratore IA si fa indossabile (ma è facile da perdere) Plaud NotePin S, il registratore IA si fa indoss...
Redmi Watch 6 in prova: lo smartwatch con ampio display da 2000 nit a meno di 100 euro Redmi Watch 6 in prova: lo smartwatch con ampio ...
Mad Catz M.M.O. 7+: lo stesso DNA del R.A.T. 8+ ADV, ma con molti più pulsanti Mad Catz M.M.O. 7+: lo stesso DNA del R.A.T. 8+ ...
Radeon RX 9070 GRE, AMD la porta in tutto il mondo | Recensione Gigabyte Gaming OC Radeon RX 9070 GRE, AMD la porta in tutto il mon...
Reolink OMVI 3i WiFi: videosorveglianza più intelligente e facile da usare Reolink OMVI 3i WiFi: videosorveglianza pi&ugrav...
Cavi sottomarini come sensori: la Finlan...
Exodus è il nuovo Mass Effect? Il...
Lockdown Mode cambia il volto di ChatGPT...
Guild Wars 3 è ufficiale: ArenaNe...
I giocatori voltano le spalle a Linux? L...
Instagram Plus arriva in Italia: cosa in...
XBOX: la nuova CEO non ha ancora le idee...
Intel non ha intenzione di abbandonare i...
La AI Mode sarà attiva di default...
Marvel's Wolverine non sarà un op...
Star Wars Zero Company esce ad agosto: n...
Bonus Decoder: fino al 70% di sconto con...
Virtua Fighter è tornato e non &e...
Il ritorno di Fumito Ueda, autore di Sha...
Cooler Master svela GPU Shield, la nuova...
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: 18:15.


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