JTable - Verschiedene Komponenten in einer Spalte unterbringen

Bartertown

Mitglied
Hallo zusammen,

Ich möchte gerade einen speziellen JTable darstellen.
Gemäß dem MVC - Muster findet auch eine Trennung zwischen Model und View statt.
Um praktisch mehr Einfluß auf die Darstellung des Tables zu nehmen,
wird ein eigenes Model erzeugt, dass AbstractTableModel implementiert.
In der überschriebenen Methode
Java:
public Class<? extends Object> getColumnClass(int columnIndex)//..
wird dafür gesorgt, dass die Classe des jeweiligen Spalteninhalts zurückgegeben wird,
damit der JTable nach Klasse selektiert die Darstellung vornimmt.

Was ist jetzt, wenn ich verschiedene Inhalte innerhalb einer Spalte darstellen will?
Nachfolgender Code soll das veranschaulichen, da ich 3 verschiedene Komponenten habe, die ich jetzt in 3 Tabellen darstelle.
Mein Ziel ware es die verschiedenen Komponenten in einer Spalte darzustellen.

Danke und viele Grüße


Java:
import java.awt.Component;
import java.awt.GridLayout;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;

public class BookTableMain {

    public static void main(String[] args) {
    new BookTableMain().initComponents();
    }

    private void initComponents() {
    JFrame f = new JFrame();
    f.add(new JScrollPane(createPanelWithTables()));
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.pack();
    f.setVisible(true);

    }

    /*
     * TODO Die verschiedenen Objekte in einer Tabelle darstellen
     */
    private JPanel createPanelWithTables() {
    JPanel panel = new JPanel();
    panel.setLayout(new GridLayout(3, 1));
    panel.add(createFirstTable());
    panel.add(createSecondTable());
    panel.add(createThirdTable());
    return panel;
    }

    private JTable createFirstTable() {
    Vector<Vector<Object>> tableData = new Vector<Vector<Object>>();

    Vector<Object> rowData = new Vector<Object>();
    rowData.add("Meerblick");
    rowData.add(new Boolean(false));

    tableData.add(rowData);

    return new JTable(new MyAbstractTableModel(tableData));
    }

    private JTable createSecondTable() {
    Vector<Vector<Object>> tableData = new Vector<Vector<Object>>();

    Vector<Object> rowData = new Vector<Object>();
    rowData.add("Zimmer");
    rowData.add(new Integer(1));

    tableData.add(rowData);

    return new JTable(new MyAbstractTableModel(tableData));
    }

    private JTable createThirdTable() {
    Vector<Vector<Object>> tableData = new Vector<Vector<Object>>();

    Vector<Object> rowData = new Vector<Object>();
    rowData.add("Preis ermitteln");
    rowData.add(new JButton());

    tableData.add(rowData);
    JTable table = new JTable(new MyAbstractTableModel(tableData));
    table.setDefaultRenderer(JButton.class, new JButtonRenderer());
    return table;
    }

    /*
     * *** Table-Model ***
     */

    @SuppressWarnings("serial")
    private class MyAbstractTableModel extends AbstractTableModel {

    private Vector<Vector<Object>> tableData;

    public MyAbstractTableModel(Vector<Vector<Object>> tableData) {
        this.tableData = tableData;
    }

    @Override
    public Class<? extends Object> getColumnClass(int columnIndex) {
        return tableData.get(0).get(columnIndex).getClass();
    }

    @Override
    public void setValueAt(Object obj, int rowIndex, int columnIndex) {
        tableData.get(rowIndex).set(columnIndex, obj);
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return columnIndex == 1;
    }

    // inherit from AbstractTableModel
    @Override
    public int getRowCount() {
        return tableData.size();
    }

    @Override
    public int getColumnCount() {
        return 2;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return tableData.get(rowIndex).get(columnIndex);
    }

    }

    /*
     * *** Renderer für JButton ***
     */

    @SuppressWarnings("serial")
    private class JButtonRenderer extends JButton implements TableCellRenderer {

    public JButtonRenderer() {
        super();
    }

    @Override
    public Component getTableCellRendererComponent(JTable table,
        Object value, boolean isSelected, boolean hasFocus, int row,
        int column) {
        if (value instanceof JButton) {
        return this;
        } else
        return null;
    }
    }

}
 
In Swing ist so ziemlich alles möglich😉

Was du wohl beabsichtigst, ist die Möglichkeit INNERHALB einer JTable eine weitere JTable anzuzeigen.

Und wie bei allen Anforderungen eine Spalte geeignet anzuzeigen, geht dies über einen geeigneten TableCellRenderer.

Hier ist ein Link der es beschreibt.
 
Danke turtle,

In dem Tutorial zu dem Link wurde gezeigt wie man in einer Zelle mehr Daten einfügen kann, indem man an dieser Zellenstelle ein Array setzt.
In meinen Fall füge ich einfach eine JTable in die Zelle.

Ich habe dann eine Sammeltabelle mit 1 Spalte und 3 Reihen.
Jede Reihe enthält eine JTable.
Für die Darstellung der JTable wird ein einfacher "TableRenderer" geschrieben.

Somit kann ich nun eine Tabelle darstellen, die verschiedene Werte innerhalb einer (äußeren) Spalte hat. 😀


PS: Allerdings gibt es noch eine Schwierigkeit mit der Editierbarkeit, weil die vorige Implementierung von isCellEditable() nun keinen Effekt mehr hat...

Java:
import java.awt.Component;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;

public class MainTableBar {

    private JTable tablebar;

    public static void main(String[] args) {
	new MainTableBar().initComponents();
    }

    private void initComponents() {
	JFrame f = new JFrame();
	f.add(new JScrollPane(createTableBar()));
	f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	f.pack();
	f.setVisible(true);

    }

    /*
     * Die verschiedenen Tabellen in einer Tabelle darstellen
     */
    private JTable createTableBar() {
	Vector<Vector<Object>> tableBarData = new Vector<Vector<Object>>();

	Vector<Object> rowData = new Vector<Object>();
	rowData.add(createFirstTable());

	Vector<Object> rowData2 = new Vector<Object>();
	rowData2.add(createSecondTable());

	Vector<Object> rowData3 = new Vector<Object>();
	rowData3.add(createThirdTable());

	tableBarData.add(rowData);
	tableBarData.add(rowData2);
	tableBarData.add(rowData3);

	tablebar = new JTable(new MyAbstractTableModel(tableBarData));
	tablebar.setDefaultRenderer(JTable.class, new JTableRenderer());
	return tablebar;
    }

    private JTable createFirstTable() {
	Vector<Vector<Object>> tableData = new Vector<Vector<Object>>();
	Vector<Object> rowData = new Vector<Object>();
	rowData.add("Meerblick");
	rowData.add(new Boolean(false));
	tableData.add(rowData);
	return new JTable(new MyAbstractTableModel(tableData));
    }

    private JTable createSecondTable() {
	Vector<Vector<Object>> tableData = new Vector<Vector<Object>>();
	Vector<Object> rowData = new Vector<Object>();
	rowData.add("Zimmer");
	rowData.add(new Integer(1));
	tableData.add(rowData);
	return new JTable(new MyAbstractTableModel(tableData));
    }

    private JTable createThirdTable() {
	Vector<Vector<Object>> tableData = new Vector<Vector<Object>>();
	Vector<Object> rowData = new Vector<Object>();
	rowData.add("Preis ermitteln");
	rowData.add(new JButton());
	tableData.add(rowData);
	JTable table = new JTable(new MyAbstractTableModel(tableData));
	// Der Renderer für JButton wird im TableRenderer gesetzt
	// table.setDefaultRenderer(JButton.class, new JButtonRenderer());
	return table;
    }

    /*
     * *** Table-Model ***
     */

    @SuppressWarnings("serial")
    private class MyAbstractTableModel extends AbstractTableModel {

	private Vector<Vector<Object>> tableData;

	public MyAbstractTableModel(Vector<Vector<Object>> tableData) {
	    this.tableData = tableData;
	}

	@Override
	public Class<? extends Object> getColumnClass(int columnIndex) {
	    return tableData.get(0).get(columnIndex).getClass();
	}


	// inherit from AbstractTableModel
	@Override
	public int getRowCount() {
	    return tableData.size();
	}

	@Override
	public int getColumnCount() {
	    return tableData.get(0).size();
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
	    return tableData.get(rowIndex).get(columnIndex);
	}

    }

    /*
     * *** Renderer für JTable ***
     */

    private class JTableRenderer implements TableCellRenderer {

	@Override
	public Component getTableCellRendererComponent(JTable table,
		Object value, boolean isSelected, boolean hasFocus, int row,
		int column) {
	    if (value instanceof JTable) {

		// Wenn sonst keine Komponenten zu rendern sind:
		// return new JTable(((JTable) value).getModel());

		JTable renderTable = new JTable(((JTable) value).getModel());
		renderTable.setDefaultRenderer(JButton.class,
			new JButtonRenderer());
		return renderTable;

	    } else
		return null;
	}
    }

    /*
     * *** Renderer für JButton ***
     */

    @SuppressWarnings("serial")
    private class JButtonRenderer extends JButton implements TableCellRenderer {

	public JButtonRenderer() {
	    super();
	}

	@Override
	public Component getTableCellRendererComponent(JTable table,
		Object value, boolean isSelected, boolean hasFocus, int row,
		int column) {
	    if (value instanceof JButton) {
		return this;
	    } else
		return null;
	}
    }

}
 
[EDIT]Bei dieser Verschachtelung konnte man die einzelnen Tabellen, die in der Gesamttabelle waren nicht editieren [/EDIT]
Um die JTable Zellen zu editieren, muss man noch einen einfachen TableCellEditor schreiben:

Code:
public class JTableEditor extends AbstractCellEditor implements
	    TableCellEditor {

	// Implement the one method defined by TableCellEditor.
	@Override
	public Component getTableCellEditorComponent(JTable table,
		Object value, boolean isSelected, int row, int column) {
	    ((JTable) value).setCellSelectionEnabled(true);
	    return (Component) value;
	}

	// Implement the one CellEditor method that AbstractCellEditor doesn't
	@Override
	public Object getCellEditorValue() {
	    // TODO Auto-generated method stub
	    return null;
	}

    }

package tablebar;

import java.awt.Component;
import java.util.Vector;

import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class MainTableBar {

private JTable tablebar;

public static void main(String[] args) {
new MainTableBar().initComponents();
}

private void initComponents() {
JFrame f = new JFrame();
f.add(createTableBar());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400,400);
f.setVisible(true);

}

/*
* Die verschiedenen Tabellen in einer Tabelle darstellen
*/
private JTable createTableBar() {
Vector<Vector<Object>> tableBarData = new Vector<Vector<Object>>();

Vector<Object> rowData = new Vector<Object>();
rowData.add(createFirstTable());

Vector<Object> rowData2 = new Vector<Object>();
rowData2.add(createSecondTable());

Vector<Object> rowData3 = new Vector<Object>();
rowData3.add(createThirdTable());

tableBarData.add(rowData);
tableBarData.add(rowData2);
tableBarData.add(rowData3);

tablebar = new JTable(new MyAbstractTableBarModel(tableBarData));
tablebar.setDefaultRenderer(JTable.class, new JTableRenderer());
tablebar.setDefaultEditor(JTable.class, new JTableEditor());
return tablebar;
}

private JTable createFirstTable() {
Vector<Vector<Object>> tableData = new Vector<Vector<Object>>();

Vector<Object> rowData = new Vector<Object>();
rowData.add("Meerblick");
rowData.add(new Boolean(false));

tableData.add(rowData);

return new JTable(new MyAbstractTableModel(tableData));
}

private JTable createSecondTable() {
Vector<Vector<Object>> tableData = new Vector<Vector<Object>>();

Vector<Object> rowData = new Vector<Object>();
rowData.add("Zimmer");
rowData.add(new Integer(1));

tableData.add(rowData);

return new JTable(new MyAbstractTableModel(tableData));
}

private JTable createThirdTable() {
Vector<Vector<Object>> tableData = new Vector<Vector<Object>>();

Vector<Object> rowData = new Vector<Object>();
rowData.add("Preis ermitteln");
rowData.add(new JButton());

tableData.add(rowData);
JTable table = new JTable(new MyAbstractTableModel(tableData));
// Der Renderer für JButton wird im TableRenderer gesetzt
// table.setDefaultRenderer(JButton.class, new JButtonRenderer());
return table;
}

/*
* *** Table-Model ***
*/
// Table Bar Model
@SuppressWarnings("serial")
private class MyAbstractTableBarModel extends AbstractTableModel {

private Vector<Vector<Object>> tableData;

public MyAbstractTableBarModel(Vector<Vector<Object>> tableData) {
this.tableData = tableData;
}

@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}

@Override
public Class<? extends Object> getColumnClass(int columnIndex) {
return tableData.get(0).get(columnIndex).getClass();
}

@Override
public int getRowCount() {
return tableData.size();
}

@Override
public int getColumnCount() {
return tableData.get(0).size();
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return tableData.get(rowIndex).get(columnIndex);
}

}

// TableModel
@SuppressWarnings("serial")
private class MyAbstractTableModel extends AbstractTableModel {

private Vector<Vector<Object>> tableData;

public MyAbstractTableModel(Vector<Vector<Object>> tableData) {
this.tableData = tableData;
}

@Override
public Class<? extends Object> getColumnClass(int columnIndex) {
return tableData.get(0).get(columnIndex).getClass();
}

@Override
public void setValueAt(Object obj, int rowIndex, int columnIndex) {
tableData.get(rowIndex).set(columnIndex, obj);
}

@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}

// inherit from AbstractTableModel
@Override
public int getRowCount() {
return tableData.size();
}

@Override
public int getColumnCount() {
return tableData.get(0).size();
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return tableData.get(rowIndex).get(columnIndex);
}

}

/*
* *** Renderer für JTable ***
*/

private class JTableRenderer implements TableCellRenderer {

@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
if (value instanceof JTable) {

// Wenn sonst keine Komponenten zu rendern sind:
// return new JTable(((JTable) value).getModel());

JTable renderTable = (JTable) value;
renderTable.setDefaultRenderer(JButton.class,
new JButtonRenderer());
return renderTable;

} else
return null;
}
}

/*
* *** Renderer für JButton ***
*/

@SuppressWarnings("serial")
private class JButtonRenderer extends JButton implements TableCellRenderer {

public JButtonRenderer() {
super();
}

@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
if (value instanceof JButton) {
return this;
} else
return null;
}
}

/*
* Editor für TableBar
*/

@SuppressWarnings("serial")
public class JTableEditor extends AbstractCellEditor implements
TableCellEditor {

// Implement the one method defined by TableCellEditor.
@Override
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
((JTable) value).setCellSelectionEnabled(true);
return (Component) value;
}

// Implement the one CellEditor method that AbstractCellEditor doesn't
@Override
public Object getCellEditorValue() {
// TODO Auto-generated method stub
return null;
}

}
}
 

Neue Themen


Zurück
Oben