JTable: Zellenfarbe bei onMouseEntered, onMouseExited ändern

shrink

Mitglied
Moin,
habe einen JTable der unter anderem zwei ImageIcons enthält.
Die Zellen werden mit einem custom DefaultCellRenderer gerendert.
Nun will ich, wenn mit der Maus über Zellen gefahren wird, die ein ImageIcon enthalten,
die Hintergrundfarbe des JLabels ändern auf dem das Icon sitzt.
Ich habe kein Plan wie ich hinbekomme.
Ich habe mal einen MouseMotionListener beim JTable angemeldet und setzte wenn
die Maus über ein entsprechendes Icon bewegt wird den Hintergrund des JLabels auf die
gewünschte Farbe. Aber wenn die Maus nun wieder ausserhalb dieser Koords bewegt wird,
hab ich keinen Referenzpunkt mehr über den ich die Zelle ansprechen und die Farbe zurücksetzen könnte.
Wenn ich einfach immer wenn das event nicht auf einem ImageIcon aufgerufen wird, bei allen
Zellen die Farbe zurück in den Ursprung änder, erreich zwar mein Ziel, erzeuge aber einen ziemlichen Overhead. Hat jemand eine Idee wie ich das bewerkstelligen kann?
 
Nun es gibt nur eine Maus daher kann immer nur eine Zelle selektiert sein. Merke dir die zuletzte selektierte Zelle. Stimmt diese nicht mehr mit der aktuell selektierten überein, so setzt du die Farbe der zuletzte selektierten wieder zurück.
 
ist einleuchtend, war wohl ein bissl spät.
Anderes prob in Bezug auf das Thema:
Ich möchte den Focus der rows mit mouseEnter und mouseExited triggern.
Dafür müsste ich wissen, wie das Actionhandling genau stattfindet.
Welche Klasse ruft denn die CellRenderer methode getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) auf?
Dort muss ich ja abfragen, on der Focus auf dem aktuellen Object liegt und dann die Farbe anpassen. Hierfür müsste ich manuell die Funktion aufrufen, um bei bedarf hasFocus = true zu übergeben. Im Default ist dies ja nur der Fall, wenn man eine row anklickt.
Die mouseEvents werden vom MouseInputListener der BasicTableUI abgefangen.
Ruft diese die getValueAt( int row, int col ) von JTable auf welche dann die CellRenderer::getTableCellRendererComponent() aufruft?
Wenn ich bloss wüsste welche Klasse denn den aufruf von getTableCellRendererComponent() könnte ich sie überschreiben und mein hasFocus setzen.
Hoffe das prob is klar.
 
Hallo,

du könntest es auch so lösen

Java:
package de.tutorials.table;

import java.awt.BorderLayout;
import java.awt.Component;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class TableExample extends JFrame {

	private JTable table = new JTable(10,10);
	
	public TableExample() {
		setSize(500,500);
		setLocationRelativeTo(null);
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		table.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer(){

			/* (non-Javadoc)
			 * @see javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
			 */
			@Override
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
				// TODO Auto-generated method stub
				if(row == 1)
				{
					hasFocus = true;
				}else
				{
					hasFocus = false;
				}
				JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
						row, column);
				
				
			
				return label;
			}
			
		});
		
		
		add(table, BorderLayout.CENTER);
	}
	
	public static void main(String[] args) {
		new TableExample().setVisible(true);
	}

}

So brauchst du nicht zu wissen, von welcher Klasse es aufgerufen wird.
Ich hoffe ich hab dein Problem richtig verstanden.


Oder meinst du eher sowas?

Java:
package de.tutorials.table;

import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JTable;

public class TableExample extends JFrame {

	private JTable table = new JTable(10, 10);

	public TableExample() {
		setSize(500, 500);
		setLocationRelativeTo(null);

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		table.addMouseMotionListener(new MouseMotionListener(){

			public void mouseDragged(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}

			public void mouseMoved(MouseEvent e) {
				int row = table.rowAtPoint(e.getPoint());
				table.setRowSelectionInterval(row, row);
				
			}
			
		});

		add(table, BorderLayout.CENTER);
	}

	public static void main(String[] args) {
		new TableExample().setVisible(true);
	}

}

MFG

zEriX
 
Zuletzt bearbeitet:
joa, soweit war ich auch schon.
habe einmal eine klasse die den DefaultCellRenderer erweitert um die Farben zu setzen und einmal einen mouseInputListener der die Selection setzt.
In der Tabelle habe ich erst 3 String columns und dann noch 2 zwei ImageIcons, die ebenfalls über meine, den DefaultCellRenderer erweitertende Klasse, gerendert werden. Die Labels auf denen die Icons sitzen, wechseln ihre Hintergrundfarbe nach weiss, wenn man mit der Maus über sie fährt.
Wenn ich das Prog starte, t das mit dem Focus bzw. Selection bei den Rows, aber sobald ich das erste mal über ein Icon fahre, tut sich nix mehr.

Hier der CellRenderer:

Code:
import java.awt.Color;
import java.awt.Component;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class MyTableCellRenderer extends DefaultTableCellRenderer
{
	private static final long serialVersionUID = 7L;
	private Color colorSelected = new Color( 200, 200, 255 );
	private Color colorFocus = new Color( 200, 200, 255 );
	private Color colorNormal = new Color( 224, 224, 216 );
	
	public MyTableCellRenderer()
	{
		super();
	}
	
	@Override
	public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus,
			int row, int column ) 
	{
		setText( null );
		setIcon( null );
		
		if( hasFocus )
		{
			setBackground( colorFocus );
		}
		else if( isSelected )
		{
			setBackground( colorSelected );
		}
		else
		{
			setBackground( colorNormal );
		}
				
		if ( value instanceof ImageIcon )
		{
			ImageIcon icon = ( ImageIcon ) value;
			
			setIcon( icon );
			setHorizontalAlignment( JLabel.CENTER );
			
			if( icon.getDescription().equals( "editFocus" ) )
			{
				setBackground( Color.WHITE );
				setToolTipText( "bearbeiten" );
				setName( "edit" );
			}
			else if( icon.getDescription().equals( "deleteFocus" ) )
			{
				setBackground( Color.WHITE );
				setToolTipText( "löschen" );
				setName( "delete" );
			}
			else if( icon.getDescription().equals( "delete" ) )
			{
				setToolTipText( "löschen" );
				setName( "delete" );
			}
			else if( icon.getDescription().equals( "delete" ) )
			{
				setToolTipText( "löschen" );
				setName( "delete" );
			}
			
			
		}
		else if( value instanceof String )
		{
			setText( value.toString() );
			setToolTipText( "" );
		}
		
		return this;
	}	
}

Die Funktion welche, das Ereignis abfängt:

Code:
public void mouseMoved( MouseEvent me ) 
	{
		if( me.getSource() instanceof JTable )
		{
			JTable table = ( JTable ) me.getSource();
			Point p = new Point( me.getX(), me.getY() );
			int rowIndex = table.rowAtPoint( p );
			int colIndex = table.columnAtPoint( p );
			table.setRowSelectionInterval( rowIndex, rowIndex );
			if( table.getValueAt( rowIndex, colIndex ) instanceof Object )
			{
				Object o = table.getValueAt( rowIndex, colIndex );
				if( o instanceof ImageIcon )
				{
					ImageIcon icon = ( ImageIcon ) o;
					URL url = null;
					
					if( icon.getDescription().equals( "delete" ) )
					{
						url = UserControlMainViewListener.class.getResource( "images/delete.gif" );
						icon = new ImageIcon( url );
						icon.setDescription( "deleteFocus" );
					}
					else if( icon.getDescription().equals( "edit" ) )
					{
						url = UserControlMainViewListener.class.getResource( "images/edit.gif" );
						icon = new ImageIcon( url );
						icon.setDescription( "editFocus" );
					}
					
					table.setValueAt( icon, rowIndex, colIndex );
				}
				else
				{
					( ( TableModelUser ) table.getModel() ).resetIcons();
				}
			}
		}
	}

Ziel ist es, das der Row Focus bzw. Selection mit mouseMove wechselt und die Selection/Focusfarbe der Row erhalten bleibt wenn man in der Row über das Icon fährt.
 
Vielleicht stehe ich auf dem Schlauch, aber ich verstehe nicht ganz was du willst. :)
 
Habe mal eben 2 Screenshots gemacht um das Prob zu verdeutlichen. :)
 

Anhänge

  • progStart.jpg
    progStart.jpg
    31 KB · Aufrufe: 179
  • afterFirstIconFocus.jpg
    afterFirstIconFocus.jpg
    36,7 KB · Aufrufe: 190
Zurück