Java - Adding items from arraylist to JTable when button clicked - java

I was trying to write the GUI for my program. I have a Product class in which I store price and names of the products in an arraylist. I also have an Order arraylist which consists of the orders given to each waiter.I put all my products in a JComboBox and added an action listener to each to show the price of each product when clicked by updating the text of a JLable. Then there is a JSpinner to get the quantity of the products selected. And lastly there is an "Add" button that I wanted to use to update the Jtable with product name and its quantity and its total price while also adding that product to the arraylist of Orders. I have no idea how populate JTable and couldn't understand much from other answers because they were using netbeans. I thought of just using a simple JLabe but also I couldn't understand how to update the text and add a new line to the label after I select and add each product. Can you explain how I can achieve this? part of my code looks like this
box1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Product prod = (Product) box1.getSelectedItem();
price.setText(String.valueOf(prod.getSellingPrice()));
add.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int numbs = (Integer) spinner.getValue();
for (int i = 0; i <= numbs; i++) {
order.addProduct(prod);
}
JLabel label = new JLabel();
lists.add(label);
label.setText(prod.getName() + " " + numbs + " " + numbs * prod.getSellingPrice());
}
});
}
});

If I understand your question correctly, you want a JTable in your gui, which shows the orders (or other data possibly) if a button is clicked.
Firstable, I would advise you to check out
https://docs.oracle.com/javase/tutorial/uiswing/components/table.html
as they explain the use of the JTable very well.
Anyway, to answer your question:
Firstable, you have to create a table and add it to your gui:
//creating a new JTable without any data and one column 'Orders'
//you might wanna declare the JTable before that, since it will be referred to in the refresh() method
JTable table = new JTable(new String[][]{{""}}, new String[]{"Orders"});
//creating a scrollpane to put the table in, in case the table data exeeds the table
JScrollPane scrollPane = new JScrollPane();
//here you would e.g. set the bounds of the scrollpane etc
scrollPane.setBounds(x,y,w,h)
//setting the table in the scrollpane
scrollPane.setViewportView(table);
//adding the scrollpane to your contentPane
contentPane.add(scrollPane);
Now you want to refresh the table, if a button is pressed, so I would put a reference to the following method in the actionlistener of the button:
//the method to refresh the table containing the orders (or possibly other data)
void refresh(List<String> orders) {
//creating a new TableModel for the table
DefaultTableModel model = new DefaultTableModel();
//set the data in the model to the data that was given, new Object[]{0} points to the 1st column
model.setDataVector(getDataVector(data), new Object[]{"Orders});
//set the model of the table to the model we just created
table.setModel(model);
}
Since model.setDataVecor() takes rows and not columns as its first parameter, you have to make the list of data fitting as a data vector, for example with the following method:
Object[][] getDataVector(List<String> data){
Object[][] vector = new Object[data.size()][1];
for(int i=0; i<data.size(); i++){
vector[i][0] = data.get(i);
}
return vector;
}

Related

simplier way to add jbutton to jtable

well i am making this system that has a table, and i have to put buttons in the last column. i've been researching but all the codes i saw are really confusing. there is one tho, but there are still some parts that i didn't understand. here's the site where i got it http://www.javaquery.com/2013/05/how-to-implement-jbutton-in-jtable.html
String[] InvoiceArray = new String[20];
//Declare above variable globally. Used by two-three methods. Change variable name as per your need.
/*
* import the ButtonColumn class if you are not working in IDE
* I used formWindowOpened event to load content in Jtable but you can use other event.
* All you need is put the code with in that event.
*/
private void formWindowOpened(java.awt.event.WindowEvent evt) {
Object[][] rowData = new Object[4][2]; // 4: is number of row ; 2: is number of column
Object columnNames[] = {"Invoice No", "View Report"}; // Name of columns
for (int i = 0; i < 4; i++) {
InvoiceArray[i] = i + "-2345";
rowData[i][0] = i + "-2345";
rowData[i][1] = "View Order " + i; // Can change the text of button.
}
DefaultTableModel tm = new DefaultTableModel(rowData, columnNames);
jTable1.setModel(tm);
ButtonColumn buttonColumn = new ButtonColumn(jTable1, showOrder, 1); // 1: is column number. column count starts with 0,1,2...
}
what's the InvoiceArray for? and should i make the showOrder from the last line? and also, i didn't understand the code he posted on how to make a listener on it. here it is:
Action showOrder = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
//JTable table = (JTable) e.getSource(); // If you have multiple component following the ActionEvent
int modelRow = Integer.valueOf(e.getActionCommand());
if (InvoiceArray[modelRow] != null) {
/* We are placing invoice no in array
* And track the button click index
* And fetch index in invoice no
*/
System.out.println("Your Invoice No:" + InvoiceArray[modelRow]);
} else {
JOptionPane.showMessageDialog(rootPane, "No records found!");
}
}
};
i know there are some explanations already. i understand some of them but not all. just a simplier way to add jbutton on jtable and also listeners for the jbutton. thank you so much
just a simplier way to add jbutton on jtable and also listeners for the jbutton.
There is no simple way. You need to understand how renderers and editors work in a JTable. Read the section from the Swing tutorial on Concepts: Renderers and Editors for the basics.
Then you can check out Table Button Column which does the hard work for you. You only need to provide the Action to be invoked when you click on the button.
what's the InvoiceArray for?
It is used to load data into the JTable. This is basic usage of a JTable and has absolutely nothing to do with adding a button to a column of the table.
After the data is loaded you should forget about the invoiceArray. The Action you write should access the data via the TableModel or the JTable.

Is it possible jtable row in optionDialog box

I have a jtable.
Some of the cells contain very long strings and trying to scroll left and right through it is difficult. My question is whether it is possible to show a row from a JTable in a pop-up eg showDialog type box (ie where the selected row is organised as a column).
Even a link to a tutorial would do.
I have scoured the internet but I don't think I'm really using the correct keywords as I get a lot of right-click options.
If this is not possible are there any other suggestions for how to do this?
As shown here, the JOptionPane factory methods will display the Object passed in the message parameter. If that message is a one column JTable, you can recycle any custom renderers and editors that were applied to the original table.
In outline,
Add a ListSelectionListener to your table and get the selectedRow.
Iterate through the table's model and construct a newModel whose rows are the columns of the selectedRow.
Create a JTable newTable = new JTable(newModel).
Apply any non-default renderers and editors.
Pass a new JScrollPane(newTable) as the message parameter to your chosen JOptionPane method.
Starting from this example, the following listener displays the dialog pictured.
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
int selectedRow = table.convertRowIndexToModel(table.getSelectedRow());
if (selectedRow > -1) {
DefaultTableModel newModel = new DefaultTableModel();
String rowName = "Row: " + selectedRow;
newModel.setColumnIdentifiers(new Object[]{rowName});
for (int i = 0; i < model.getColumnCount(); i++) {
newModel.addRow(new Object[]{model.getValueAt(selectedRow, i)});
}
JTable newTable = new JTable(newModel) {
#Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(140, 240);
}
};
// Apply any custom renderers and editors
JOptionPane.showMessageDialog(f, new JScrollPane(newTable),
rowName, JOptionPane.PLAIN_MESSAGE);
}
}
});
I want to show all the values in the row, each in their cel, organised vertically- that's what I meant by 'in a column'.
That should be in the question, not in the comment.
There is no default functionality for this but you can do it yourself.
You could create a JPanel (maybe using a GridBagLayout), with two labels in a row to represent the data in a column of the selected row of the table.
For the data in the first label you would use the getColumnName(...) method of the TableModel.
For the data in the second label you would use the getValueAt(...) method of the TableModel.
Another option is to simply display a tool tip for the cell. See the section from the Swing tutorial on Specifying ToolTips For Cells for more information.
You may use the following ListSelectionListener:
final JTable dialogTable =new JTable();
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent event) {
int selectedRow = table.getSelectedRow();
if (selectedRow > -1) {
int columnCount = table.getModel().getColumnCount();
Object[] column = new Object[]{"Row "+(selectedRow+1)};
Object[][] data = new Object[columnCount][1];
for (int i = 0; i < columnCount; i++) {
Object obj = table.getModel().getValueAt(selectedRow, i);
data[i][0] = obj;
}
dialogTable.setModel(new DefaultTableModel(data, column));
JOptionPane.showMessageDialog(null, new JScrollPane(dialogTable));
}
}
});
This is going to show a message dialog which contains a JTable with data that is derived from the selected row. Hope this helps you.

Add values to existing JTable dynamically

I've created a JTable using following way. This table has 5 columns and 4 rows.
All 4 rows are empty in this status.
String[] columns = {"Emplotee ID","Name","Address","City","Salary"};
//Table that already have 4 empty rows
DefaultTableModel model = new DefaultTableModel(columns,4);
JTable detail = new JTable(model);
JScrollPane scroll = new JScrollPane(detail);
Now I want to add values into those empty rows using String array.
The GUI of this program has 5 JTextFields to get user input. When I enter values into JTextFileds and click Add button, all JTextFiled values get by String array named values.
String[] values = new String[6];
//When click addButton all textFiled data should go into table
addButton.addMouseListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent evt){
values[0] = idField.getText(); //get JTextFields data into array
values[1] = nameField.getText();
values[2] = addressField.getText();
values[3] = cityField.getText();
values[4] = salaryField.getText();
//What now?
}
});
I know I can use this to add new row into the table. But this is not the feature what I want.
DefaultTableModel newModel = (DefaultTableModel)detail.getModel();
newModel.addRow(values);
Set contents of an existing table row with:
int row;
....
// make sure row is set to index of the table row
// you want to populate
for (int c=0; c<values.length; ++c)
detail.setValueAt(values[c], row, c);
TableModel also has setValueAt method, if you prefer.

JTable JComboBox is defaulting to display 1st item when list is expanded

I have been trying to determine why my JComboBox is displaying the 1st item in the list through numerous Google searches, but I'm struggling to find relevant help. It could be that I don't know the correct terminology (hence the overly specific title of this question) and thus not finding the information that would explain my issue. I checked out the JComboBox API, and few of the listeners and models that it uses, but they did not seem likely candidates.
The JComboBox in question is inside a JTable, so I am not aware if that changes the default behaviour of it. The code I am using is as below:
//row and col are final due to usage inside anonymous inner class
public TableCellEditor getCellEditor(final int row, final int col)
{
String[] listItems = new String[arrayList.getSize()];
int i = -1;
for(String s : arrayList)
{
i++;
listItems[i] = s;
}
JComboBox<String> box = new JComboBox<>(listItems);
box.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
if(e.getStateChange() == ItemEvent.SELECTED)
{
if(e.getItem().equals("Add/Edit Projectile"))
{
//Where Editor is a JFrame that will be opened
new Editor();
}
}
}
});
DefaultCellEditor list = new DefaultCellEditor(box);
}
Please note that the Arraylist in my program does not contain Strings, but instead a more complicated set of custom objects that I believe would distract from the main issue.
I haven't included a Renderer for JComboBox's in the JTable as I was happy enough with the way it appeared, and figured that my problem was more going to be something I have neglected to implement in the model/implemented wrong.
I've also provided a couple of screenshots to better portray my problem. The first image is when the JComboBox is not selected, and simply displaying the currently selected item.
The second image is when I have just clicked the JComboBox to bring up the list. As depicted, it will immediately bring up that first item, no matter what it is.
If anyone has any suggestions as to where to look/solutions, I would be very grateful.
EDIT
My particular table has two columns, where the left column is a variable name, and the right column is the value associated with the variable. The tables role is to display the properties of a selected object, where each value for different variable for different objects are likely to not be the same.
In this particular case, the cell displays a JComboBox with all the available Projectiles in the game we are making. Each enemy has a different type of projectile it defaults to. So when I click on a different enemy in our game area, the table will display all of their current properties (defaults if they have not been changed).
Enemies do have a getter for the Projectile, so I could determine what the currently selected enemy is, get it's projectile, do a toString() to find how it is to be represented in the list, and do a setValueAt().
The only problem is at the moment it is always selecting the first item in the list when the list is expanded.
Unless the values for the JComboBox are dynamically generated for each row, you should be able to just prepare the CellEditor ahead of time, for example...
JComboBox cb = new JComboBox(new String[]{"1", "2", "3", "4"});
DefaultCellEditor editor = new DefaultCellEditor(cb);
JTable table = new JTable(new DefaultTableModel(5, 1));
table.getColumnModel().getColumn(0).setCellEditor(editor);
This will set the selected value of the editor to the value of the cell when the editing process starts
Updated
In the case where the combobox values are dynamically generate per row, you could do something more like...
JComboBox cb = new JComboBox();
DefaultCellEditor editor = new DefaultCellEditor(cb) {
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
JComboBox editor = (JComboBox) getComponent();
String[] listItems = new String[arrayList.getSize()];
int i = -1;
for (String s : arrayList) {
i++;
listItems[i] = s;
}
DefaultComboBoxModel model = new DefaultComboBoxModel(listItems);
editor.setModel(model);
editor.setSelectedItem(value);
return editor;
}
};
JTable table = new JTable(new DefaultTableModel(5, 1));
table.getColumnModel().getColumn(0).setCellEditor(editor);
Note the use of editor.setSelectedItem(value);, this will set the selected value to the cells current value...
You could also re-use the model, clearing it each time and re-filling it with new values. You might find this more efficient if you have a large number of rows as you won't need to constantly create a new model each time a cell is edited
Thow this is an oldie...
Your problem is most likely you don't implement "equals" in the class used in the combo.
The Combo needs to select the current item when it is being prepared and does so by iterating through the elements of the model and selects the first one that is equal to the value in the cell. If none is encountered then it leaves the combo as is (either first element or the last used element in a previous cell edit)
This is how you should default to the previously selected element:
//...
Object selectedItem = box.getSelectedItem();
//Add some elements to the jComboBox
box.setSelectedItem(selectedItem);

Increase row count in a JTable

I'm developing an address book for my classmates but I'm having a problem with a JTable. Here you can see a preview of the program, I'm using NetBeans [click]. If you click Add to the Address Book, the program adds a new row in that table and fills its cells with the data located in text fields below. I'm using the following code but the row count doesn't increase.
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
int h;
DefaultTableModel model = new DefaultTableModel();
h=jTable1.getRowCount()+1;
model.setRowCount(h);
jTable1.setValueAt(jTextField2.getText(), h, 1);
jTable1.setValueAt(jTextField3.getText(), h, 2);
//I'll use more setValueAt() because I must fill all the cells
}
Could you give me some advice as to how to fix this problem?
You created a new model. You should take the model that is assigned to the table.
DefaultTableModel model = new DefaultTableModel();
should be:
DefaultTableModel model = jTable1.getModel();

Categories

Resources