Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando
Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando
Abbiamo giocato a lungo a Battlefield 6, abbiamo provato tutte le modalità multiplayer, Redsec, e le numerose personalizzazioni. In sintesi, ci siamo concentrati su ogni aspetto del titolo per comprendere al meglio uno degli FPS più ambiziosi della storia dei videogiochi e, dopo quasi due mesi, abbiamo tirato le somme. In questo articolo, condividiamo con voi tutto ciò che è Battlefield 6, un gioco che, a nostro avviso, rappresenta esattamente ciò che questo genere attendeva da tempo
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare
Abbiamo messo alla prova il drone Antigravity A1 capace di riprese in 8K a 360° che permette un reframe in post-produzione ad eliche ferme. Il concetto è molto valido, permette al pilota di concentrarsi sul volo e le manovre in tutta sicurezza e decidere con tutta tranquillità come gestire le riprese. La qualità dei video, tuttavia, ha bisogno di uno step in più per essere competitiva
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator
Dopo oltre 4 anni si rinnova la serie Sony Alpha 7 con la quinta generazione, che porta in dote veramente tante novità a partire dai 30fps e dal nuovo sensore partially stacked da 33Mpixel. L'abbiamo provata per un breve periodo, ecco come è andata dopo averla messa alle strette.
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


Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando Due mesi di Battlefield 6: dalla campagna al bat...
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare Antigravity A1: drone futuristico per riprese a ...
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator Sony Alpha 7 V, anteprima e novità della ...
realme GT 8 Pro Dream Edition: prestazioni da flagship e anima racing da F1 realme GT 8 Pro Dream Edition: prestazioni da fl...
OVHcloud Summit 2025: le novità del cloud europeo tra sovranità, IA e quantum OVHcloud Summit 2025: le novità del cloud...
HBO ha cancellato la produzione della se...
OpenAI ha pensato a una partnership (o a...
Starlink Mobile: SpaceX potrebbe lanciar...
Volkswagen trasforma lo stabilimento di ...
Meta AI più reattivo e imparziale...
In Cina la prima GPU discreta al mondo c...
Vertiv CoolCenter, il sistema di raffred...
Konecta entra nel Kraken BPO Partner Pro...
Un dialogo con l'AI sposta voti meglio d...
iPhone 17 al minimo storico: oggi il 256...
Gli utenti italiani scelgono ChatGPT: &e...
Anche Xiaomi avrà il suo trifold:...
È Natale in casa Tesla: arriva la...
Shai-Hulud diventa più cattivo: e...
Aereo ultraleggero si schianta in atterr...
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: 21:10.


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