Adding JComboBox to JTable: ComboBoxes in different rows are not independent - java

I have a table with a combobox where the user can select a country. I have the problem, that comboBoxes in each row are not independent of each other. When I select an item in row A and then click on the comboBox in row B, the ComboBox B are automatically set to the same value as comboBox A.
Code:
DefaultTableModel model = new DefaultTableModel();
//Creating the Headers
ArrayList<Adress> adressList = customer.getAdressList();
//customer.getAdressList() is an ArrayList, which has been populated from SQL
model.addColumn("ID");
model.addColumn("Country");
//Iterate through Adresses of current Customer and fill JTable
for(Iterator<Adress> iterator = adressList.iterator(); iterator.hasNext();){
Adress adress = iterator.next();
Object[] data = new Object[2];
data[0] = adress.getID();
data[1] = adress.getCountry();
model.addRow(data);
}
//Populate combobox with values from an enum
JComboBox country_comboBox = new JComboBox(CountryEnum.values());
// Set Model, Renderer and Editor
table.setModel(model);
table.getColumnModel().getColumn(1).setCellRenderer(new JComboBoxCountryRenderer(country_comboBox));
table.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(country_comboBox));
and the Renderer:
public class JComboBoxCountryRenderer extends JComboBox implements TableCellRenderer{
CountryEnum country;
public JComboBoxCountryRenderer(JComboBox comboBox) {
if (comboBox != null) {
this.setModel(comboBox.getModel());
this.setSelectedIndex(comboBox.getSelectedIndex());
}
}
#Override
public Component getTableCellRendererComponent(JTable arg0, Object value, boolean arg2, boolean arg3, int arg4,
int arg5) {
if (value instanceof CountryEnum) {
this.setSelectedItem((CountryEnum) value);
}
return this;
}
}

You use JCombobox as the renderer, try using as an editor instead...
See this example from Oracle.

Related

A JComboBox in a specific cell in JTable

I would like to know how to set up a JComboBox in a particular cell in a JTable.
I have seen people using TableColumn setCellEditor(new DefaultCellEditor(comboBox)).
But this is for an entire column, I would like a specific cell.
So maybe I should do a custom TableCellEditor that would fit my needs, but I am a little lost on how to do it...
The goal of this is to manage filters on parameters. There are two kinds of filters:
The one that compares two values, for instance: number of balloons > 5
The one that will say is a value is inside a range of value, for instance: parameter name is inside {"one", "two", "three", "seven"}.
screenshot of my JTable:
As we can see in the picture, when there is the "comparator" "is among", we would need a JComboBox in cell[0][2] to choose the values of the range within a complete set of fields.
While cell[1][2] does not need a JComboBox, but just an editable cell.
I hope I have been clear and thank you for your help.
EDIT:
I was able to display a JComboBox only to realize, I couldn't select multiple values on it. So now I am trying to display a JList instead of a ComboBox.
But when I click on the cell, the JList is not displayed, I don't know why.
Here is my code:
JTable tableParametersFilter = new JTable(modelParametersFilter){
// Determine editor to be used by row
public TableCellEditor getCellEditor(int row, int column)
{
int modelColumn = convertColumnIndexToModel( column );
int modelRow = convertRowIndexToModel( row );
Parameter_Filter pf = view.listParameter_Filter.get(modelRow);
if(modelColumn == 2 && pf instanceof Parameter_Filter_To_List_Of_Fields) {
Parameter_Filter_To_List_Of_Fields pftlof = (Parameter_Filter_To_List_Of_Fields)pf;
JList<String> list = new JList<String>(pftlof.list_of_fields_total_names);
list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION );
list.setLayoutOrientation(JList.VERTICAL_WRAP);
list.setVisibleRowCount(-1);
return new TableCellEditor() {
#Override
public boolean stopCellEditing() {
return false;
}
#Override
public boolean shouldSelectCell(EventObject anEvent) {
return false;
}
#Override
public void removeCellEditorListener(CellEditorListener l) {
}
#Override
public boolean isCellEditable(EventObject anEvent) {
return true;
}
#Override
public Object getCellEditorValue() {
return list.getSelectedValuesList().toString();
}
#Override
public void cancelCellEditing() {
}
#Override
public void addCellEditorListener(CellEditorListener l) {
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
return list;
}
};
}
return super.getCellEditor(row, column);
}
};
Any suggestions?
I have solved my problem.
I have not been able to add multiple choice JComboBox, or a displayable JList on the Cell of the Jtable.
Instead, I have used a JOptionPane that displayed a JList.
Here's the code:
tableParametersFilter.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
JTable target = (JTable)e.getSource();
int row = target.getSelectedRow();
int column = target.getSelectedColumn();
if(column == 2){
Parameter_Filter pf = view.listParameter_Filter.get(row);
if(pf instanceof Parameter_Filter_To_List_Of_Fields) {
Parameter_Filter_To_List_Of_Fields pftlof = (Parameter_Filter_To_List_Of_Fields) pf;
JList<String> jlist = new JList<String>(pftlof.list_of_fields_total_names);
String StringOfIntArray = (String) tableParametersFilter.getValueAt( row, 2);
int[] list_parameter_id = Statique.StringOfIntArrayToIntegerArray(StringOfIntArray);
if(list_parameter_id.length < jlist.getModel().getSize()) {
int[] list_places = pftlof.getPlaceOfParameters(list_parameter_id);
for(int i = 0; i < list_places.length; i++) {
jlist.setSelectedIndices(list_places);
}
}
JScrollPane scrollPane = new JScrollPane(jlist);
scrollPane.setPreferredSize( new Dimension( 500, 500 ) );
JOptionPane.showMessageDialog(
null, scrollPane, "Multi-Select Example", JOptionPane.PLAIN_MESSAGE);
int[] SelectedIndices = jlist.getSelectedIndices();
Integer[] listParametersId = new Integer[SelectedIndices.length];
for(int i = 0; i < SelectedIndices.length; i++) {
int id = pftlof.list_of_fields_Total[SelectedIndices[i]].id;
try {
Parameter p = Parameter.getParameter(
id,
Parameter_Filter_To_List_Of_Fields.getTotal_Parameter_In_Parameter_Filter_To_List_Of_Fields());
listParametersId[i] = p.id;
} catch (NoSuchFieldException e1) {
e1.printStackTrace();
}
}
System.out.println(Arrays.toString(listParametersId));
tableParametersFilter.setValueAt(Arrays.toString(listParametersId), row, 2);
}
}
}
}

Need to launch a new JPanel on click event in a JTable cell.

I want to create a JTable having the last column with advanced options icon. On clicking this last column in the JTable, I want a new JPanel to pop up allowing user to enter input for required 4 string input fields. This JPanel when dismissed, should return to the original JTable.
I am not sure where to save the data for 4 fields from the new JPanel. As their would be 4 string input fields per JTable row, just displayed in the JPanel.
Can my JTabel cell hold an object saving the data?
UseCase: I have a JTable with 10 columns. It is getting very cluttered so I want to move 5 columns to a new panel which will be launched on clicking an advanced options icon in the original JTable last column.
Sample code on how to associate the data from the JPanel with the row in JTable will be highly appreciated.
In order to show a pop-up when cell is clicked, you need a cell editor class. The main purpose of this class is to provide custom editors for cells, but you can use it to trigger some action when your cell is clicked:
public class InfoCellEditor extends AbstractCellEditor implements TableCellEditor {
#Override
public java.awt.Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
InfoObject info = (InfoObject) value;
editButton = new JButton(new InfoAction(info));
editButton.setText("INFO");
editButton.setEnabled(true);
}
private class InfoAction extends AbstractAction {
InfoObject info;
public InfoAction(InfoObject info) {
super();
this.info = info;
}
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, info.toString());
stopCellEditing();
}
}
}
Then, extend JTable class and implement getColumnClass and isCellEditable methods:
public class MyTable extends JTable {
public MyTable() {
super();
setDefaultEditor(InfoObject.class, new InfoCellEditor());
}
#Override
public Class getColumnClass(int columnIndex) {
if(columnIndex == 4)
return InfoObject.class;
else
return String.class;
}
#Override
public boolean isCellEditable(int row, int column) {
if(column == 4)
return true;
else
return false;
}
}
Lastly, you should make sure that InfoObject instances are inserted to 5th column. And you can also implement a TableCellRenderer for some custom visual representation of that column.
Object headers = new Object[COLUMN_COUNT];
Object cells[][] = new Object[ROW_COUNT][];
...
cells[0][4] = new InfoObject(data[0]);
cells[1][4] = new InfoObject(data[1]);
table.setModel(new DefaultTableModel(cells, headers));
table.getModel().fireTableDataChanged();
table.setVisible();

Java JComboBox icon

Displaying data in a JTable. One column serves as a field Checkbox. The problem is that instead of the icon appears in the display ChceckBox true / false. How do I fix this?
Add data:
private DefaultTableModel headermodel = new DefaultTableModel();
private JScrollPane scrollHeader = new JScrollPane();
private JTable headerTable = new JTable();
public void loadHead(){
header = model.getHead();
int ids=0;
int id=1;
for(String head: header) {
headermodel.addRow(new Object[]{id,head});
headerMap.put(ids,head);
id++;
ids++;
count++;
}
header.clear();
}
and display data in JTable:
headerTable = new JTable(headermodel);
headermodel.addColumn("Lp.");
headermodel.addColumn("Column Name");
headermodel.addColumn("Constraint");
headermodel.addColumn("Sum");
scrollHeader = new JScrollPane(headerTable);
TableColumnModel tcm = headerTable.getColumnModel();
tcm.getColumn(2).setCellEditor(new DefaultCellEditor(new JCheckBox()));
tcm.getColumn(3).setCellEditor(new DefaultCellEditor(new JCheckBox()));
tcm.getColumn(3).setCellRenderer(headerTable.getDefaultRenderer(boolean.class));
add(scrollHeader);
The model's getColumnClass(int columnIndex) method should return Boolean.class for the appropriate column index so that the renderer knows to render a check box for that column. For example,...
DefaultTableModel headermodel = new DefaultTableModel(){
#Override
public Class<?> getColumnClass(int columnNumber) {
if (columnNumber == 2 || columnNumber == 3) {
return Boolean.class;
} else {
return super.getColumnClass(columnNumber);
}
}
}
You shouldn't have to set the cell renderer for these columns for this since the default cell renderer will handle Boolean.class appropriately.

Java - delete selected row from tablemodel

I need delete deleted row from my arraylist...
private GuiIO guiIO;
private DefaultTableModel tableModel;
private List<Book> zoz;
public MyGui() {
initComponents();
this.setLocationRelativeTo(this.getRootPane());
this.guiIO = new GuiIO();
tableModel = new DefaultTableModel(new String[]{"Znacka", "Model", "Najazdene", "Rok vyroby", "Vykon", "Cena"}, 0);
this.tblTabulka.setModel(tableModel);
this.tblTabulka.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
tblTabulka.setAutoCreateRowSorter(true);
TableRowSorter rowSorter = new TableRowSorter(tableModel);
zoz = guiIO.getAllBook();
}
my function for delete row from model:
private void btnClearActionPerformed(java.awt.event.ActionEvent evt) {
final int sectedRowIndex = this.tblTabulka.getSelectedRow();
this.tableModel.removeRow(sectedRowIndex);
zoz = guiIO.getAllBook();
}
public List getAllBook() {
List all_book = new ArrayList<Book>();
for (Containerable item = this.book.getFirst();
item!=null;
item = this.book.getNext())
all_book.add(item);
return all_book;
}
but i need delete it from my private List zoz;
how can i do it?
I need delete it from my private List zoz?
zoz.remove(sectedRowIndex); // if table is not sortable
Note:
Do not initialize the list again after deleting the selected row.
DefaultTableModel is not populating from the list
put a check tblTabulka.getSelectedRow() != -1 before deleting the row whether row is selected or not?
Use Map instead of List something like
Map<String,Book> books = new HashMap<String,Book>();
where you can make isbn or id as key.
Sample code:
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// check for selected row first
if (tblTabulka.getSelectedRow() != -1) {
// get value of first cell of selected row
String isbn= (String)tableModel.getValueAt(tblTabulka.getSelectedRow(), 0);
books.remove(isbn);
// remove from the model also
model.removeRow(tblTabulka.getSelectedRow());
}
}
});

How to sort rows based on a column added dynamically in jtable?

There already exist a jtable, and I need to add a column dynamically, then set table cell renderer for that column, the cell renderer is jlabel with icon. I already finished that.
My question is : Right now I need to sort that column based on different icons used in table cell renderer, so how to do that? Thank you.
There are the related code:
JTable tableļ¼›// the table is already existed, I cannot change it
TableColumn column = new TableColumn();
column.setHeaderValue("Icon");
column.setCellRenderer(new IconCellRenderer());
table.addColumn(column);
public class IconCellRenderer extends DefaultTableCellRenderer
{
private static final long serialVersionUID = 1L;
public IconCellRenderer()
{
super();
}
#Override
public Component getTableCellRendererComponent(JTable pTable, Object pValue,
boolean pIsSelected, boolean pHasFocus, int pRow, int pColumn)
{
JLabel label = new JLabel();
if (checkCondition(..))
{
label.setIcon(iconOne);
}
else
{
label.setIcon(iconTwo));
}
label.setHorizontalAlignment(SwingConstants.CENTER);
return label;
}
}
For that purposes you can use TableRowSorter, and set Comparator to needed column. In that comparator you can compare values of cells and sorting them:
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
sorter.setComparator(0, new Comparator<Object>() {
#Override
public int compare(Object o1, Object o2) {
return 0;
}
});
table.setRowSorter(sorter);
table is your JTable , model is model of your table.
read more about sorting in JTable.

Categories