JTable - String und Button in einer Zelle darstellen

sisela

Erfahrenes Mitglied
Hi Leute,

ich möchte gerne in einer Zelle einer JTable gleichzeitig einen String und ein JButton anzeigen.
Z. B. Einen String "c:\blablaPfad " und dahinter ein JButton("...") mit dem man dann ein neuen Pfad wählen kann.

Wie geht das? Vielen Dank schon mal...
 
Tach auch Snape,

vielen Dank für deinen Hinweis aber für mein Problem habe ich nicht direkt eine Lösung gefunden. Ich wiederhole nochmal: Ich möchte gerne in einer Zelle ein Label und(!) einen Button anzeigen lassen. Die Lösungen aus deinem Link zeigen nur einen Button pro Zelle an. Das hatte ich auch hinbekommen aber schöner wäre halt ein Label und ein Button.
Ich könnte auch das Label als ButtonText benutzen, dann würde ich zwei Fliegen mit einer Klappe schlagen aber wie gesagt anders würde ich es besser finden.

mfg
 
Tach,
guggst Du in die API für den TableCellRenderer mit der Methode

Code:
public Component getTableCellRendererComponent(...)

dann müsste doch eigentlich klar sein, wie der Hase läuft. Es ist eine Component zurückzugeben. Also ist es auch möglich, ein JPanel zurückzugeben, welches ein JLabel und ein JButton beinhaltet. ;)
 
Hallo!

Ich möchte gerne in einer Zelle ein Label und einen Button anzeigen lassen
... dann leite doch einfach eine eigene Komponente von JComponent ab und platziere dann "intern" das JLabel und den JButton entsprechend... anschließend verwendest du Snapes vorgeschlagene Methode und überschreibst
public Component getTableCellRendererComponent(...)
entsprechend -> gib dort für die "passende" Zelle deine eigene Komponente zurück.

Gruß Tom
 
Hi,
danke erst einmal. Ich habe jetzt die Anzeige so hinbekommen, allerdings funkioniert jetzt mein MouseListener nicht mehr (er funktioniert überall und nicht nur bei den Buttons). Außerdem lassen sich die anderen Felder jetzt nicht mehr editieren.
Habe mal den Code beigefügt:
Code:
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

class JTableButtonRenderer implements TableCellRenderer 
{
  private TableCellRenderer defaultRenderer;

  public JTableButtonRenderer(TableCellRenderer renderer) 
  {
    defaultRenderer = renderer;
  }

  public Component getTableCellRendererComponent(JTable table, Object value,
						 boolean isSelected,
						 boolean hasFocus,
						 int row, int column)
  {
    if(value instanceof MyTableComponent) return (MyTableComponent)value;
    return defaultRenderer.getTableCellRendererComponent(
	   table, value, isSelected, hasFocus, row, column);
  }
}


class MyTableComponent extends JPanel
{
	public MyTableComponent(String labelName)
	{
		add(new JLabel(labelName));
		add(new JButton("..."));
	}
}


class JTableButtonModel extends AbstractTableModel 
{
  private Object[][] __rows = 
  {
      { "hi", new MyTableComponent("C:/images") },
      { "ha", new MyTableComponent("C:/images")},
      { "ho", new MyTableComponent("C:/images") },
      { "yeah", new MyTableComponent("C:/images") }
  };

  private String[] __columns = { "Numbers", "Buttons" };

  public String getColumnName(int column) 
  { 
    return __columns[column];
  }

  public int getRowCount() {
    return __rows.length;
  }

  public int getColumnCount() {
    return __columns.length;
  }

  public Object getValueAt(int row, int column) { 
      return __rows[row][column];
  }

  public boolean isCellEditable(int row, int column) {
    return false;
  }

  public Class getColumnClass(int column) {
    return getValueAt(0, column).getClass();
  }
}

class JTableButtonMouseListener implements MouseListener 
{
  private JTable __table;

  private void __forwardEventToButton(MouseEvent e) 
  {
    TableColumnModel columnModel = __table.getColumnModel();
    int column = columnModel.getColumnIndexAtX(e.getX());
    int row    = e.getY() / __table.getRowHeight();
    Object value;
    JButton button;
    MouseEvent buttonEvent;

    if(row >= __table.getRowCount() || row < 0 ||
       column >= __table.getColumnCount() || column < 0)
      return;

    value = __table.getValueAt(row, column);

    if(!(value instanceof JButton))
      return;

    button = (JButton)value;
    buttonEvent =
      (MouseEvent)SwingUtilities.convertMouseEvent(__table, e, button);
    button.dispatchEvent(buttonEvent);
    
    // This is necessary so that when a button is pressed and released
    // it gets rendered properly.  Otherwise, the button may still appear
    // pressed down when it has been released.
    __table.repaint();
  }

  public JTableButtonMouseListener(JTable table) {
    __table = table;
  }

  public void mouseClicked(MouseEvent e) 
  {
    System.out.println("foo");
  	__forwardEventToButton(e);
  }

  public void mouseEntered(MouseEvent e) {
    __forwardEventToButton(e);
  }

  public void mouseExited(MouseEvent e) {
    __forwardEventToButton(e);
  }

  public void mousePressed(MouseEvent e) 
  {
  	__forwardEventToButton(e);
  }

  public void mouseReleased(MouseEvent e) {
    __forwardEventToButton(e);
  }
}

public final class JTableButton extends JFrame 
{
  private JTable table;
  private JScrollPane scrollPane;

  public JTableButton() 
  {
    super("JTableButton Demo");
    TableCellRenderer defaultRenderer;

    table = new JTable(new JTableButtonModel());
    table.setRowHeight( table.getRowHeight() + 20 );
    defaultRenderer = table.getDefaultRenderer(MyTableComponent.class);
    table.setDefaultRenderer(MyTableComponent.class,
			       new JTableButtonRenderer(defaultRenderer));
    table.setPreferredScrollableViewportSize(new Dimension(400, 200));
    table.addMouseListener(new JTableButtonMouseListener(table));

    scrollPane = new JScrollPane(table);
    setContentPane(scrollPane);
  }

  public static void main(String[] args) 
  {
    Frame frame;
    WindowListener exitListener;

    exitListener = new WindowAdapter() 
	{
      public void windowClosing(WindowEvent e) 
      {
		Window window = e.getWindow();
		window.setVisible(false);
		window.dispose();
		System.exit(0);
      }
    };

    frame = new JTableButton();
    frame.addWindowListener(exitListener);
    frame.pack();
    frame.setVisible(true);
  }
}

Vielleicht habt ihr ja noch ne Idee? Ich mach mir erst einmal nen Kaffee :confused:
 
Also habe ja das Problem mit dem MouseListener.
Ich habe jetzt den MouseListener nochmal überarbeitet und jetzt bekomme ich auch ein Event, wenn man auf mein von JPanel abgeleitetes Klassenelement klickt. Ich hatte zwar das Problem, dass ich immer mehrmals den Event erhielt wegen, press, release und click aber nun gehts.
Das Problem ist nur, ich finde diese Methode so etwas von häßlich, das ich eigentlich nicht damit leben will.
Habt ihr noch andere Vorschläge?

Hier nochmal der MouseListener
Code:
	class JTableButtonMouseListener implements MouseListener 
	{
	  private JTable table;
	  private TableFileChooser tfc;

	  public JTableButtonMouseListener(JTable table) 
	  {
	  	this.table = table;
	  }
	  
	  private void forwardEventToButton(MouseEvent e) 
	  {
	    TableColumnModel columnModel = this.table.getColumnModel();
	    int column = columnModel.getColumnIndexAtX(e.getX());
	    int row    = e.getY() / this.table.getRowHeight();
	    Object value;
	    
	    MouseEvent tfcEvent;

	    if(row >= this.table.getRowCount() || row < 0 ||
	       column >= this.table.getColumnCount() || column < 0)
	    {
	    	return;
	    }

	    value = this.table.getValueAt(row, column);

	    if(!(value instanceof TableFileChooser))
	    {
	    	return;
	    }
	    else
	    {
	    	tfc = (TableFileChooser) value;
		    tfcEvent = (MouseEvent)SwingUtilities.convertMouseEvent(this.table, e, tfc);
		    if (tfc instanceof TableFileChooser && e.getButton() == MouseEvent.BUTTON1)
		    {
		    	System.out.println("alles klar");
		    	tfc.dispatchEvent(tfcEvent);
			    this.table.repaint();
		    }
	    }
	  }
	  		  
	  public void mouseClicked(MouseEvent e) 
	  {
	    forwardEventToButton(e);
	  }

	  public void mouseEntered(MouseEvent e) {
	    //forwardEventToButton(e);
	  }

	  public void mouseExited(MouseEvent e) {
	    //forwardEventToButton(e);
	  }

	  public void mousePressed(MouseEvent e) 
	  {
	  	//forwardEventToButton(e);
	  }

	  public void mouseReleased(MouseEvent e) {
	    //forwardEventToButton(e);
	  }
	}
bis denne
 
hallo
ich habe eine Prob wenn ich etwas in der Zellen meiner Tabelle schreibe und die Zelle ändere dann bleibt die Änderung nicht erhalten wie kann ich das vermeiden
 
Ferndiagnosen ohne Code sind natürlich immer schwierig. Aber das Verhalten lässt mich vermuten, dass etwas mit Deiner setValueAt() und/oder getValueAt() Methode nicht stimmt.
 
Zurück