# JTable 2 Selektionsfarben Mouse-Event



## Iron Monkey (3. Mrz 2009)

Hi an alle!

Ich möchte gerne 2 verschiedene Selektionen der JTable wie folgt einbauen:

- Mit MouseMoved soll jede ganze Zeile der JTable mit der Farbe "Hellgrün" gezeichnet werden!
- Mit MouseClicked soll die gewählte Zeile der JTable mit der Farbe "Gelb" gezeichnet werden!

Mit MouseMotionListener, MouseListener und DefaultTableCellRenderer habe ich mich soweit vorbereitet.

Das Problem ist nur, dass die gelbe Selektion durch MouseMoved immer wieder verschwindet. Mir fehlet ein paar Code im DefaultTableCellRenderer, damit die gelbe Selektion während der MouseMoved nicht verschwinden darf.

Hier ist mein Code:

*DefaultTableCellRenderer*

```
public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column )
	{
		c = super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column);
		
		l = (JLabel) c;
		
		l.setOpaque(true);
		l.setHorizontalAlignment( colData[ column ].m_alignment );
		
		if( isSelected )
			l.setBackground( table.getSelectionBackground() );
		else
		{
			if( row % 2 == 0 )
				l.setBackground( LABEL_COLOR_HELLBLAU_2 );
			else
				l.setBackground( LABEL_COLOR_WHITE );
		}
		
       	return l;
	}
```

*mouseClicked*

```
if( e.getButton() == MouseEvent.BUTTON1 )
		{
			Object source = e.getSource();
			
			if( source instanceof JTable )
			{
				JTable table = ((JTable) source);
				
				int row = table.rowAtPoint( e.getPoint() );
				table.setRowSelectionInterval( row, row );

				table.setSelectionBackground( LABEL_COLOR_YELLOW );
			}
		}
```

*mouseMoved*

```
Object source = e.getSource();
		
		if( source instanceof JTable )
		{
			JTable table = ((JTable) source);
			
			int row = table.rowAtPoint( e.getPoint() );
			table.setRowSelectionInterval( row, row );

			table.setSelectionBackground( TABLE_MOUSE_MOVE_COLOR_GREEN );
		}
```

Gruß
Iron Monkey


----------



## Ebenius (3. Mrz 2009)

Wie soll das auch gehen? Der SelectionBackground ist eine normale Eigenschaft der JTable. Wenn Du ihn änderst, dann für alle selektierten Zellen. Wenn Du das wirklich brauchst (und ich halte das Verhalten ohne nähere Erklärung vorläufig für irreführend und zweifelhaft), dann wirst Du kaum umhin kommen, ein zweites ListSelectionModel zu benutzen oder die alternative Selektion im Tabellenmodell abzubilden (was auch nur selten aber nicht nie Sinn ergibt).

Ebenius


----------



## Iron Monkey (3. Mrz 2009)

Hi Ebenius!

Warum macht das keinen Sinn?

Schau dir erstmal das Bild als Beispiel an. Da kann man sehr gut nachvollziehen, wozu man 2 Selektionen braucht!

Die grüne Markierung macht die MouseMoved und die blaue Markierung hat eine Aufgabe, dass ganz links alle Datums validiert wird. Ich finde, dass das ein Sinn macht.

Gruß
Iron Monkey


----------



## Ebenius (3. Mrz 2009)

Iron Monkey hat gesagt.:


> Warum macht das keinen Sinn?


Daher schrieb ich:


Ebenius hat gesagt.:


> [...] ich halte das Verhalten *ohne nähere Erklärung vorläufig* für irreführend und zweifelhaft [...]


Wenn dem Benutzer klar ist, was er machen soll, dann ist alles gut. Meistens, wenn solche Fragen kommen, liegt es an einem Konzeptfehler. Wenn es in diesem Fall nicht so ist, dann schön. 

Was bedeuten die beiden unterschiedlichen Markierungen nochmal genau? Ich hab den Satz oben nicht richtig verstanden. Abhängig davon würde ich überlegen, ob ich die Markierung im Tabellenmodell oder in einem zweiten ListSelectionModel halte.

Ebenius


----------



## Iron Monkey (3. Mrz 2009)

Also, die grüne Markierung bedeutet, in welcher Zeile der Tabelle bist du jetzt mit der Maus ---> MouseMoved von MouseMotionListener

und die blaue Markierung ist die Selektion der JTable, um das Datum "Ende" aus der selektierten Zeile ganz links im Datum-Rahmen zu zeigen ( siehe Bild )!

OK, ich versuche jetzt, mit ListSelectionModel / TabellenModel einzubauen!

Gruß
Iron Monkey


----------



## Ebenius (3. Mrz 2009)

Aaaaaah... Grün ist ein Mouse-Over-Effekt. Jetzt verstehe ich langsam. In dem Fall wird das immer nur maximal eine Zeile treffen, oder?

Dann kannst Du natürlich einfach die JTable ableiten und dort eine mouseOverRow merken. So funktioniert es, muss natürlich noch Dein Renderer angepasst werden. Zum Spaß nur mal gelbe Zeile bei MouseOver: [HIGHLIGHT="Java"]public class MyTable extends JTable {

  private int mouseOverRow = -1;

  /** Creates a new {@code MyTable}. */
  public MyTable() {
    enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
    enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  }

  @Override
  protected void processMouseMotionEvent(MouseEvent e) {
    super.processMouseMotionEvent(e);
    final int oldIndex = mouseOverRow;
    mouseOverRow = rowAtPoint(e.getPoint());
    if (oldIndex != mouseOverRow) {
      if (mouseOverRow != -1) {
        repaintRow(mouseOverRow);
      }
      if (oldIndex != -1) {
        repaintRow(oldIndex);
      }
    }
  }

  @Override
  protected void processMouseEvent(MouseEvent e) {
    super.processMouseEvent(e);
    final int eventId = e.getID();
    if (eventId == MouseEvent.MOUSE_EXITED
          || eventId == MouseEvent.MOUSE_ENTERED) {
      final int oldIndex = mouseOverRow;
      if (oldIndex != -1) {
        mouseOverRow = -1;
        repaintRow(oldIndex);
      }
    }
  }

  /**
   * Repaint the row at the given view row index. Does nothing, if the column
   * count is zero.
   * 
   * @param rowIndex the row index
   */
  protected void repaintRow(int rowIndex) {
    final int cols1 = getColumnCount();
    Rectangle rect;
    if (cols1 > 0) {
      rect = getCellRect(rowIndex, 0, true);
      if (cols1 > 1) {
        rect = rect.union(getCellRect(rowIndex, cols1 - 1, true));
      }
      repaint(rect);
    }
  }

  // -------------------------------------------------------------------------
  // Bean getters and setters
  // -------------------------------------------------------------------------

  /**
   * Returns the view index of the row the mouse is over.
   * 
   * @return the row index
   */
  public int getMouseOverRow() {
    return mouseOverRow;
  }

  // -------------------------------------------------------------------------
  // Program Entry Point
  // -------------------------------------------------------------------------

  /**
   * Test main method.
   * 
   * @param args ignored
   */
  public static void main(String[] args) {
    final MyTable table = new MyTable();
    table.setModel(new DefaultTableModel(10, 4));
    table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {

      @Override
      public Component getTableCellRendererComponent(
            JTable table,
            Object value,
            boolean isSelected,
            boolean hasFocus,
            int row,
            int column) {
        if (((MyTable) table).getMouseOverRow() == row) {
          setBackground(Color.YELLOW);
        } else {
          setBackground(null);
        }
        return super.getTableCellRendererComponent(table, value, isSelected,
              hasFocus, row, column);
      }
    });
    final JFrame f = new JFrame("Mouse Over Table");
    f.setContentPane(new JScrollPane(table));
    f.pack();
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.setVisible(true);
  }
}[/HIGHLIGHT]

Ebenius


----------



## byte (3. Mrz 2009)

... oder einfach JXTable von SwingX benutzen, da ist das ein Einzeiler:

[HIGHLIGHT="Java"]jxtable.addHighlighter(new ColorHighlighter(HighlightPredicate.ROLLOVER_ROW, Color.WHITE, Color.GREEN));[/HIGHLIGHT]


----------



## Ebenius (4. Mrz 2009)

byto hat gesagt.:


> ... oder einfach JXTable von SwingX benutzen, da ist das ein Einzeiler


Damn it. Ich wusste, die gab's. Aber benutzt hab ich sie nie und einfach nicht dran gedacht. 

Ebenius


----------



## Iron Monkey (4. Mrz 2009)

Ebenius hat gesagt.:


> Aaaaaah... Grün ist ein Mouse-Over-Effekt. Jetzt verstehe ich langsam. In dem Fall wird das immer nur maximal eine Zeile treffen, oder?
> 
> Ebenius



Ja, es muss immer nur maximal eine Zeile getroffen werden, aber das ist kein Problem für mich! 

Super, vielen Dank!

Gruß
Iron Monkey


----------

