JTable, JButton und CellEditor



  • Hi,

    ich hätte da gern ein Problem. Ich möchte Ein Button zu einem JTable hinzufügen und die Actions ordentlich handlen.
    Gegeben ist eine Tabelle mit beliebig vielen Zeilen, eine Spalte besteht aus JButtons.

    Also in der Theorie schreibe ich ein CellEditor:
    [java]
    public class CustomCellEditor
    extends AbstractCellEditor implements TableCellEditor
    {
    .
    .
    .
    public CustomCellEditor(JButton button)
    {
    editor = button;
    editor.setContentAreaFilled(true);
    }

    public Component getTableCellEditorComponent(
    JTable table, Object value,
    boolean isSelected,
    int row, int column)
    {
    this.value = value;

    editor.setText(value == null ? "" : value.toString());
    editor.setForeground(table.getForeground());
    return editor;
    }
    .
    .
    .
    }[/code]

    und einen CellRenderer
    [java]
    class ButtonRenderer extends JButton
    implements TableCellRenderer
    {
    .
    .
    .
    public Component getTableCellRendererComponent(JTable table, Object value,
    boolean selected, boolean focused,
    int row, int column)
    {
    setText(value == null ? "" : value.toString());
    this.focused = focused;
    return this;
    }
    }
    .
    .
    .
    }[/code]

    So weit, so all right. Die Darstellung funzt. Eigenartiges Verhalten beim klicken auf die Buttons. Ist die Zeile der Tabelle wo sich der anzuklickende Button befindet selektier läßt sich der Button eindrücken ist sie aber nicht selektiert so drückt er sich nur bei jedem zweiten klick ein.

    D.h. klickt man auf eine nicht markierte Zeile direkt auf den Button funzt es erst mal net. Klickt man nun ein zweites mal in einer nicht markierten Zeile auf ein Button, so läßt er sich eindrücken

    Scheint mir buggy, oder hab ich was übersehen?

    Getestet mit JDK1.4

    thx, O'Dog

    [ Dieser Beitrag wurde am 17.06.2002 um 19:50 Uhr von O'Dog editiert. ]



  • Hi O'Dog!

    Gibt es da nicht soetwas wie einen TableListener oder TableModelListener o.ä.? Vielleicht musst du mit so einem arbeiten, das Event abfangen und anschließend an deinen Button weiterleiten. Ist nur eine Vermutung meinerseits. Vielleicht konnte ich dich ja in eine sinnvolle Richtung schubsen 🙂

    cu
    Stefan



  • Hi,

    versuchs mal mit diesem super-kommentierten Code 🙂

    [java]import java.awt.;
    import java.awt.event.
    ;
    import javax.swing.;
    import javax.swing.table.
    ;

    public class JButtonTableExample extends JFrame {

    public JButtonTableExample(){
    super( "JButtonTable Example" );

    DefaultTableModel dm = new DefaultTableModel();
    dm.setDataVector(new Object[][]{{"btnFoo","foo"},
    {"btnBar","bar"}},
    new Object[]{"Button","String"});

    JTable table = new JTable(dm);
    table.getColumn("Button").setCellRenderer(new ButtonRenderer());
    table.getColumn("Button").setCellEditor(new ButtonEditor(new JCheckBox()));
    JScrollPane scroll = new JScrollPane(table);
    getContentPane().add( scroll );
    setSize( 400, 100 );
    setVisible(true);
    }

    public static void main(String[] args) {
    JButtonTableExample frame = new JButtonTableExample();
    frame.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    }
    });
    }
    }

    class ButtonRenderer extends JButton implements TableCellRenderer {

    public ButtonRenderer() {
    setOpaque(true);
    }

    public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean hasFocus, int row, int column) {
    if (isSelected) {
    setForeground(table.getSelectionForeground());
    setBackground(table.getSelectionBackground());
    } else{
    setForeground(table.getForeground());
    setBackground(UIManager.getColor("Button.background"));
    }
    setText( (value ==null) ? "" : value.toString() );
    return this;
    }
    }

    class ButtonEditor extends DefaultCellEditor {
    protected JButton button;
    private String label;
    private boolean isPushed;

    public ButtonEditor(JCheckBox checkBox) {
    super(checkBox);
    button = new JButton();
    button.setOpaque(true);
    button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    fireEditingStopped();
    }
    });
    }

    public Component getTableCellEditorComponent(JTable table, Object value,
    boolean isSelected, int row, int column) {
    if (isSelected) {
    button.setForeground(table.getSelectionForeground());
    button.setBackground(table.getSelectionBackground());
    } else{
    button.setForeground(table.getForeground());
    button.setBackground(table.getBackground());
    }
    label = (value ==null) ? "" : value.toString();
    button.setText( label );
    isPushed = true;
    return button;
    }

    public Object getCellEditorValue() {
    if (isPushed) {
    JOptionPane.showMessageDialog(button, label + ": clicked!");
    }
    isPushed = false;
    return new String( label ) ;
    }

    public boolean stopCellEditing() {
    isPushed = false;
    return super.stopCellEditing();
    }

    protected void fireEditingStopped() {
    super.fireEditingStopped();
    }
    }[/code]

    Hope that helps!



  • Original erstellt von CengizS:
    **versuchs mal mit diesem super-kommentierten Code 🙂
    **

    Hi, ich bin tendenziell gegen übertriebenes Kommentieren im Code.
    Nur bei Hacks oder undurchsichtigen Codestellen. Von daher passt das schon 🙂

    Der Code funktioniert das liegt wohl an "fireEditingStopped" den du bei Action-Events von Buttons aufrufst. Wenn du das rausläßt hast du das Verhalten wie oben von mir beschrieben (teilweise nicht eingedrückte Buttons), anscheinend werden Button-Events der UI vom Table manchmal unterdrückt.

    Original erstellt von CengizS:
    Hope that helps!

    Jap

    bis dänn, O'Dog


Anmelden zum Antworten