JTable, JComboBox - problems in showing JComboBox in second column - java

I have written this simple program:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class JcomboboxJtableDemo extends JPanel
implements ActionListener {
private DefaultTableModel tableModel;
JTable table = new JTable (tableModel);
private JScrollPane scrollpaneTable = new JScrollPane( table );
private JPanel PaneBottoniTabella = new JPanel( );
public JcomboboxJtableDemo() {
super(new BorderLayout());
String[] petStrings = { "Bird", "Cat", "Dog", "Rabbit", "Pig" };
JComboBox comboBox = new JComboBox(petStrings);
comboBox.setSelectedIndex(4);
tableModel = CreateTableModel();
tableModel.insertRow( 0, new Object[] {"Header col1", ""} );
tableModel.insertRow( 0, new Object[] {petStrings[0], ""} );
tableModel.insertRow( 0, new Object[] {petStrings[1], ""} );
tableModel.insertRow( 0, new Object[] {petStrings[2], ""} );
tableModel.insertRow( 0, new Object[] {petStrings[3], ""} );
tableModel.setValueAt("Header col2", 0, 1);
DefaultCellEditor editor = new DefaultCellEditor(comboBox);
table.getColumnModel().getColumn(0).setCellEditor(editor);
table.getColumnModel().getColumn(1).setCellEditor(editor);
//Lay out the demo.
add(comboBox, BorderLayout.PAGE_START);
add(table, BorderLayout.PAGE_END);
setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
}
private final DefaultTableModel CreateTableModel () {
DefaultTableModel modello = new DefaultTableModel( new Object[] { "Col1","Col2" }, 0 ) {
#Override
public boolean isCellEditable(int row, int column) {
return true;
}
};
table.setModel(modello);
return modello;
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("ComboBoxDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JComponent newContentPane = new JcomboboxJtableDemo();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
I you try to run it you will see that there is a problem in showing correctly the JComboBox components in the second column, in the first column the are correctly shown and you can see each selected item as set in the code, instead in the second column there are some problems: none on the relative cell.
Could you tell me why? How can I solve the problem?
Thanks

You're using the same JComboBox component for both ColumnModel columns which in turn share the same ComboBoxModel. Any change in the selected item from one column will be reflected in the other column. Create a second combobox
JComboBox comboBox2 = new JComboBox(petStrings);
...
table.getColumnModel().getColumn(1).setCellEditor(editor2);
so that any changes can occur independently in either column.

Related

Custom Combo box in JTable wont set the selected option

I've created a custom combo box that displays possible changes in state for orders. I did it with the help of this post, using MadProgrammer's code as base line:
Changing Dropdown content in a JTable Column in Swing
It worked, partially.
Even though after clicking the combo box is activated and it shows the proper state options for the user, it has the following problem.
After the user selects the option, the combo box doesn't set the selected value in the table. However if the user changes the combo box of another order, the change does take place. It also works if you click other part of the selected row that isn't the combo box cell.
I suspect that this is because the cell only changes to be a combo box when is clicked, so it doesn't behave like a combo box does. Yet I'm a bit lost in how to fix it.
Any help is greatly appreciated.
Here are the relevant parts of my code:
EDIT: Following Andrew Thompson's advice, i replaced the code with a reproducible example. I'll be working on MadProgrammer's suggested solution and update it later.
package test;
import java.awt.Component;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
public class TestCellEditor {
public static void main(String[] args) {
new TestCellEditor();
}
public TestCellEditor() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
List<String> values = new ArrayList<>(5);
values.add("B");
values.add("A");
values.add("O");
values.add("G");
values.add("P");
ComboBoxTableCellEditor editor = new ComboBoxTableCellEditor(values);
DefaultTableModel model = new DefaultTableModel(new Object[]{"Status"}, 5);
JTable table = new JTable(model);
table.getColumnModel().getColumn(0).setCellEditor(editor);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ComboBoxTableCellEditor extends AbstractCellEditor implements TableCellEditor {
private JComboBox editor;
private List<String> masterValues;
public ComboBoxTableCellEditor(List<String> masterValues) {
this.editor = new JComboBox();
this.masterValues = masterValues;
}
#Override
public Object getCellEditorValue() {
return editor.getSelectedItem();
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
DefaultComboBoxModel model = new DefaultComboBoxModel(masterValues.toArray(new String[masterValues.size()]));
for (int index = 0; index < table.getRowCount(); index++) {
}
editor.setModel(model);
editor.setSelectedItem(value);
return editor;
}
}
}
This approach will only override the getTableCellEditorComponent(...) method of the DefaultCellEditor to reset the model of the combo box based on a value in the current row that is being edited.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.table.*;
public class StateCellEditor extends DefaultCellEditor
{
private int lookupColumn;
private HashMap<Object, DefaultComboBoxModel<?>> map;
public StateCellEditor(JComboBox<?> comboBox, int lookColumn, HashMap<Object, DefaultComboBoxModel<?>> map)
{
super(comboBox);
this.lookupColumn = lookupColumn;
this.map = map;
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
{
Component c = super.getTableCellEditorComponent(table, value, isSelected, row, column);
JComboBox<?> comboBox = (JComboBox<?>)c;
Object lookup = table.getModel().getValueAt(row, lookupColumn);
DefaultComboBoxModel model = map.get( lookup );
comboBox.setModel( model );
return comboBox;
}
private static void createAndShowUI()
{
HashMap<Object, DefaultComboBoxModel<?>> map = new HashMap<>();
map.put("Color", new DefaultComboBoxModel<Object>( new String[]{ "Red", "Blue", "Green" } ));
map.put("Shape", new DefaultComboBoxModel<Object>( new String[]{ "Circle", "Square", "Triangle" } ));
map.put("Fruit", new DefaultComboBoxModel<Object>( new String[]{ "Apple", "Orange", "Banana" } ));
JPanel panel = new JPanel( new BorderLayout() );
panel.setLayout( new BorderLayout() );
// Create the table with default data
Object[][] data =
{
{"Color", "Red"},
{"Shape", "Square"},
{"Fruit", "Banana"}
};
String[] columnNames = {"Type","Value"};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
JTable table = new JTable(model);
DefaultCellEditor dce = new StateCellEditor(new JComboBox<Object>(), 0, map);
table.getColumnModel().getColumn(1).setCellEditor(dce);
JScrollPane scrollPane = new JScrollPane( table );
panel.add( scrollPane );
JFrame frame = new JFrame("Table Combo Box by Row");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel, BorderLayout.CENTER);
frame.setSize(200, 200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Following the suggestion of #camickr i managed to implement an easier solution.
I put this on the method that populates the table:
table.getColumnModel().getColumn(5).setCellEditor(getCellEditor(status));
public List<TableCellEditor> TableComboBoxByRow(){
// Create the editors to be used for each row
List<TableCellEditor> editors = new ArrayList<TableCellEditor>(3);
String[] items1 = { "I", "C", "F" };
JComboBox comboBox1 = new JComboBox( items1 );
DefaultCellEditor dce1 = new DefaultCellEditor( comboBox1 );
editors.add( dce1 );
String[] items2 = { "E" };
JComboBox comboBox2 = new JComboBox( items2 );
DefaultCellEditor dce2 = new DefaultCellEditor( comboBox2 );
editors.add( dce2 );
String[] items3 = { "ET" };
JComboBox comboBox3 = new JComboBox( items3 );
DefaultCellEditor dce3 = new DefaultCellEditor( comboBox3 );
editors.add( dce3 );
String[] items4 = { "F" };
JComboBox comboBox4 = new JComboBox( items4 );
DefaultCellEditor dce4 = new DefaultCellEditor( comboBox4 );
editors.add( dce4 );
return editors;
}
public TableCellEditor getCellEditor(String status)
{
if(estado.equals("I") || estado.equals("C")){
return TableComboBoxByRow().get(0);
}
else if(estado.equals("E"))
{
return TableComboBoxByRow().get(1);}
else if(estado.equals("ET"))
{
return TableComboBoxByRow().get(2);
}else{
return TableComboBoxByRow().get(3);
}
}
Thank you so much!

populate DefaultTableModel after insert a row java

I am running a program with two frames. First one has a table, the second one has a form which allows adding a new user to the table. I think the problem is I didn't add a reference from the mainframe. I was trying different methods to refresh the mainframe programmatically, but it did not help so much. I read many articles on how to to it but I could find a solution. My table usually changes when I close my app and open it again. But I don't think is the right way to do it. I tried to delete elements from DefaultTableModel and populated jtable again, but did not get any results. Here is my code:
public Vector vector_jtable = new Vector();
public MainApp() {
initComponents();
Database b = new Database();
b.getAmountOfRows(getCount);
this.setLocationRelativeTo(null);
printResultDB();
}
//add function that is responsible for addding data to the table
public void postDataJtable() {
System.out.println("The vector is: " + vector_jtable);
Vector<String> header = new Vector<String>();
header.add("Number");
header.add("Name");
header.add("First Payment");
header.add("Next Payment");
header.add("Picture");
header.add("Phone");
header.add("Amount");
header.add("Age");
model = (DefaultTableModel)jTable2.getModel();
model.setDataVector(vector_jtable,header);
}
I created a vector that allows putting data from the second frame.
MainApp app;
public AddStudents(MainApp a) {
initComponents();
app = a;
this.setLocationRelativeTo(null);
jDateChooser1.setDateFormatString("yyyy-MM-dd");
jDateChooser2.setDateFormatString("yyyy-MM-dd");
}
After that, I push the button to send it out and update the mainframe, but nothing happened:
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
app.vector_jtable.add(name);
app.vector_jtable.add(first_p);
app.vector_jtable.add(next_p);
app.vector_jtable.add(picture);
app.vector_jtable.add(phone);
app.vector_jtable.add(amount);
app.vector_jtable.add(age);
app.postDataJtable();
My question. How to add a row in jtable and refresh it. I really stuck in this topic. I need your help.
Don't update the Vector.
When you want to change the data in the table you need to change the data in the TableModel.
You can use the addRow(...) method of the DefaultTableModel to add a new row of data.
So the basic logic is:
Vector<Object> row = new Vector<Object>();
row.add( someVariable1 );
row.add( someVariable2 );
...
modal.addRow( row ):
The model will then tell the table to repaint itself.
Edit:
There is no trick all you need is a reference to the model. Then you update the model.
Here is a simple example to prove the concept works:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class SSCCE extends JPanel
{
private DefaultTableModel model;
SSCCE()
{
setLayout( new BorderLayout() );
model = new DefaultTableModel(0, 2);
JTable table = new JTable( model );
add(new JScrollPane( table ));
JButton button = new JButton( "Add Row" );
add(button, BorderLayout.PAGE_END);
button.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
Vector<Object> row = new Vector<Object>();
row.add( "" + model.getRowCount() );
row.add( new Date().toString() );
model.addRow( row );
}
});
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args) throws Exception
{
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}
If it doesn't work for you then you need to debug your code. Maybe you have two "model" variables? Maybe you have to "table" variables. Maybe your code isn't even executed. Did you add any debug statements to the code to make sure it is executed.
We can't solve your problem only point you in the right direction.
You can try some aspects from this example below. The example has two JFrame's - one with a JTable and the other the data entry fields. When the data is entered and the "UpdateTable" button is pressed (in the data entry class) the table is updated.
The example uses java.util.Observer and Observable to achieve this functionality.
The class with table:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.util.Observer;
import java.util.Observable;
public class TableUpdateTester implements Observer {
private JTable table;
private static final Object[] TABLE_COLUMNS = {"Book", "Author"};
private static final Object [][] TABLE_DATA = {
{"Book 1", "author 1"}, {"Book 2", "author 1"}
};
public static void main(String [] args) {
TableUpdateTester tester = new TableUpdateTester();
new DataEntryClass(tester);
}
public TableUpdateTester() {
JFrame frame = new JFrame("Table Update Tester");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(getTablePanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JPanel getTablePanel() {
table = new JTable(new DefaultTableModel(TABLE_DATA, TABLE_COLUMNS));
JScrollPane scrollpane = new JScrollPane(table);
scrollpane.setPreferredSize(new Dimension(400, 150));
scrollpane.setViewportView(table);
JPanel panel = new JPanel();
panel.add(scrollpane);
return panel;
}
// This is Observer's override method.
#Override public void update(Observable o, Object arg) {
String [] data = (String []) arg;
System.out.println("Data recieving: " + java.util.Arrays.toString(data));
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(data);
}
}
The data entry class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Observable;
public class DataEntryClass {
public DataEntryClass(TableUpdateTester observer) {
final DataObservable observable = new DataObservable();
observable.addObserver(observer);
JLabel label = new JLabel("Book: ");
final JTextField text = new JTextField(15);
JLabel label2 = new JLabel("Author: ");
final JTextField text2 = new JTextField(15);
JButton button = new JButton("Update Table");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String data1 = text.getText().isEmpty() ? "empty" : text.getText();
String data2 = text2.getText().isEmpty() ? "empty" : text2.getText();
String [] data = {data1, data2};
System.out.println("Data sent: " + java.util.Arrays.toString(data));
observable.changeData(data);
}
});
JPanel panel = new JPanel();
GridLayout grid = new GridLayout(3, 2);
panel.setLayout(grid);
panel.add(label);
panel.add(text);
panel.add(label2);
panel.add(text2);
panel.add(new JLabel(""));
panel.add(button);
JFrame frame = new JFrame();
frame.setTitle("Data Entry");
frame.add(panel);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.pack();
}
}
class DataObservable extends Observable {
DataObservable() {
super();
}
void changeData(Object data) {
// the two methods of Observable class
setChanged();
notifyObservers(data);
}
}
Finally, I found a solution to my problem. I will post my code here.
The Mainframe. I know the app with two frames is not a good option, because it's hard to fix the problem and it usually takes a lot of time to debug it.
/**
* Create the application.
*/
public MainApp() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 689, 345);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
//add table in DefaultTableModel
model = new DefaultTableModel(0,2);
table = new JTable(model);
table.setBounds(58, 38, 524, 197);
frame.getContentPane().add(table);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(0, 0, 4, 4);
frame.getContentPane().add(scrollPane);
JButton btnNewButton = new JButton("Add");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Call a second frame
//add reference for DefaultTableModel and send it to another frame
AddData frame = new AddData(model);
frame.setVisible(true);
}
});
btnNewButton.setBounds(239, 269, 117, 29);
frame.getContentPane().add(btnNewButton);
}
The second frame, that is responsible for adding a new row in a table.
/**
* Create the frame.
*/
public AddData(DefaultTableModel model) {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JDateChooser dateChooser = new JDateChooser();
dateChooser.setBounds(115, 71, 188, 41);
contentPane.add(dateChooser);
JButton btnNewButton = new JButton("Send");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//MainApp app = new MainApp();
Vector<Object> row = new Vector<Object>();
row.add(""+model.getRowCount());
row.add(dateChooser.getDate().toString());
model.addRow(row);
}
});
btnNewButton.setFont(new Font("Lucida Grande", Font.PLAIN, 20));
btnNewButton.setBounds(165, 192, 117, 41);
contentPane.add(btnNewButton);
}
I found my mistake. I did not send a link of DefaultTableModel into the second frame. That's why it was null every time. It was a really painful experience, but I learned from my mistakes. Thanks, everyone for your help. I really appriciate.

Get value from a cell in JTable

I've looked everywhere but can't seem to figure this out. I just want to pull out a cell's value from my JTable when a user clicks on it.
However at the moment I am getting -1 so I suppose double clicking results in no row being detected. Here is the code:
import java.awt.*;
import java.awt.event.*;
import java.sql.SQLException;
import javax.swing.*;
import javax.swing.table.TableColumn;
public class CardLayoutExample {
private static JScrollPane scrollPane;
public static void main(String[] arguments) throws SQLException {
// main window
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame window = new JFrame("CardLayout Example");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(1500,800);
window.getContentPane().setLayout(new BorderLayout());
final CardLayout cardLayout = new CardLayout();
final JPanel cardPanel = new JPanel(cardLayout);
JPanel card3 = new JPanel();
cardPanel.add(card3,"All Patients");
String AllPatients="select * from tblPtDetails";
JTable tablePatientDt = new JTable(Bquery.buildTableModel(Bquery.resultQuery(AllPatients)));
tablePatientDt.setEnabled(false);
tablePatientDt.setPreferredScrollableViewportSize(new Dimension(1200, 400));
tablePatientDt.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
tablePatientDt.setRowHeight(30);
tablePatientDt.setAutoCreateRowSorter(true);
card3.add(tablePatientDt);
card3.add(new JScrollPane(tablePatientDt), BorderLayout.CENTER);
for (int i = 0; i < (tablePatientDt.getColumnCount()); i++) {
TableColumn columnPatients = null;
columnPatients = tablePatientDt.getColumnModel().getColumn(i);
columnPatients.setPreferredWidth(70); //sport column is bigger
}
tablePatientDt.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int row = tablePatientDt.getSelectedRow();
int column = tablePatientDt.getSelectedColumn();
//Object val= tablePatientDt.getModel().getValueAt(row, column);
//tablePatientDt.getModel().getValueAt(row, column);
//return tablePatientDt.getModel().getValueAt(row, column);
System.out.println(row);
JFrame newFrame = new JFrame();
newFrame.setTitle("Detail Screen");
newFrame.setVisible(true);
}
}
});
Your main problem is here:
tablePatientDt.setEnabled(false);
Because the table is not enabled, no cell or row can ever be selected, and so the selected row will always be -1. Solution: get rid of that line. Instead, if you don't want a cell to be editable on double click, override the JTable or its model and override the isCellEditable method:
e.g.,
// create your JTable model here:
DefaultTableModel model = ......
JTable tablePatientDt = new JTable(model){
#Override
public boolean isCellEditable(int row, int column) {
return false;
}
Other issues: don't add the JTable to more than one component as you're doing. That spells great risk for trouble since Swing components can be added to only one component at a time.
A side recommendation: in your future questions post only small compilable and runnable programs. Your code above cannot run since it has database dependencies that we don't have access to, and is also incomplete. In order to find your problem, I had to take your code and create a small runnable program with it, an mcve (please read the link):
import java.awt.*;
import java.awt.event.*;
import java.sql.SQLException;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
public class CardLayoutExample {
private static JScrollPane scrollPane;
public static void main(String[] arguments) throws SQLException {
// main window
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame window = new JFrame("CardLayout Example");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// !! window.setSize(1500, 800);
window.getContentPane().setLayout(new BorderLayout());
final CardLayout cardLayout = new CardLayout();
final JPanel cardPanel = new JPanel(cardLayout);
JPanel card3 = new JPanel();
cardPanel.add(card3, "All Patients");
String AllPatients = "select * from tblPtDetails";
//!!
String[][] data = {{"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}};
String[] columnNames = {"One", "Two", "Three"};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
// !! JTable tablePatientDt = new JTable(Bquery.buildTableModel(Bquery.resultQuery(AllPatients)));
JTable tablePatientDt = new JTable(model){
#Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
// !! tablePatientDt.setEnabled(false);
tablePatientDt.setPreferredScrollableViewportSize(new Dimension(1200, 400));
tablePatientDt.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
tablePatientDt.setRowHeight(30);
tablePatientDt.setAutoCreateRowSorter(true);
// !! card3.add(tablePatientDt);
card3.add(new JScrollPane(tablePatientDt), BorderLayout.CENTER);
for (int i = 0; i < (tablePatientDt.getColumnCount()); i++) {
TableColumn columnPatients = null;
columnPatients = tablePatientDt.getColumnModel().getColumn(i);
columnPatients.setPreferredWidth(70); // sport column is bigger
}
tablePatientDt.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int row = tablePatientDt.getSelectedRow();
int column = tablePatientDt.getSelectedColumn();
// Object val= tablePatientDt.getModel().getValueAt(row,
// column);
// tablePatientDt.getModel().getValueAt(row, column);
// return tablePatientDt.getModel().getValueAt(row, column);
System.out.println(row);
JFrame newFrame = new JFrame();
newFrame.setTitle("Detail Screen");
newFrame.setVisible(true);
}
}
});
//!!
window.add(cardPanel);
window.pack();
window.setVisible(true);
}
}
But really this effort should be yours not mine, since we're all volunteers, and you're the one asking for volunteer help in solving a problem. So in the future we ask that you create your own mcve to go with your questions.
Also that detail window shouldn't be a JFrame but rather a JDialog.

Java Eclipse Jtable Cell / Column

for Java Kepler Eclipse and Jtable, I am trying to make it so as when a specific table cell is selected, that cell will work as an editorPane; or have the whole column work as editorPane. When I click a cell on column COMMENTS it enlargens the row but I cant get it to work as an editorPane. My project is actualy very different but I wrote this mini one with the table so you can copy, paste and run it to see exactly what the problem is when you click on a COMMENTS cell.
I tried to make the column an editorPane to begin with like I made the column DONE with checkBox, but it doesnt work or I am doing it wrong. I also tried cellRenderer but I couldnt make that work either.
Whether the whole column works as an editorPane or just the selected cell it doesnt matter, whatever is easier and as long as it works
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
public class JavaTestOne {
JFrame frmApp;
private JTable table;
private JCheckBox checkbox;
DefaultTableModel model;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JavaTestOne window = new JavaTestOne();
window.frmApp.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public JavaTestOne() {
initialize();
}
private void initialize() {
frmApp = new JFrame();
frmApp.getContentPane().setFont(new Font("Tahoma", Font.PLAIN, 13));
frmApp.setBounds(50, 10, 1050, 650);
frmApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmApp.getContentPane().setLayout(new CardLayout(0, 0));
frmApp.setTitle("App");
{
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(0, 42, 984, 484);
frmApp.add(scrollPane);
{
table = new JTable();
table.setFillsViewportHeight(true);
Object[][] data = {
{"I01", "Tom",new Boolean(false), ""},
{"I02", "Jerry",new Boolean(false), ""},
{"I03", "Ann",new Boolean(false), ""}};
String[] cols = {"ID","NAME","DONE","COMMENTS"};
model = new DefaultTableModel(data, cols) {
private static final long serialVersionUID = -7158928637468625935L;
public Class getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
};
table.setModel(model);
table.setRowHeight(20);
table.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
int row = table.rowAtPoint(evt.getPoint());
int col = table.columnAtPoint(evt.getPoint());
table.setRowHeight(20);
if(col==3){
table.setRowHeight(row, 100);
//this is where I need it to work as an editorPane if it is only for the selected cell
}
}
});
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
scrollPane.setViewportView(table);
checkbox = new JCheckBox("OK");
checkbox.setHorizontalAlignment(SwingConstants.CENTER);
checkbox.setBounds(360, 63, 97, 23);
}
}
}
}
Another alternative is to display a popup window to edit the cell:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
/*
* The editor button that brings up the dialog.
*/
//public class TablePopupEditor extends AbstractCellEditor
public class TablePopupEditor extends DefaultCellEditor
implements TableCellEditor
{
private PopupDialog popup;
private String currentText = "";
private JButton editorComponent;
public TablePopupEditor()
{
super(new JTextField());
setClickCountToStart(1);
// Use a JButton as the editor component
editorComponent = new JButton();
editorComponent.setBackground(Color.white);
editorComponent.setBorderPainted(false);
editorComponent.setContentAreaFilled( false );
// Make sure focus goes back to the table when the dialog is closed
editorComponent.setFocusable( false );
// Set up the dialog where we do the actual editing
popup = new PopupDialog();
}
public Object getCellEditorValue()
{
return currentText;
}
public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
popup.setText( currentText );
// popup.setLocationRelativeTo( editorComponent );
Point p = editorComponent.getLocationOnScreen();
popup.setLocation(p.x, p.y + editorComponent.getSize().height);
popup.show();
fireEditingStopped();
}
});
currentText = value.toString();
editorComponent.setText( currentText );
return editorComponent;
}
/*
* Simple dialog containing the actual editing component
*/
class PopupDialog extends JDialog implements ActionListener
{
private JTextArea textArea;
public PopupDialog()
{
super((Frame)null, "Change Description", true);
textArea = new JTextArea(5, 20);
textArea.setLineWrap( true );
textArea.setWrapStyleWord( true );
KeyStroke keyStroke = KeyStroke.getKeyStroke("ENTER");
textArea.getInputMap().put(keyStroke, "none");
JScrollPane scrollPane = new JScrollPane( textArea );
getContentPane().add( scrollPane );
JButton cancel = new JButton("Cancel");
cancel.addActionListener( this );
JButton ok = new JButton("Ok");
ok.setPreferredSize( cancel.getPreferredSize() );
ok.addActionListener( this );
JPanel buttons = new JPanel();
buttons.add( ok );
buttons.add( cancel );
getContentPane().add(buttons, BorderLayout.SOUTH);
pack();
getRootPane().setDefaultButton( ok );
}
public void setText(String text)
{
textArea.setText( text );
}
/*
* Save the changed text before hiding the popup
*/
public void actionPerformed(ActionEvent e)
{
if ("Ok".equals( e.getActionCommand() ) )
{
currentText = textArea.getText();
}
textArea.requestFocusInWindow();
setVisible( false );
}
}
private static void createAndShowUI()
{
String[] columnNames = {"Item", "Description"};
Object[][] data =
{
{"Item 1", "Description of Item 1"},
{"Item 2", "Description of Item 2"},
{"Item 3", "Description of Item 3"}
};
JTable table = new JTable(data, columnNames);
table.getColumnModel().getColumn(1).setPreferredWidth(300);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
// Use the popup editor on the second column
TablePopupEditor popupEditor = new TablePopupEditor();
table.getColumnModel().getColumn(1).setCellEditor( popupEditor );
JFrame frame = new JFrame("Popup Editor Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JTextField(), BorderLayout.NORTH);
frame.add( scrollPane );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Using this approach you don't continually manipulate the row size. You could even customize the code to make the dialog fit the width of the cell and appear below the cell.
Seems you need to implement your own TableCellEditor, read more in tutorial.
For example like that:
private class CustomEditor extends AbstractCellEditor implements TableCellEditor{
private JTextPane pane = new JTextPane();
private JScrollPane scroll = new JScrollPane(pane);
private int row = -1;
#Override
public Object getCellEditorValue() {
return pane.getText();
}
#Override
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
if(this.row != -1)
table.setRowHeight(this.row, 20);
this.row = row;
table.setRowHeight(row, 100);
pane.setText(value == null ? "" : value.toString());
return scroll;
}
}
and then set it as column editor: table.getColumn("COMMENTS").setCellEditor(new CustomEditor());

java: dialog with 2 button for event "click on Jtable cell"?

I have a jtable with "data" in my java project:
DefaultTableModel model=(DefaultTableModel)jTablePolicyView.getModel();
for(Policy policy : sngltn.GetPerPolicies(cstmr.getPer()))
{
model.addRow(new Object[] {String.valueOf(policy.getPolicyId()),...,....});
}
I want that :
for clicking on each cell in my jtable , will spring a dialog(not Form...).
will be two buttons (with "my label") on this dialog.
i will be able to determine what action will happen(this action should use the contents of the cell) for clicking each button.
So what I'm asking?
Is it possible?
Example code, greatly help me...
Thank!
i try this code for my first mission(for clicking on each cell in my jtable)...
but it's didnt work, why?
my code:
public class UpdateCstmrForm extends javax.swing.JFrame
{
......
public UpdateCstmrForm(long person_id) throws Exception
{
DefaultTableModel model=(DefaultTableModel)jTablePolicyView.getModel();
.....
initComponents();
.....
for(Policy policy : sngltn.GetPerPolicies(cstmr.getPer()))
{
model.addRow(new Object[] {......});
}
jTablePolicyView.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount() == 2)
{
JTable target = (JTable)e.getSource();
int row = target.getSelectedRow();
int column = target.getSelectedColumn();
System.out.println(model.getValueAt(row, column));
}
}
}
.....
}
}
You need to use a custom editor. The following example should get you started:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
/*
* The editor button that brings up the dialog.
*/
//public class TablePopupEditor extends AbstractCellEditor
public class TablePopupEditor extends DefaultCellEditor
implements TableCellEditor
{
private PopupDialog popup;
private String currentText = "";
private JButton editorComponent;
public TablePopupEditor()
{
super(new JTextField());
setClickCountToStart(1);
// Use a JButton as the editor component
editorComponent = new JButton();
editorComponent.setBackground(Color.white);
editorComponent.setBorderPainted(false);
editorComponent.setContentAreaFilled( false );
// Make sure focus goes back to the table when the dialog is closed
editorComponent.setFocusable( false );
// Set up the dialog where we do the actual editing
popup = new PopupDialog();
}
public Object getCellEditorValue()
{
return currentText;
}
public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
popup.setText( currentText );
// popup.setLocationRelativeTo( editorComponent );
Point p = editorComponent.getLocationOnScreen();
popup.setLocation(p.x, p.y + editorComponent.getSize().height);
popup.show();
fireEditingStopped();
}
});
currentText = value.toString();
editorComponent.setText( currentText );
return editorComponent;
}
/*
* Simple dialog containing the actual editing component
*/
class PopupDialog extends JDialog implements ActionListener
{
private JTextArea textArea;
public PopupDialog()
{
super((Frame)null, "Change Description", true);
textArea = new JTextArea(5, 20);
textArea.setLineWrap( true );
textArea.setWrapStyleWord( true );
KeyStroke keyStroke = KeyStroke.getKeyStroke("ENTER");
textArea.getInputMap().put(keyStroke, "none");
JScrollPane scrollPane = new JScrollPane( textArea );
getContentPane().add( scrollPane );
JButton cancel = new JButton("Cancel");
cancel.addActionListener( this );
JButton ok = new JButton("Ok");
ok.setPreferredSize( cancel.getPreferredSize() );
ok.addActionListener( this );
JPanel buttons = new JPanel();
buttons.add( ok );
buttons.add( cancel );
getContentPane().add(buttons, BorderLayout.SOUTH);
pack();
getRootPane().setDefaultButton( ok );
}
public void setText(String text)
{
textArea.setText( text );
}
/*
* Save the changed text before hiding the popup
*/
public void actionPerformed(ActionEvent e)
{
if ("Ok".equals( e.getActionCommand() ) )
{
currentText = textArea.getText();
}
textArea.requestFocusInWindow();
setVisible( false );
}
}
private static void createAndShowUI()
{
String[] columnNames = {"Item", "Description"};
Object[][] data =
{
{"Item 1", "Description of Item 1"},
{"Item 2", "Description of Item 2"},
{"Item 3", "Description of Item 3"}
};
JTable table = new JTable(data, columnNames);
table.getColumnModel().getColumn(1).setPreferredWidth(300);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
// Use the popup editor on the second column
TablePopupEditor popupEditor = new TablePopupEditor();
table.getColumnModel().getColumn(1).setCellEditor( popupEditor );
JFrame frame = new JFrame("Popup Editor Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JTextField(), BorderLayout.NORTH);
frame.add( scrollPane );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
It demonstrates how to use a JTextArea as an editor for a cell.

Categories

Resources