How to Verify Required Fields in JTable - java

I have a JTable and I need to verify the input of 2 columns. That is 2 specific columns need to contain proper values in every cell. If they do then I want to enable a button. I know how to enable a button but I don't know where/how to verify those 2 columns. What table model method would be the appropriate place to verify those cells and enable the button, if any? I'm thinking I need a listener for those cells and process them in loseFocus(). The only issue is if the user leaves the cursor in one of those cells so it never loses focus even though the entry is valid. This must be a relatively common practice so there must be a best programming practice to accomplish it. TIA.

A TableModelListener added to the table's model will notify you of any change in the model's data. Within the listener, you can iterate through the rows, extracting column data with getValueAt(...) method, and then enable/disable your JButton or its Action accordingly.
For example, in the following code there are two columns of integers. The ints in the B column must be greater than the A column for the data to be valid. If this is not the case (or if any value is null), the button is disabled:
import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
public class TableFun extends JPanel {
private Integer[][] DATA = {{1, 2}, {3, 4}, {5, 6}};
private String[] COL_NAMES = {"A", "B"};
private DefaultTableModel model = new DefaultTableModel(DATA, COL_NAMES) {
public java.lang.Class<?> getColumnClass(int columnIndex) {
return Integer.class;
};
};
private JTable table = new JTable(model);
private JButton myButton = new JButton("My Button");
public TableFun() {
model.addTableModelListener(new TableModelListener() {
#Override
public void tableChanged(TableModelEvent e) {
boolean valid = true;
for (int row = 0; row < model.getRowCount(); row++) {
Integer valueA = (Integer) model.getValueAt(row, 0);
Integer valueB = (Integer) model.getValueAt(row, 1);
if (valueA == null || valueB == null || valueA.compareTo(valueB) > 0) {
valid = false;
}
}
myButton.setEnabled(valid);
}
});
JPanel panel = new JPanel();
panel.add(myButton);
setLayout(new BorderLayout());
add(new JScrollPane(table));
add(panel, BorderLayout.PAGE_END);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
TableFun mainPanel = new TableFun();
JFrame frame = new JFrame("TableFun");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}

Related

JTable appearing blank

I will only post the part that matters.
I have created a JFrame with a JPanel in it, that contains some JTextFields, JTextAreas and a JList. I know want to add a JTable to show some results, but it will appear blank. I tried checking out some posts, but I wasn't able to fix it.
I entered 2 rows manually, but they wouldn't appear. Nor would the column names. Please help!
import javax.swing.*;
import javax.swing.table.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
public class GUI_Automata_Ex_1 extends JFrame {
public static int ScreenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
public static int ScreenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
public static int WindowWidth = ScreenWidth*3/4;
public static int WindowHeight = WindowWidth*9/16;
public static int unit = WindowWidth/160;
// tables used
static String[] columnNames = {"word", "length", "result"};
static Object[][] data = {{"abbaa", new Integer (5), "belongs"}, {"baabbb", new Integer (6), "does not belong"}};
public static JTable table_saved_words = new JTable(data, columnNames);
public static DefaultTableModel dtm_saved_words = new DefaultTableModel();
public static JScrollPane sp_saved_words;
public GUI_Automata_Ex_1 () {
// this will only run on ultrawide screens (e.g. 21:9 or 32:9) because the window is 16:9 optimized
if (ScreenWidth/2 > ScreenHeight) {
WindowHeight = ScreenHeight*3/4;
WindowWidth = WindowHeight*16/9;
unit = WindowWidth/160;
}
this.setTitle("Automata Theory 1st Excercise");
this.setBounds(ScreenWidth/2-WindowWidth/2,ScreenHeight/2-WindowHeight/2,WindowWidth,WindowHeight);
this.setResizable(false);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBackground(colorBG);
Board board = new Board();
this.setContentPane(board);
this.setLayout(null);
// TABLES
// settings for table_saved_words
table_saved_words.setBackground(Color.white);
table_saved_words.setFont(fontM);
table_saved_words.setModel(dtm_saved_words);
table_saved_words.setPreferredScrollableViewportSize(new Dimension(unit*86, unit*50));
table_saved_words.setFillsViewportHeight(true);
sp_saved_words = new JScrollPane(table_saved_words);
board.add(sp_saved_words);
sp_saved_words.setBounds(unit*68, unit*32, unit*86, unit*50);
sp_saved_words.setWheelScrollingEnabled(true);
sp_saved_words.setViewportView(table_saved_words);
sp_saved_words.setVisible(false);
dtm_saved_words.addRow(new Object[]{"aabbbbaa", 5, "belongs"});
}
public class Board extends JPanel {
public void paintComponent (Graphics g) {
}
}
}
}
Here is a screenshot:
https://i.stack.imgur.com/AHtLf.png
The JTable is on the bottom-right. I did not include the code part for the other J-components.
What I want to do after I get the lists to show is simply add some rows as the window runs (words that the user enters and either belong to a dictionary or not and their length), but the part I'm stuck on is getting the JTable to show the columns and data.
Your table model has no columns, so it never shows the data you add to it.
From the documentation for the zero-argument DefaultTableModel constructor
Constructs a default DefaultTableModel which is a table of zero columns and zero rows.
Initially, your table has a valid table model created automatically:
JTable table_saved_words = new JTable(data, columnNames);
But then you create a new model, with no columns:
DefaultTableModel dtm_saved_words = new DefaultTableModel();

Java Swing: Making a graceful Jscrollpane with or without a JTable

I needed a UI that collects similar pieces of data over and over again which can best be described as a batch entry.To input the batch, i needed a scrollpane that adjusts to whatever size of data the user is inputting. To do this smoothly,I relied on the jtable attached to a jscrollpane, and the row to be a jpanel. I am facing some troubles with this solution, that is
I dont know how to access the textfields in my jpanel
I dont know how to add more jpanels as rows on my jtable.
I may add that i jumped to this solution(which may not necessarily be the best) after trying to add many jpanel to one jscrollpane over and over again but this did not work well.This alternative failed as it seems adding a jpanel through the setviewportview was not designed to accept a new panel to expand the view.A variant of the same is one jpanel attached to one scrollpane, then add many jpanels on the mainpanel attached to the scrollpane but the view did not expand and the scrollpane stayed the same.I have checked out oracle's scrollpane tutorialand seen the dynamic changing of a client and how to revalidate the client but am not sure how this will apply in my case where am adding a new jpanels(unless i add them on one jpanel which i keep setting a new clients preferred size as i add a new jpanel.)
NB:
The jpanel i keep adding is not really new as i am iterating it.
Another third solution i had tried is using a flexible gridlayout which its row is a variable 'x' which the user can choose and the a number of 'x' jpanels can be added, problem was,and this is the main problem, the scrollpane was not gracefull to allow expansion so neither did it adjust to a new view.
Note that the scrollpane i need should not be attached to the JFrame but to a an inner view (like a scrollpane for North or Center only in a borderLayout UI) within the JFrame.
I know that the jpanel as a row can be replaced by a normal row where each cell on the row can act either as a jtextfield,jlabel or whatever component i need, but this approach was taken for a particular need to make the JTable look like an actual physical document.
How do I make a good scrollpane that expands dynamically to addition of jpanels ?
The code below shows two attempts of adding jpanels in the hope of expanding the scrollpane but both fail.
Solution one renders each cell as a jpanel but i cannot access the textfield on the jpanel thus i cannot get the data from the user and i cannot also add another row to create a batch.
public class JTablePanelRow extends JFrame implements ActionListener{
JButton addRow = new JButton("Add Row");
JTable table = new JTable();
JScrollPane spane = new JScrollPane();
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel panelRow = new JPanel();
JLabel lblName = new JLabel("NAME");
JTextField txName = new JTextField();
JLabel lblAge = new JLabel("AGE");
JTextField txAge = new JTextField();
TblModel tblmodel = new TblModel();
public static void main(String[] args) {
JTablePanelRow tblPane = new JTablePanelRow();
tblPane.init();
}
void init(){
panelRow.setLayout(new GridLayout(2,2,4,4));
panelRow.add(lblName);
panelRow.add(txName);
panelRow.add(lblAge);
panelRow.add(txAge);
table.setModel(tblmodel);
table.setRowHeight(50);
table.getColumn("A").setCellRenderer(new PanelRenderer(panelRow));
spane.setViewportView(table);
addRow.addActionListener(this);
mainPanel.add(addRow,"North");
mainPanel.add(spane,"Center");
this.getContentPane().add(mainPanel);
this.setVisible(true);
this.setSize(new Dimension(400,500));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==addRow){
tblmodel.addNewRow();
}
}
}
class TblModel extends AbstractTableModel{
#Override
public int getRowCount() {
return 1;
}
#Override
public int getColumnCount() {
return 1;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
return "";
}
public void addNewRow(){
//how to add the jpanel again
}
}
class PanelRenderer extends DefaultTableCellRenderer{
JPanel entryPn = new JPanel();
public PanelRenderer(JPanel entryPn){
this.entryPn = entryPn;
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
entryPn.setPreferredSize(new Dimension(200,50));
entryPn.setBackground(Color.pink);
return entryPn;}
}
Solution two tries to add jpanels through a flexible gridlayout but the jpanels are not added or not scrollable.
public class GridLayoutTrick extends JFrame{
JPanel mainPanel = new JPanel(new BorderLayout());
JScrollPane scroll = new JScrollPane();
JPanel entryPanel = new JPanel();
JPanel rowPanel = new JPanel();
int batchNumber = 10;
JPanel northPanel = new JPanel();
public static void main(String[] args) {
GridLayoutTrick glt = new GridLayoutTrick();
glt.init();
}
void init(){
rowPanel.setBackground(Color.PINK);
rowPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK,5));
rowPanel.setPreferredSize(new Dimension(100,50));
entryPanel.setLayout(new GridLayout(batchNumber,1,4,4));
for(int i = 0;i < batchNumber;i++){
entryPanel.add(rowPanel);
}
entryPanel.setBackground(Color.BLUE);
scroll.setViewportView(entryPanel);
mainPanel.add(northPanel,"North");
mainPanel.add(scroll,"Center");
this.getContentPane().add(mainPanel);
this.setVisible(true);
this.setSize(new Dimension(400,400));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Solution two tries to add jpanels through a flexible gridlayout but the jpanels are not added or not scrollable.
for(int i = 0;i < batchNumber;i++){
entryPanel.add(rowPanel);
}
You only have 1 "rowPanel".
You need to create a separate instance of the "rowPanel" every time you want to add it the the "entryPanel".
mainPanel.add(northPanel,"North");
mainPanel.add(scroll,"Center");
Don't use magic constants. Use the fields from the API:
BorderLayout.PAGE_START
BorderLayout.CENTER
Although I really think the suggestions by MadProgrammer are a better solution.
I'm left scratching my head why you wouldn't just use the editable capabilities of the JTable alone, you're just making life more difficult for yourself by trying to use a JPanel as the cells renderer/editor
You should start by taking a closer look at How to use tables to get a better understanding of how tables are suppose to be used
The following is an overly simplified example which allows you to add any number of rows and edit the values at each cell in the table...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private DefaultTableModel model;
public TestPane() {
setLayout(new BorderLayout());
model = new DefaultTableModel(new Object[]{"Name", "Age"}, 0);
JTable table = new JTable(model);
add(new JScrollPane(table));
JButton btn = new JButton("Add");
add(btn, BorderLayout.SOUTH);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
model.addRow(new Object[] {"", ""});
table.editCellAt(model.getRowCount() - 1, 0);
table.getEditorComponent().requestFocusInWindow();
}
});
}
}
}
Personally, I'd set up a container object to hold the data and manage it through a custom TableModel, but that's me.
I'd also look at implementing a continuous editing model to allow the user to move easily through the table in a "continuous" editing mode

From JTable to Histogram - Swing

I have a JTable with three columns. For each rows I have a word, its type and the number of occurrences; for example in the next picture, the String "Rosing Prize" is present two times.
Starting from this JTable I want to build an histogram that takes as input the first and the last column. The first column is the name of bars and the last is its height; when the user selects some rows, they are represent in the histogram.
For example in this situation I have 4 rows selected:
The output are four J-Frames: the first with just one bar (that represents the first row); in the second J-Frame I have two bars (first and second row); in the third JFrame there are 3 bars for first, second and third row and, finally in the forth and last JFrame I have the correct output:
I thought about two possibilities to fix this problem:
to add a Jbutton and after one presses it the selected rows are drawn in the histogram
to add all JFrame to an ArrayList and to print only the last.
Are there better solutions?
I added a ListSelectionListener listener to my table model.
In your ListSelectionListener, update the chart's dataset only when getValueIsAdjusting() is false. This will defer updates until the selection is stable.
If I understand your question right, ListSelectionListener will solve your problem.
Define a selection listener first:
class MySelectionListener implements ListSelectionListener {
Then add it to your table's selection model:
MySelectionListener selectionListener = new MySelectionListener();
table.getSelectionModel().addListSelectionListener(selectionListener);
Edit:
Create a MouseListener. Then add it to your table. Here is a working sample code:
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JTable;
public class TableTest {
JFrame window = new JFrame();
private TableTest() {
createWindow();
}
public void createWindow() {
Object rowData[][] = { { "Row1-Column1", "Row1-Column2", "Row1-Column3" },
{ "Row2-Column1", "Row2-Column2", "Row2-Column3" },
{ "Row3-Column1", "Row3-Column2", "Row3-Column3" } };
Object columnNames[] = { "Column One", "Column Two", "Column Three" };
JTable table = new JTable(rowData, columnNames);
table.addMouseListener(new SelectionListener(table));
window.add(table);
window.pack();
window.setVisible(true);
}
public static void main(String[] args) {
new TableTest().createWindow();
}
}
class SelectionListener extends MouseAdapter {
JTable table;
public SelectionListener(JTable table) {
this.table = table;
}
#Override
public void mouseReleased(MouseEvent e) {
int[] rows = table.getSelectedRows();
for (int i = 0; i < rows.length; i++) {
System.out.println(rows[i]);
}
}
}

Preferred height of JPanel is lower then combined height of its children in table renderer

I have a JTable for which the renderer returns a JPanel composed of multiple JLabel instances. One of those JLabels can contain HTML used among other things to split the output over multiple lines using <br/> tags.
To show the multiple lines in the table, the renderer calls in the getTableCellRendererComponent method
table.setRowHeight(row, componentToReturn.getPreferredSize().height);
to dynamically update the row height, based on the contents. This only works correctly if componentToReturn indicates a correct preferred size.
It looks however that the getPreferredSize returns bogus values. The preferred height of the returned component is smaller than the sum of the heights of the labels inside the component.
Here is a little program illustrating this behaviour (without using a JTable)
import java.awt.*;
import javax.swing.*;
public class SwingLabelTest {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
LabelPanel renderer = new LabelPanel();
Component component = renderer.getComponent(false);
//asking for a bigger component will not
//update the preferred size of the returned component
component = renderer.getComponent(true);
}
});
}
private static class LabelPanel {
private final JPanel compositePanel;
private final JLabel titleLabel = new JLabel();
private final JLabel propertyLabel = new JLabel();
public LabelPanel() {
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.PAGE_AXIS));
labelPanel.add(titleLabel);
labelPanel.add(propertyLabel);
compositePanel = new JPanel(new BorderLayout());
//normally it contains more components,
//but that is not needed to illustrate the problem
compositePanel.add(labelPanel, BorderLayout.CENTER);
}
public Component getComponent( boolean aMultiLineProperty ) {
titleLabel.setText("Title");
if ( aMultiLineProperty ){
propertyLabel.setText("<html>First line<br/>Property: value</html>");
} else {
propertyLabel.setText("Property: value");
}
int titleLabelHeight = titleLabel.getPreferredSize().height;
int propertyLabelHeight = propertyLabel.getPreferredSize().height;
int compositePanelHeight = compositePanel.getPreferredSize().height;
if ( compositePanelHeight < titleLabelHeight + propertyLabelHeight){
throw new RuntimeException("Preferred size of the component returned "
+ "by the renderer is incorrect");
}
return compositePanel;
}
}
}
As I am aware that the previous example is a bit far-fetched, here an example which includes a JTable
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class SwingTableTest {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
DefaultTableModel tableModel = new DefaultTableModel(0, 1);
JTable table = new JTable(tableModel);
table.setDefaultRenderer(Object.class, new DataResultRenderer());
tableModel.addRow(new Object[]{new Object()});
tableModel.addRow(new Object[]{new Object()});
tableModel.addRow(new Object[]{new Object()});
JFrame testFrame = new JFrame("TestFrame");
testFrame.getContentPane().add(new JScrollPane(table));
testFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
testFrame.setSize(new Dimension(300, testFrame.getPreferredSize().height));
testFrame.setVisible(true);
}
});
}
private static class DataResultRenderer implements TableCellRenderer {
private final JPanel compositePanel;
private final JLabel titleLabel = new JLabel();
private final JLabel propertyLabel = new JLabel();
public DataResultRenderer() {
JPanel labelPanel = new JPanel();
labelPanel.setOpaque(false);
labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.PAGE_AXIS));
labelPanel.add(titleLabel);
labelPanel.add(propertyLabel);
compositePanel = new JPanel(new BorderLayout());
//normally it contains more components,
//but that is not needed to illustrate the problem
compositePanel.add(labelPanel, BorderLayout.CENTER);
}
#Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
titleLabel.setText("Title");
if ( row == 2 ){
propertyLabel.setText("<html>Single property: value</html>");
} else {
String text = "<html>";
text += "First property<br/>";
text += "Second property<br/>";
text += "Third property:value";
text += "</html>";
propertyLabel.setText(text);
}
int titleLabelHeight = titleLabel.getPreferredSize().height;
int propertyLabelHeight = propertyLabel.getPreferredSize().height;
int compositePanelHeight = compositePanel.getPreferredSize().height;
if ( compositePanelHeight < titleLabelHeight + propertyLabelHeight){
throw new RuntimeException("Preferred size of the component returned "
+ "by the renderer is incorrect");
}
table.setRowHeight(row, compositePanel.getPreferredSize().height);
return compositePanel;
}
}
}
I am looking for a way to update the row height of the table to ensure that the multi-line content is completely visible, without knowing up front how many lines each row will contain.
So either I need a solution to retrieve the correct preferred size, or my approach is completely wrong and then I need a better one.
Note that the above examples are simplified. In the real code, the "renderer" (the code responsible for creating the component) is decorated a few times. This means that the outer renderer is the only with access to the JTable, and it has no knowledge about what kind of Component the inner code returns.
Because setRowHeight() "Sets the height, in pixels, of all cells to rowHeight, revalidates, and repaints," the approach is unsound. Absent throwing an exception, profiling shows 100% CPU usage as an endless cascade of repaints tries to change the row height repeatedly. Moreover, row selection becomes unreliable.
Some alternatives include these:
Use TablePopupEditor to display multi-line content on request from a TableCellEditor.
Update an adjacent multi-line panel from a TableModelListener, as shown here.

KeyListeners for a JComboBox which is used as a cell editor in a table

I am sorry if this sounds likes a basic question but I am relatively new to java. I have a JComboBox which I populate from a database and then use it in a JTable. I do that using the following code:
itemEditortxt = new JComboBox(buildComboBoxmodel("SELECT item_name FROM items ORDER BY item_name"));
AutoCompleteDecorator.decorate(itemEditortxt);
TableColumn ledgerColumn = invoicePurchasedTable.getColumnModel().getColumn(0);
ledgerColumn.setCellEditor(new ComboBoxCellEditor(itemEditortxt));
I am trying to add key listeners to the JComboBox but for some reason they are not being called when I press any key when the focus is on the cell which uses the JComboBox. Following is how I add the litterers:
itemEditortxt.addKeyListener(new KeyListener() {
#Override
public void keyPressed(KeyEvent e) {System.out.print("line1");}
#Override
public void keyReleased(KeyEvent e) {System.out.print("line2");}
#Override
public void keyTyped(KeyEvent e) {System.out.print("line3");}
});
Can someone please tell me what Im doing wrong? Thanks.
Following is the SSCCE. There are two similar JComboBoxes, one is added normally and the other is used as a cell editor. In the first one the user can use the keyboard arrows and then press ENTER in order to make a selection. This is not the case for the one in the table. Thanks:
package sp2;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import javax.swing.table.*;
import org.jdesktop.swingx.autocomplete.*;
class InvoicePurchasedModel extends DefaultTableModel {
public InvoicePurchasedModel (Vector<Vector<Object>> data, Vector<String> columnNames) {
super(data, columnNames);
}
#Override
public Class getColumnClass(int col) {
if (col == 0)
return String.class;
else
return Double.class;
}
}
public class SP2 {
JFrame mainPage;
JTabbedPane jtp;
JPanel mainPanel;
JPanel purchasedInvoicesPanel;
RXTable invoicePurchasedTable;
DefaultTableModel invoicePurchasedtm;
JComboBox itemEditortxt;
JComboBox itemEditortxt2;
SP2() {
mainPage = new JFrame("System");
mainPage.getContentPane().setLayout(new GridLayout());
mainPage.setSize(1200, 1200);
mainPage.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
createTabs();
mainPage.setVisible(true);
}
void createTabs() {
jtp = new JTabbedPane();
mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout());
mainPage.getContentPane().add(jtp);
purchasedInvoicesPanel = new JPanel();
jtp.addTab("Purchased", purchasedInvoicesPanel);
invoicePurchasedtm = buildInvoicePurchasedTableModel();
invoicePurchasedTable = new RXTable(invoicePurchasedtm) {
private final KeyStroke tabKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
public void changeSelection(int row, int column, boolean toggle, boolean extend)
{
super.changeSelection(row, column, toggle, extend);
if (editCellAt(row, column))
{
Component editor = getEditorComponent();
editor.requestFocusInWindow();
}
}
};
invoicePurchasedTable.setCellSelectionEnabled(true);
invoicePurchasedTable.setSelectAllForEdit(true);
purchasedInvoicesPanel.setLayout(new BoxLayout(purchasedInvoicesPanel, BoxLayout.PAGE_AXIS));
JPanel purchasedInvoicesPanel1 = new JPanel();
JPanel purchasedInvoicesPanel2 = new JPanel();
purchasedInvoicesPanel.add(purchasedInvoicesPanel1);
purchasedInvoicesPanel.add(purchasedInvoicesPanel2);
JScrollPane invoicePurchasedscrollPane = new JScrollPane(invoicePurchasedTable);
invoicePurchasedTable.setPreferredScrollableViewportSize(new Dimension(1000, 400));
String[] names = {"aa", "aa1", "aa2", "bb", "bb1", "bb2"};
itemEditortxt = new JComboBox(names);
itemEditortxt2 = new JComboBox(names);
AutoCompleteDecorator.decorate(itemEditortxt);
AutoCompleteDecorator.decorate(itemEditortxt2);
TableColumn ledgerColumn = invoicePurchasedTable.getColumnModel().getColumn(0);
ledgerColumn.setCellEditor(new ComboBoxCellEditor(itemEditortxt));
purchasedInvoicesPanel1.add(itemEditortxt2);
purchasedInvoicesPanel2.add(invoicePurchasedscrollPane);
}
public static DefaultTableModel buildInvoicePurchasedTableModel() {
Vector<String> columnNames = new Vector<String>();
columnNames.add("Item");
columnNames.add("Quantity");
columnNames.add("Unit Price");
columnNames.add("Amount");
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
Vector<Object> vector = new Vector<Object>();
vector.add("");
vector.add(0.00);
vector.add(0.00);
vector.add(0.00);
data.add(vector);
return new InvoicePurchasedModel(data, columnNames);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SP2();
}
});
}
}
"I am trying to add key listeners to the JComboBox but for some reason they are not being called when I press any key when the focus is on the cell which uses the JComboBox."
I think what you may be trying to do is add a listener to "text field" for the combobox. The first thing you need to do is actually get the editor component. then you can add a DocumentListener to the Document of the JTextComponent
JTextComponent editor = (JTextComponent) comboBox.getEditor().getEditorComponent();
editor.getDocument().addDocumentListener(new DocumentListener(){
...
});
Ok, so the problem was caused by the AutoCompleteDecorator. I deactivated it and used instead the AutoCompletion.enable(employeeDelete). Now the ENTER and TAB keys work as expected. I appreciate all the comments that helped me.

Categories