JButton action is not performed inside of JTable - java

I got a simple JTable which one of it's cells is an Edit button which needs to open a new JDialog.
After a several examples from the web I created a new class which implements TableCellRenderer and returned a JButton from it but the button is not doing what I need for some reason.
This is my code:
final MessageResourcesTableModel model = new MessageResourcesTableModel(columnNames);
JTable resultsTable = new JTable(model);
resultsTable.setShowGrid(true);
resultsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
resultsTable.setPreferredScrollableViewportSize(resultsTable.getPreferredSize());
resultsTable.setFillsViewportHeight(true);
resultsTable.setFont(font13);
final TableCellRenderer buttonRenderer = new JTableButtonRenderer();
resultsTable.getColumn(COLUMN_EDIT).setCellRenderer(buttonRenderer);
And this is the renderer:
class JTableButtonRenderer implements TableCellRenderer {
#Override public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) {
final JButton editButton = new JButton("Edit");
editButton.setOpaque(true);
editButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
System.out.println("Hi from Action !!!");
}
});
return editButton;
}
}
Although there is a simple ActionListener implementation, there is nothing over the console

A renderer only displays the data in the cell. You can't add an ActionListener to the button because it is not a real component. A renderer only paints an image of the button in the table.
You need to create a custom editor if you want to be able to click on the button.
See Table Button Column for an editor implementation that does this for you.

Related

Adding JComboBox to JTable

I'm creating a JTable in Java & I'm asked to add to the table a JCheckBox, JButton and a JComboBox. The table that I created is displaying all the information, the button is working fine and the JCheckBox is also working, the problem I'm facing is that the JComboBox is not working. I really can't figure out why. I've tried to look the problem up but I can't figure it out. Can someone help me please?
The code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class sinX extends JFrame {
private JTable table;
private DefaultTableModel model;
private Object[][] data;
private String[] columnNames;
private JButton button;
JComboBox comboBox;
public sinX() {
comboBox = new JComboBox();
setTitle("Programming Languages");
data = new Object[][]{{"C","Dennis Ritchie",1972,false},{"C++","Bjarne Stroustrup",1983,true},
{"Python","Guido van Rossum",1991,false},{"Java","James Gosling",1995,true},{
"JavaScript","Brendan Eich",1995,true},{"C#","Anders Hejlsberg",2001,false},
{"Scala","Martin Odersky",2003,true}};
columnNames = new String[] {"Language","Author","Year","Check Box"};
//model = new DefaultTableModel(data, columnNames);
//table = new JTable(model);
//table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
final Class[] columnClass = new Class[] {
String.class, String.class, Integer.class, Boolean.class
};
//create table model with data
DefaultTableModel model = new DefaultTableModel(data, columnNames) {
#Override
public boolean isCellEditable(int row, int column)
{
return false;
}
#Override
public Class<?> getColumnClass(int columnIndex)
{
return columnClass[columnIndex];
}
};
table = new JTable(model);
table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
button = new JButton("Remove");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
// check for selected row first
if(table.getSelectedRow() != -1) {
// remove selected row from the model
model.removeRow(table.getSelectedRow());
JOptionPane.showMessageDialog(null, "Selected row deleted successfully");
}
}
});
TableColumn year = table.getColumnModel().getColumn(2);
comboBox.addItem("A");
comboBox.addItem("B");
comboBox.addItem("C");
comboBox.addItem("D");
year.setCellEditor(new DefaultCellEditor(comboBox));
add(new JScrollPane(table), BorderLayout.CENTER);
add(button, BorderLayout.SOUTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 500);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String args[]) {
new sinX();
}
}
the problem I'm facing is that the JComboBox is not working.
year.setCellEditor(new DefaultCellEditor(comboBox));
The above code indicates you are trying to use a combo box as an editor for the given column.
public boolean isCellEditable(int row, int column)
{
return false;
}
However, you have stated in your model that none of columns are editable.
You need to return true for any column where you want to edit the data.
the JCheckBox is also working
Not really. Yes you see the boolean value is rendered as a check box. However, you can't change its value by clicking on it, unless of course you return true for that column as well.

How to make the JComboBox dropdown always visible in a JTable

I'm using JComboBox with JTables, but the dropdown menu is only "visible" when it's clicked. How can I change this default behavior and make it always visible and user-friendly?
public void start(){
TableColumn column = table.getColumnModel().getColumn(0);
JComboBox comboBox = new JComboBox();
DefaultComboBoxModel model = new DefaultComboBoxModel();
model.addElement("a");
model.addElement("b");
comboBox.setModel(model);
}
As I understand it, you would like the cells to always look like JComboBoxes, and not jLabels.
This can easily be accomplished by adding a TableCellRenderer to your TableColumn.
Pasting in the following code should have the desired effect.
column.setCellRenderer(new TableCellRenderer() {
JComboBox box = new JComboBox();
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
box.removeAllItems();
box.addItem(value.toString());
return box;
}
});

JTable selection listener

I have a code which displays Table in applets & consists of two columns:-
image icon
description
Here's my code:
import javax.swing.table.*;
public class TableIcon extends JFrame
{
public TableIcon()
{
ImageIcon aboutIcon = new ImageIcon("about16.gif");
ImageIcon addIcon = new ImageIcon("add16.gif");
ImageIcon copyIcon = new ImageIcon("copy16.gif");
String[] columnNames = {"Picture", "Description"};
Object[][] data =
{
{aboutIcon, "About"},
{addIcon, "Add"},
{copyIcon, "Copy"},
};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
JTable table = new JTable( model )
{
// Returning the Class of each column will allow different
// renderers to be used based on Class
public Class getColumnClass(int column)
{
return getValueAt(0, column).getClass();
}
};
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane( table );
getContentPane().add( scrollPane );
}
public static void main(String[] args)
{
TableIcon frame = new TableIcon();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setVisible(true);
}
}
Now what i want to know is how can I implement selection listener or mouse listener event on my table , such that it should select a particular image from my table and display on text area or text field(my table contains path of image file)?
Can I add text field on table & table on frame? Please feel free to ask queries if required.
In my code I have a table where I set single selection mode; in my case, listener described in How to Write a List Selection Listener (with a for loop from getMinSelectionIndex to getMaxSelectionIndex) is not useful because releasing mouse button I'm sure I have just one row selected.
So I've solved as follows:
....
int iSelectedIndex =-1;
....
JTable jtable = new JTable(tableModel); // tableModel defined elsewhere
jtable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
ListSelectionModel selectionModel = jtable.getSelectionModel();
selectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
handleSelectionEvent(e);
}
});
....
protected void handleSelectionEvent(ListSelectionEvent e) {
if (e.getValueIsAdjusting())
return;
// e.getSource() returns an object like this
// javax.swing.DefaultListSelectionModel 1052752867 ={11}
// where 11 is the index of selected element when mouse button is released
String strSource= e.getSource().toString();
int start = strSource.indexOf("{")+1,
stop = strSource.length()-1;
iSelectedIndex = Integer.parseInt(strSource.substring(start, stop));
}
I think this solution, that does not require a for loop between start and stop to check which element is selectes, is more suitable when table is in single selection mode
How about this?
protected void handleSelectionEvent(ListSelectionEvent e) {
if (e.getValueIsAdjusting())
return;
final DefaultListSelectionModel target = (DefaultListSelectionModel)e.getSource();
iSelectedIndex = target.getAnchorSelectionIndex();
}
Read the section from the Swing tutorial on How to Write a List Selection Listener.
You can't add a text field to the table, but you can add a textfield and a table to the same frame.

save Jtable data when savebutton is pressed

I want to save Name and value of jtable into two variable
public class NewClass extends JPanel implements TableModelListener {
private final String[] columnNames = { "Name", "Value","check"};
private JTable table;
private DefaultTableModel tableModel;
private final JButton buttonSave;
public NewClass(){
tableModel = new DefaultTableModel(columnNames, 0);
tableModel.addTableModelListener(this);
table = new JTable(tableModel);
javax.swing.table.TableColumn var_col;
var_col = table.getColumnModel().getColumn(2);
final JCheckBox check = new JCheckBox();
var_col.setCellEditor(new DefaultCellEditor(check));
var_col.setCellRenderer(new DefaultTableCellRenderer() {
#Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int
column) {
check.setSelected(((Boolean)value).booleanValue()) ;
return check;
}
});
JScrollPane scrollPane = new JScrollPane(table);
setLayout(new BorderLayout());
setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
add(BorderLayout.NORTH, new JLabel("Mon panier", JLabel.CENTER));
add(BorderLayout.CENTER, scrollPane);
//--------I want to save these Name and value in two variables -----------
Object[] data1 = {
new String("work"), new String("done"),new Boolean(false)};
tableModel.addRow(data1);
buttonSave = new JButton("Save");
buttonSave.setEnabled(false);
buttonSave.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
buttonSave.setEnabled(false);
}
});
As discussed in How to Use Tables, your table's data should be managed by a TableModel such as AbstractTableModel or the concrete DefaultTableModel used in your example. In this example, DataModel extends AbstractTableModel and synthesizes a List<Value> of test data; yours would listen to whatever object monitors the serial port. The example also uses the class Value to encapsulate a selectable numeric value. The custom TableCellEditor updates each Value as it is changed, so the DataModel always contains the selection state of each element in the list. Your save button could then save the list elements in whatever format you prefer.

Adding button to a jtable

I am having a table in which i have to adda JButton.
I am doing
TableColumnModel colModel = table.getColumnModel();
colModel.getColumn(0).setCellEditor(new MYCellEditor(new JCheckbox()));
MyCellEditor extends DefaultCellEditor{
public MyCellEditor(JCheckbox checkbox){
super(checkbox);
Jbutton button = new JButton("Start");
//actionlistener for button.
}
}
MyRenderer extends DefaultTablecellRenderer{
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
//return a button for column ==0
}
My understanding is that the Celleditor has same instance of button for all cells in a column. So if i click on one button the text changes from "Start" to "stop" but if i click on button in other row it doesnt work.. After debugging it shows that the text is alreadt Stop .
How can i have different instance of button in each row ?
The article Table Button Column cited in #camickr's previous answer provides a more flexible solution, but you may find the tutorial How to Use Tables: Using Other Editors helpful, too. The ColorEditor discussed there is part of the TableDialogEditDemo, available via Java Web Start. You'll need to change the corresponding ColorRenderer accordingly.

Categories

Resources