Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Guten Morgen, auch wenns bei mir orkanartig regnet,
gibts irgendein Beispiel im Netz, wo ein JButton in einer Zelle einer JTable ist?? Hab noch nicht s gefunden und hab jetzt auch keine Idee, ob ich da ein JPanel in die Zelle legen muss und dann den JButton drauf oder geht das direkt?
Ich habe dir mal versucht ein einfaches Beispiel zu schreiben
Als erstes brauchst du einen Renderer der dir den Button anzeigt auf der Tabelle:
Code:
public class JButtonRenderer extends DefaultTableCellRenderer {
/**
*
*/
private static final long serialVersionUID = -4853509522303880332L;
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
return ((JButton)value);
}
}
Des Weiteren braucht du einen Editor damit du auch auf den Button klicken kannst:
Code:
public class MyTableEditor extends DefaultCellEditor {
/**
*
*/
private static final long serialVersionUID = 3052947778058597660L;
public MyTableEditor(JTextField textField) {
super(textField);
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
return (JButton)value;
}
}
Als nächstes musst du JTable überschreiben und dort einen MouseMotionListener ranhängen ohne diesen müsstest du einen doppelklick auf den Button machen damit er ausgelöst wird. Wenn du das möchtest dann brauchst du JTable nicht zu überschreiben sondern einfach nur eine JTable nutzen:
Code:
public class MyTable extends JTable implements MouseMotionListener{
/**
*
*/
private static final long serialVersionUID = -7985913044410714472L;
public MyTable(MyTableModel model) {
super(model);
addMouseMotionListener(this);
}
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseMoved(MouseEvent me) {
int col = ((TableColumnModel)getColumnModel()).getColumnIndexAtX(me.getX());
if (col == 1)
{
editCellAt(rowAtPoint(me.getPoint()), ((TableColumnModel)getColumnModel()).getColumnIndexAtX(me.getX()));
}
}
}
Dann brauchst du noch ein TableModel welches die Daten hält und sagt welche Klasse sich in welcher Spalte befindet
sonst weis der Rendere nicht um was für eine Klasse es sich handelt:
Code:
public class MyTableModel extends AbstractTableModel {
/**
*
*/
private static final long serialVersionUID = -9181487403748353628L;
private Vector<String> s = new Vector<String>();
private Vector<JButton> b = new Vector<JButton>();
public MyTableModel() {
createTestDaten();
}
private void createTestDaten(){
s.add("Button1");
s.add("Button2");
s.add("Button3");
s.add("Button4");
b.add(new JButton("Erster"));
b.add(new JButton("Zweiter"));
b.add(new JButton("Dritter"));
b.add(new JButton("Vierter"));
}
public int getColumnCount() {
return 2;
}
public int getRowCount() {
return s.size();
}
@Override
public Class<?> getColumnClass(int columnIndex) {
if (columnIndex == 0)
{
return String.class;
}
else if (columnIndex == 1)
{
return JButton.class;
}
else
{
return super.getColumnClass(columnIndex);
}
}
public Object getValueAt(int rowIndex, int columnIndex) {
if (columnIndex == 0)
{
return s.elementAt(rowIndex);
}
else
{
return b.elementAt(rowIndex);
}
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
}
Das ganze noch zusammenbasteln, auf einen Frame legen und starten:
Code:
public class Main {
public static void main(String[] args) {
MyTable table = new MyTable(new MyTableModel());
table.setDefaultRenderer(JButton.class, new JButtonRenderer());
table.setDefaultEditor(JButton.class, new MyTableEditor(new JTextField()));
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(table);
frame.setSize(new Dimension(200,100));
frame.setVisible(true);
}
}
Ich hoffe das Beispielt hilft dir weiter und ist gut zu verstehen
Mein Problem ist aber noch, dass ich schon einen TableRenderer habe der so wie unten aussiet und ich das auch beibehalten möchte, ich möchte nur in der letzten Spalte einen JButton (also eine JComponent haben)
Code:
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
JLabel label = new JLabel((String)value);
label.setOpaque(true);
Border b = BorderFactory.createEmptyBorder(1, 1, 1, 1);
label.setBorder(b);
label.setFont(table.getFont());
label.setForeground(table.getForeground());
label.setBackground(table.getBackground());
if (hasFocus) {
label.setBackground(new Color( 64, 64, 128));
label.setForeground(Color.white);
} else if (isSelected) {
label.setBackground(new Color(160, 160, 255));
} else {
label.setHorizontalAlignment(JLabel.CENTER);
}
}
}
return label;
}
Eine Frage hätte ich noch, ich hab jetzt die JButtons in meiner JTable ganz rechts in der letzten Spalte, wenn ich nun einen JButton in einer Zeile drücke, dann soll diese Zeile makiert werden und in der Zeile etwas passieren,
Wenn alle Zellen in einer Zeile automatisch (durch mein Programm) voll werden, dann wird diese Zeile removed, Auch liste ich die Einträge rückwärts auf (die neuesten Einträge sind oben),
Wie könnte ich jetzt herausfinden, in welcher Zeile ich den JButton drücke.
Ich habe schon versucht, beim hinzufügen der JButtons mit setName(x) Namen nach der Reihenfolge zu vergeben aber das funktioniert nicht, da sich ja Zeilen automatisch löschen bzw. wenn ich mit einem JButton die dazugehörende Zeile vervollständige, dann wird diese Zeile auch gelöscht und die Reihenfolge, die ich mit setName den JButtons zugeordnet habe, funktioniert nicht mehr,
Könnte mir jemand noch kurz erklären, wie das mit dem Beispiel oben geht (Link)
Ich muss also das Interface CellEditor implementieren und bei der Methode shouldSelectCell true zurückgeben, was ich aber in der actionPerformed(..) - Methode machen muss, das ist mir nicht klar, wie ich in der Methode actionPerformed das invokeLater und table.getSelectedRow bzw. table.getSelectedColumn implemetiere.
Wäre sehr dank bar für Eure Hilfe!!
lg
Code:
public boolean shouldSelectCell(EventObject anEvent)
{
return true;
}
dann habe ich alle Methoden von CellEditor implementiert:
Code:
public Object getCellEditorValue() {
return null;
}
public boolean isCellEditable(EventObject anEvent) {
return false;
}
public boolean shouldSelectCell(EventObject anEvent)
{
return true;
}
public boolean stopCellEditing() {
return false;
}
public void cancelCellEditing()
{
}
public void addCellEditorListener(CellEditorListener l)
{
}
public void removeCellEditorListener(CellEditorListener l)
{
}
und dann habe ich in meiner actionPerformed()- Methode geschrieben:
Code:
if (e.getActionCommand().equals("button1"))
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
int row = tableList[1].getSelectedRow();
int column = tableList[1].getSelectedColumn();
System.out.println("Ausgabe: " + row + ", " + column);
}
});
Nur muss ich jetzt eine Zeile selektieren, damit ich die Zeile und die Spale in der actionPerformed- Methode bekomme Wie kann ich es machen, dass ich keine Zeile selektiere und trotzdem die Zeile des gedrückten JButtons in der JTable bekomme,
Versuch's mal so:
Kopier erstmal das Beispiel. Du brauchst im Wesentlichen gar nix anzupassen. Das heisst:
1. Lass die anonyme Unterklasse von JTable so wie sie ist, mit ihren Methoden getCellRenderer und getCellEditor.
2. Lass den DefaultRenderer und DefaultEditor für die JComponent Klasse gesetzt.
3. Lass die Klassen "JComponentCellRenderer" und "JComponentCellEditor" genau so wie sie sind
(bei shouldSelectCell änderst du lediglich die Zeile "return false;" auf "return true;").