Link to home
Start Free TrialLog in
Avatar of dshrenik
dshrenikFlag for United States of America

asked on

JButtons in a column

I am having trouble adding JButtons to a entire column of a JTable.

I have a 3X5 table, and I want the last column to all consist of buttons.

If possible, please provide some sample code. Thanks!
Avatar of for_yan
for_yan
Flag of United States of America image

It is probably ecven easiier to do it just using TableCellRenderer (I think we did GIFs with you in one of the  columns)
So the same idea , only the method returns Componet so you can check which column and return eiother label or button detpendning on the
column

this is not 3x5 but the fisrt column is buttons
ansd I made it from
http://www.roseindia.net/java/example/java/swing/CustomCellRenderer.shtml
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;

public class CustomCellRenderer{
  JTable table;
  TableColumn tcol;
  public static void main(String[] args) {
  new CustomCellRenderer();
  }

  public CustomCellRenderer(){
  JFrame frame = new JFrame("Creating a Custom Cell Reanderer!");
  JPanel panel = new JPanel();
  String data[][] = {{"Vinod","Computer","3"},
   {"Rahul","History","2"},
   {"Manoj","Biology","4"},
   {"Sanjay","PSD","5"}};
  String col [] = {"Name","Course","Year"};
  DefaultTableModel model = new DefaultTableModel(data,col);
  table = new JTable(model);
  tcol = table.getColumnModel().getColumn(0);
  tcol.setCellRenderer(new CustomTableCellRenderer());
  tcol = table.getColumnModel().getColumn(1);
  tcol.setCellRenderer(new CustomTableCellRenderer());
  tcol = table.getColumnModel().getColumn(2);
  tcol.setCellRenderer(new CustomTableCellRenderer());
  JTableHeader header = table.getTableHeader();
  header.setBackground(Color.yellow);
  JScrollPane pane = new JScrollPane(table);
  panel.add(pane);
  frame.add(panel);
  frame.setSize(500,150);
  frame.setUndecorated(true);
  frame.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  frame.setVisible(true);
  }

  public class CustomTableCellRenderer extends DefaultTableCellRenderer{
  public Component getTableCellRendererComponent (JTable table,
Object obj, boolean isSelected, boolean hasFocus, int row, int column) {
  //Component cell = super.getTableCellRendererComponent(
   //table, obj, isSelected, hasFocus, row, column);
      if(column == 0){
          JButton btn = new JButton(obj.toString());
          return btn;
      }
      else
      {
          JLabel lbl = new JLabel(obj.toString());
          return lbl;
      }

  }
}
}

Open in new window

Avatar of dshrenik

ASKER

That is working fine, but I cannot add actionlisteneres.
Why do you want to do it - we already were talking that it is better to get mosuseEvents form the table
then actionListeners form buttons inside the table
That's right, but the problem is I am using a smaller button that does not occupy the entire cell, and I want an action to be performed only when the user clicks the button and not anywhere in the cell.

I think you need to make Cell editable in table model
then it will listen to events
you need to override
public boolean isCellEditable(int row, int column) {
return true;
}
That did not work.
it is too complex - you can read about how to do it here,
but it is better to come up with simpler design:

http://www.devx.com/getHelpOn/10MinuteSolution/20425
ASKER CERTIFIED SOLUTION
Avatar of for_yan
for_yan
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yes, that article mostly leads tyo anlysing the position of moouse clicking - you can probably with that even figure out if it was clicked insde the button
inside the cell. The one form www.devx.com works, but it has the whole cell made up of button
(so that we again could have used that mouse.atPoint() method for simplicity instead).
In general it shows the way how to go to cells made up of custom element say containg label and button.
However it does not seem so strightforward to modify it to such components.
No, this www.devx.com does not give any other way either.
The problem is that JTable captures events - so you need then analyze
location of the event and then distinguish if that was on button or on
sioomething else in the same cell. It is probably possible but not so simple.

This is JTable with buttons within cells which responds only
to clicks on the buttons but not on the enclosing cell:

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

//this is taken from   http://stackoverflow.com/questions/3606864/jtable-buttons-in-custom-panel-in-cell/3606915#3606915
// but modified as it was not compiling

public class MyClassTable  {
    public static void main(String[] args) {


        ArrayList<MyClass>ar = new ArrayList<MyClass>();
        ar.add(new MyClass("a","b"));
        ar.add(new MyClass("c","d"));
         ar.add(new MyClass("e","f"));

        JTable myClassTable = new JTable(new MyClassTableModel(ar));
        myClassTable.setDefaultRenderer(MyClass.class, new MyClassCellRenderer());
        myClassTable.setDefaultEditor(MyClass.class, new MyClassCellEditor());
        myClassTable.setRowHeight(100);

        JFrame jf = new JFrame();
        jf.add(new JScrollPane(myClassTable));
        jf.setSize(300,330);
        jf.setVisible(true);


    }

}

class MyClassTableModel extends DefaultTableModel {
  ArrayList<MyClass> data;

  public MyClassTableModel(ArrayList<MyClass> data) {
    this.data = data;
  }

  public Class<?> getColumnClass(int columnIndex) {
      if(columnIndex ==0)
      return MyClass.class;
     else return String.class;}
  public int getColumnCount() { return 2; }
  public String getColumnName(int columnIndex) { if(columnIndex ==0) return "MyClass";
  else return "Just string";}
  public int getRowCount() { return (data == null) ? 0 : data.size(); }
  public Object getValueAt(int rowIndex, int columnIndex) {if(columnIndex ==0) return data.get(rowIndex);
  else return data.get(rowIndex).getString1();}
  public boolean isCellEditable(int rowIndex, int columnIndex) { return true; }
}


class MyClassCellComponent extends JPanel implements ActionListener {
  MyClass mc;
    JButton btn;
    JLabel lbl;

  public MyClassCellComponent(MyClass mc) {
      this.mc = mc;

        btn = new JButton(mc.getString1());
      btn.addActionListener(this);
    lbl = new JLabel(mc.getString2());

    this.setLayout(new FlowLayout());
    this.add(lbl);
    this.add(btn);


    // initialize components (labels, buttons, etc.)
    // add action listeners
  }

   public void actionPerformed (ActionEvent ae){
       System.out.println("click");
      if(ae.getSource() instanceof JButton){
         System.out.println(((JButton)ae.getSource()).getText());
      }

   }

  public void updateData(MyClass myClass, boolean isSelected, JTable table) {
    this.mc = myClass;
      btn.setText(myClass.getString1());
         lbl.setText(myClass.getString2());
    // update buttons, labels etc. accordingly
  }
}

class MyClassCellRenderer implements TableCellRenderer {


  public MyClassCellRenderer() {
  //  panel = new MyClassCellComponent();
  }

  public Component getTableCellRendererComponent(JTable table, Object value,        boolean isSelected, boolean hasFocus, int row, int column) {
      if(column == 0){
    MyClass myClass = (MyClass)value;
       MyClassCellComponent panel = new      MyClassCellComponent(myClass);
    panel.updateData(myClass, isSelected, table);
    return panel; }
      else{
          JLabel jl = new JLabel(value.toString());
          return jl;
      }

  }
}

class MyClassCellEditor extends AbstractCellEditor implements TableCellEditor{


  public MyClassCellEditor() {

    //panel = new MyClassCellComponent();
  }
  public Component getTableCellEditorComponent(JTable table, Object value,      boolean isSelected, int row, int column) {
                   if(column == 0){
    MyClass myClass = (MyClass)value;
       MyClassCellComponent panel = new      MyClassCellComponent(myClass);
    panel.updateData(myClass, true, table);
    return panel;
                   }
      else{
          JLabel jl = new JLabel(value.toString());
          return jl;
      }
  }
  public Object getCellEditorValue() {
    return null;
  }

   
   public boolean stopCellEditing() {
       return true;

   }


}

class MyClass {
    String s1;
    String s2;
    public MyClass(String s1, String s2){
        this.s1 = s1;
        this.s2 = s2;
    }
  public String getString1(){return s1;}
   public String getString2(){return s2;}


}

Open in new window