I have text fields and a JTable on a Frame. When user clicks on the JTable row or moves key up and down, textfields filled up with these selected row values so that user can update the row. So the problem is when I select the row and then pressed the delete button the table refreshes but the textfields still show the deleted row values.So at this moment I dont want to reset the fields. I want to show the row values which comes before the deleted row in the text field
For example there are two rows
id name
1 hello
2 bello
user selected the row which has ID 2 and delete it. now the values on the textfield should be hello not bellow
You can use a ListSelectionListener on your JTable which sets the text of the JTextField elements based on the current selection in your JTable. When the delete button is pressed, you can have the ActionListener remove the selected row from the JTable and force the next selection in the model via setRowSelectionInterval. Below is a simple example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.*;
public class JTableDelete extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JTable table;
private JTextField textField;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JTableDelete frame = new JTableDelete();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public JTableDelete() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
table = new JTable();
table.setModel(new DefaultTableModel(new Object[][] { { "Red" }, { "Green" }, { "Blue" }, { "Violet" }, { "Orange" }, },
new String[] { "Colors" }));
ListSelectionModel cellSelectionModel = table.getSelectionModel();
cellSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
cellSelectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
int selectedRow = table.getSelectedRow();
int selectedColumn = table.getSelectedColumn();
if (selectedRow != -1 && selectedColumn != -1)
textField.setText((String) table.getValueAt(selectedRow, selectedColumn));
else
textField.setText("");
}
});
contentPane.add(table, BorderLayout.CENTER);
JButton btnDelete = new JButton("Delete");
btnDelete.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int row = table.getSelectedRow();
int rowCount = table.getRowCount() - 1; // -1 because counting starts at 0
if (row != -1) {
((DefaultTableModel) table.getModel()).removeRow(row);
rowCount--; // 1 less row now
if (row < table.getRowCount()) // next selection
table.setRowSelectionInterval(row, row);
else if (rowCount != -1) // end selection
table.setRowSelectionInterval(rowCount, rowCount);
}
}
});
contentPane.add(btnDelete, BorderLayout.SOUTH);
textField = new JTextField();
textField.setEnabled(false);
contentPane.add(textField, BorderLayout.NORTH);
textField.setColumns(10);
pack();
}
}
Related
I'm trying to set a button in enabled(false) when I create it, and when I select any row on the Jtable, that button goes enabled(true).
Logic is pretty simple here, but for some reason, it doesn't quite work, the button never gets into enabled(true).
JButton btnIniciarReparacin = new JButton("INICIAR REPARACI\u00D3N");
btnIniciarReparacin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
tiempoStart = (int) (System.currentTimeMillis() / 1000L);
btnIniciarReparacin.setEnabled(false);
}
});
btnIniciarReparacin.setFont(new Font("SansSerif", Font.BOLD, 13));
btnIniciarReparacin.setBackground(new Color(231, 111, 81));
btnIniciarReparacin.setBounds(129, 625, 254, 50);
frame.getContentPane().add(btnIniciarReparacin);
int row = table.getSelectedRow();
//Comprobamos si hemos cogido algo de la tabla y si los botones están encendidos
if (table.isRowSelected(row)) {
btnIniciarReparacin.setEnabled(true);
} else {
btnIniciarReparacin.setEnabled(false);
}
Swing GUI's work by your adding listeners to events and then responding to state changes within the listener.
You appear to be checking the row selection state in code where you create your components, and that will never work since it only checks the state once, and before the user has had a chance to make a selection. Instead, you need to use a listener on your JTable, more specifically a ListSelectionListener that you add to the JTable's selection model that you get via table.getSelectionModel().addListSelectionListener(...)
Also note that this:
int row = table.getSelectedRow();
if (table.isRowSelected(row)) {
btnIniciarReparacin.setEnabled(true);
} else {
btnIniciarReparacin.setEnabled(false);
}
can be shortened to:
int row = table.getSelectedRow();
btnIniciarReparacin.setEnabled(table.isRowSelected(row));
e.g. something like:
table.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
public void valueChanged(ListSelectionEvent event) {
int row = table.getSelectedRow();
btnIniciarReparacin.setEnabled(table.isRowSelected(row));
}
});
For example, if the button deletes a row:
import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
#SuppressWarnings("serial")
public class Test01 extends JPanel {
private static final String[] COLUMNS = {"One", "Two", "Three", "Four"};
private DefaultTableModel tableModel = new DefaultTableModel(COLUMNS, 0);
private JTable table = new JTable(tableModel);
private JButton deleteRowButton = new JButton("Delete Row");
public Test01() {
int tableRows = 20;
for (int i = 0; i < tableRows; i++) {
Integer[] row = new Integer[COLUMNS.length];
for (int j = 0; j < row.length; j++) {
row[j] = (int) (100 * Math.random());
}
tableModel.addRow(row);
}
table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
int row = table.getSelectedRow();
deleteRowButton.setEnabled(table.isRowSelected(row));
}
});
deleteRowButton.addActionListener(e -> {
int row = table.getSelectedRow();
tableModel.removeRow(row);
});
deleteRowButton.setEnabled(false);
JPanel bottomPanel = new JPanel();
bottomPanel.add(deleteRowButton);
setLayout(new BorderLayout());
add(new JScrollPane(table));
add(bottomPanel, BorderLayout.PAGE_END);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
Test01 mainPanel = new Test01();
JFrame frame = new JFrame("Test01");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
I have a JTable, edit button and save button. when I click the edit button , I want to insert two JTextFields into a particular cell which is selected . So I can write (strings) into these text fields .
when I click on save button want to remove those two textfields from the cell and paste that strings (into the same cell of the table).
You don't need to add a JTextField to a JTable in order for a cell to be editable. The isCellEditable(int row, int column) function can be overridden to return a boolean dependent on the edit button. Here's an example:
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.EventQueue;
import java.awt.event.*;
import java.awt.Dimension;
public class EditTableExample extends JFrame {
private boolean editable = false;
public EditTableExample() {
//set up jframe
setPreferredSize(new Dimension(500, 500));
setMinimumSize(new Dimension(500, 500));
setResizable(false);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
//set up content pane
JPanel contentPane = new JPanel();
setContentPane(contentPane);
//table model
Object[][] tableContents = new Object[][]{ //contents of our table
{"Person1", "City1"},
{"Person2", "City2"},
{"Person3", "City3"}
};
Object[] tableHeader = new Object[]{
"Name", "City"
};
DefaultTableModel model = new DefaultTableModel(tableContents, tableHeader) {
#Override
public boolean isCellEditable(int row, int column) {
return editable;
}
};
//table
JTable table = new JTable(model);
//scrollpane to house table
JScrollPane tablePane = new JScrollPane(table);
tablePane.setPreferredSize(new Dimension(450, 450));
//button that will add a row
JButton add = new JButton("Add Row");
add.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
model.addRow(new Object[model.getColumnCount()]); //adds a new, empty row to the table
}
});
//button that will toggle edit mode
JButton edit = new JButton("Toggle Edit");
edit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
editable = !editable; //switches the value of 'editable' on click
}
});
//button to remove a row
JButton remove = new JButton("Remove Row");
remove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
try {
model.removeRow(table.getSelectedRow()); //remove selected row
}
catch (ArrayIndexOutOfBoundsException e) {
JOptionPane.showMessageDialog(rootPane, "No Row Selected");
}
}
});
//add everything together
contentPane.add(tablePane);
contentPane.add(add);
contentPane.add(edit);
contentPane.add(remove);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
EditTableExample e = new EditTableExample();
e.setVisible(true);
}
});
}
}
As you can see, the isCellEditable function will return the value of 'editable', a boolean whose value is toggled by the 'edit' button. Instead of having one cell per person that contains "Name, City" there are two columns, one for the person's name and one for their city. Let me know if you have any other questions.
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.
I need to remove the rows that are selected after a button is pressed.
That's is my code: I have a column that is a checkbox, then a check if it is checked and add the corresponding line to the list.
DefaultTableModel model = (DefaultTableModel) jTableLayouts.getModel();
// gets the number of rows that were selected
Public ArrayList<Integer> selectedLines = new ArrayList<Integer>();
for (int j = 0; j <= jTableLayouts.getModel().getRowCount(); j++) {
if ((Boolean) jTableLayouts.getModel().getValueAt(j,2)){ //checkbox
selectedLines.add(jTableLayouts.getSelectedRow());
}
model.removeRow(selectedLines.get(j));
}
With this code I can remove one by one. Any ideas how I can remove all the lines after a press the button?
EDIT: I only need to remove the rows that are marked as true in the checkbox. Example: the rows 0,1,4,5 are marked as true, after that I will add these lines in a list, and then just remove the lines that are on the list at same time after the button is pressed.
As #MadProgrammer already commented, you can do this from a button by having the ActionListener perform the deletes and add the deleted rows to the list you want.
In this snippet when pressing the button, the checked rows on the left are deleted and added to the table on the right. Check the createDeleteButton method for how this is done.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
#SuppressWarnings("serial")
public class TestTableDeleteRows extends JPanel {
private JTable tblLeft;
private JTable tblRight;
public TestTableDeleteRows() {
initialize();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(600,400);
}
private void initialize() {
setLayout(new BorderLayout());
add(createHeaderPane(),BorderLayout.NORTH);
add(createTablePane(),BorderLayout.CENTER);
add(createDeleteButton(),BorderLayout.SOUTH);
}
private JPanel createHeaderPane() {
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.LINE_AXIS));
p.add(new JScrollPane(new JLabel("Source",SwingConstants.CENTER)));
p.add(new JScrollPane(new JLabel("Deleted",SwingConstants.CENTER)));
return p;
}
private JPanel createTablePane() {
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
tblLeft = createTable(stdRows);
tblRight = createTable(new Vector<Vector<Object>>());
p.add(new JScrollPane(tblLeft));
p.add(new JScrollPane(tblRight));
return p;
}
private static final int COL_CHECK=0;
private static final int COL_TEXT=1;
private static final Vector<Vector<Object>> stdRows;
private static final Vector<Object> cols;
static {
stdRows = new Vector<Vector<Object>>();
for(int i=0;i!=100;++i)
stdRows.add(new Vector<Object>(Arrays.asList(new Object[]{Boolean.FALSE,"This is text line number "+(i+1)})));
cols = new Vector<>(Arrays.asList(new Object[]{"Check me","Silly text"}));
}
private static JTable createTable(Vector<Vector<Object>> rows) {
JTable t = new JTable(rows,cols) {
#Override
public Class<?> getColumnClass(int column) {
if(getRowCount()>0)
return getValueAt(0, column).getClass();
return super.getColumnClass(column);
}
};
t.getColumnModel().getColumn(COL_CHECK).setPreferredWidth(50);
t.getColumnModel().getColumn(COL_TEXT).setPreferredWidth(200);
return t;
}
private JButton createDeleteButton() {
JButton b = new JButton("Delete checked rows");
b.addActionListener(new ActionListener() {
#SuppressWarnings("unchecked")
#Override
public void actionPerformed(ActionEvent e) {
Vector<Vector<Object>> removedRows = new Vector<>();
DefaultTableModel modelLeft = (DefaultTableModel) tblLeft.getModel();
for(int r=0;r!=modelLeft.getRowCount();++r)
if((Boolean) modelLeft.getValueAt(r,COL_CHECK)) {
removedRows.add((Vector<Object>) modelLeft.getDataVector().get(r));
modelLeft.removeRow(r--);
}
DefaultTableModel modelRight = (DefaultTableModel) tblRight.getModel();
for(Vector<Object> row : removedRows)
modelRight.addRow(row);
}
});
return b;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame("Delete checked rows in JTable from button");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(new TestTableDeleteRows());
f.pack();
f.setVisible(true);
}
});
}
}
Result:
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());