I want to upgrade the list items of myComboBox when I click a row in myJtabel. I did what I must do to have a good result. But when a unpgrade myComboBox I have a true as a last item and every time I have done an upgrade adds a true as item
What it does not go in my class
myUpgradeCombo :
class myUpgradeCombo {
public static <E> void upgrade_(JComboBox<E> combo, int index)
{
E item = combo.getItemAt(index);
combo.removeItemAt(index);
combo.insertItemAt(item, 0);
combo.setSelectedIndex(0);
}
public static <E> boolean upgrade(JComboBox<E> combo, E item)
{
for (int index=0; index<combo.getItemCount(); index++)
{
if (combo.getItemAt(index).toString().equals(item.toString()))
{
upgrade_(combo,index);
return true;
}
}
return false ;
}
}
when myJtable Mouse pressed :
int rec = myJtableF.getSelectedRow();
String idf = myJtableF.getValueAt(rec, 1).toString();
String format = myJtableF.getValueAt(rec, 2).toString();
String platef = myJtableF.getValueAt(rec, 3).toString();
this.myCombo.addItem(myUpgradeCombo.upgrade(myCombo, new FC(format,platef,idf)));
As result in myCombo :
...... MySelectedItem
.......Firstitem
.......SecondItem
.......ThirdItem
.......fourthItem
.......true
.......true
Thanks,
Well because the return value of your myUpgradeCombo.upgrade(myCombo, new FC(format,platef,idf)) is passed to this.myCombo.addItem().
So the true returned from upgrade() is added as an item to your combo box, in this line:
this.myCombo.addItem(myUpgradeCombo.upgrade(myCombo, new FC(format,platef,idf)));
Related
I use:
Java 10 SE
Java Swing
Eclipse IDE
I have JTable, the contents gets loaded at runtime dynamically. It has some JComboBoxes. If I select the JComboBox, and then attempt to reload the table, the JComboBox appears visible at the time when the table loading is in progress.
Besides that, if the JComboBox's contents gets updated (elsewhere in different table, when the combo supposed to reflect that new contents), that new contents does not get visible staright away after loading the JTable dynamically.
The snap-shot sample of the app:
That's, the table being loaded at runtime up, and in the middle you have vsisble JComboBox persistent from the previous selection.
How to:
Get rid off that persistent JComboBox
Make the data visible instantly, upon update under the combo, once you load the table dynamically
I have the public final class TableColumnEditor extends DefaultCellEditor{
which returns the JComboBox on a specific column:
else if(row == ROW_2_DEVS_WORK_WEEKEND) {
ProjectMetrics metrics = new ProjectMetrics();
JComboBox<String> combo = new JComboBox<>();
combo.setBackground(Color.WHITE);
for(String devs : metrics.identifyDevsThatWorkAtWeekend()) {
combo.addItem(devs);
}
return combo;
}
I have the public final class TableColumnRenderer extends DefaultTableCellRenderer{
which makes sure that the view displays the JComboBox under that specific column:
else if(row == ROW_2_DEVS_WORK_WEEKEND) {
ProjectMetrics metrics = new ProjectMetrics();
JComboBox<String> combo = new JComboBox<>();
combo.setBackground(Color.WHITE);
for(String devs : metrics.identifyDevsThatWorkAtWeekend()) {
combo.addItem(devs);
break;
}
return combo;
}
The table gets loaded dynamically right here (non-essential things removed):
public static void reloadTableDynamically(JTable metricsTable){
DefaultTableModel model = (DefaultTableModel)metricsTable.getModel();
if(projectData.isEmpty()) {
metricsTable.clearSelection();
int rowCount = model.getRowCount();
for(int item = (rowCount - 1); item >= 0; item--) {
model.removeRow(item);//clears previous rows
}
metricsTable.repaint();
return;
}
model.getDataVector().clear();
int rowCount = constantRows + ((devsTask.size() == 0) ? 1 : devsTask.size());
try {
new Thread(()-> {
int lastRowID = 0;
int devsTaskID = 0;
for(int item = 0; item < rowCount; item++) {
Object[] input = null;
if(item == 0) {
input = new Object[] {"", metrics.getProjectDateRange(), "" };
}//similar branches removed
else {
devsTaskID++;
input = new Object[] {"", devsTask.get(devsTaskID).getDeveloper(), ""};
}
model.addRow(input);
metricsTable.scrollRectToVisible(new java.awt.Rectangle(metricsTable.getCellRect(lastRowID++, 0, true)));
metricsTable.repaint();
try {
Thread.sleep(Config.getInstance().getReloadInOutTable());
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
metricsTable.scrollRectToVisible(new java.awt.Rectangle(metricsTable.getCellRect(projectData.size() - 1, 0, true)));
metricsTable.repaint();//so that to reach the last row
}).start();
}
catch(Exception e) {
}
}
What do you think?
Well, I figured out how to overcome this problem.
Firstly, the JComboBox gets updated on EDT(Event Despatch Thread).
/**
* #param combo The JComboBox ref.
* #param toDisplay The value to add to it
*/
public static void updateComboBoxOnEventDespatchThread(JComboBox<String> combo, String toDisplay) {
Runnable doComboUpdate = new Runnable() {
public void run() {
combo.addItem(toDisplay);
}
};
SwingUtilities.invokeLater(doComboUpdate);
}
Under the JTable column editor:
else if(row == ROW_2_DEVS_WORK_WEEKEND) {
ProjectMetrics metrics = new ProjectMetrics();
JComboBox<String> combo = new JComboBox<>();
combo.setBackground(Color.WHITE);
Runnable doComboInsert = new Runnable() {
public void run() {
int id = 0;
for(String devs : metrics.identifyDevsThatWorkAtWeekend()) {
UIutils.updateComboBoxOnEventDespatchThread(combo, "("+ ++id +") " + devs);
}
}
};
SwingUtilities.invokeLater(doComboInsert);
return combo;
}
But the main fix, without which both issues do not go away, is following.
That is, I noticed that in order for data to appear under the table instantly, firstly, you need to select any other unrelated table's cell.
That is, the Java thread, which loads the JTable at runtime, does need to have this:
if(model.getRowCount() > 0) {
metricsTable.selectAll();
}
That's probably a hack, but it works for me!
I have combobox which is filled with some items. Each item have display member and value member:
Vector model = new Vector();
model.addElement(new FilterValue("10000 Hz", 0));
model.addElement(new FilterValue("5000 Hz", 1));
model.addElement(new FilterValue("1000 Hz", 5));
model.addElement(new FilterValue("100 Hz", 50));
model.addElement(new FilterValue("10 Hz", 500));
model.addElement(new FilterValue("1 Hz", 5000));
public class FilterValue {
private final String label;
private final int value;
public FilterValue(String label, int value) {
this.label = label;
this.value = value;
}
public String getLabel() {
return label;
}
public int getValue() {
return value;
}
public String toString()
{
return label;
}
}
Initialization of JComboBox
cbFilter1 = new JComboBox(model);
cbFilter1.setBounds(176, 70, 90, 20);
cbFilter1.setSelectedIndex(-1);
pnlOUT1.add(cbFilter1);
cbFilter1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComboBox comboBox = (JComboBox)e.getSource();
FilterValue item = (FilterValue)comboBox.getSelectedItem();
System.out.println( item.getValue() + " : " + item.getLabel() );
}
});
When I select for example 5000 Hz, display text is 5000 Hz, and value is 1.
The question is how to set value for example 5 and display 1000 Hz?
I have tried with
cbFilter1.setSelectedItem(5);
But there is no effect.
So you basically want to select the items either by their value or by their label.
The first (and simplest) thing I could think of to achieve this, is to create a Map object with the FilterValue as value. With this mapping you can simply use setSelectedItem on the ComboBox.
First copy the elements from your Vector:
Map<Integer, FilterValue> valueMap = new HashMap<>();
Map<String, FilterValue> labelMap = new HashMap<>();
model.forEach(filter -> {
valueMap.put(filter.getValue(), filter);
labelMap.put(filter.getLabel(), filter);
});
Then you could do something like this
String label = "5000 Hz";
cbFilter1.setSelectedItem(labelMap.get(label));
or this
int value = 5;
cbFilter1.setSelectedItem(valueMap.get(value));
It is then your choice how to collect the value (or label) of the FilterValue (maybe a JTextField or whatever)
Change your selected item:
cbFilter1 = new JComboBox(model);
cbFilter1.setBounds(176, 70, 90, 20);
cbFilter1.setSelectedIndex(5); // EDITED
pnlOUT1.add(cbFilter1);
cbFilter1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComboBox comboBox = (JComboBox)e.getSource();
FilterValue item = (FilterValue)comboBox.getSelectedItem();
System.out.println( item.getValue() + " : " + item.getLabel() );
}
});
So you want the select a row by passing an existing value or label ?
The method setSeletedIndex(int index) expects an int corresponding of the number of the row (here, from 0 to 5).
You could use the method setSelectedItem(Object obj) to select the wanted FilterValue object.
Here is a simple method to help you select the correct FilterValue object from a given value :
/* Could do the same for label, using val.getLabel()
* and passing a String in parameter
*/
public void selectByValue(int value){
FilterValue row = null;
for(FilterValue val : model){ //Searching for the corresponding FilterValue
if(val.getValue() == value){
row = val;
}
}
cbFilter1.setSelectedItem(row); //Select the corresponding row
}
When calling this method like this
this.selectByValue(5);
It will search for the FilterValue in your Vector that have the value "5" and select the row of this object. This expects you don't have any values twice or it would select the first that appears.
Tested, and worked ;)
Hope it helped !
Thanks to all, I've found one solution that works fine in my case:
public static void setSelectedValue(JComboBox comboBox, int value)
{
FilterValue item;
for (int i = 0; i < comboBox.getItemCount(); i++)
{
item = (FilterValue)comboBox.getItemAt(i);
if (item.getValue() == value)
{
comboBox.setSelectedIndex(i);
break;
}
}
}
I got an ArrayList:
ArrayList<CheckBox> swmsInfo = new ArrayList<CheckBox>();
and some checkboxes:
checkBoxCompany = createCheckBox(R.id.checkBoxCompany);
checkBoxName = createCheckBox(R.id.checkBoxName);
checkBoxPhone = createCheckBox(R.id.checkBoxPhone);
checkBoxAdress = createCheckBox(R.id.checkBoxAdress);
I want to get their values 0 or 1 if some of the checkboxes are checked or not , and when i got their values i want to put them into a array. My checkboxes are inside a array
ArrayList<CheckBox> boxes = new ArrayList<CheckBox>();
You can loop through the arraylist and get the value. Something like
for (int i = 0; i<boxes.size(); i++){
CheckBox cb = boxes.get(i);
if (cb.isChecked()){
System.out.println("checked");
//from here you can populate you array
}else{
System.out.println("not checked");
//from here you can populate you array
}
}
======= Edit after the comment =======
public class CheckBoxStatus{
CheckBox cb;
boolean blnIsChecked;
public CheckBoxStatus(CheckBox cb, boolean blnIsChecked){
this.cb = cb;
this.blnIsChecked = blnIsChecked;
}
public CheckBox getCheckbox(){
return this.cb;
}
public boolean getStatus(){
return this.blnIsChecked;
}
public boolean setStatus(boolean blnIsChecked){
this.blnIsChecked = blnIsChecked;
}
}
//Now in your code instead of ArrayList<CheckBox>, use ArrayList<CheckBoxStatus>
ArrayList<CheckBoxStatus> alCBS = new ArrayList<CheckBoxStatus>();
CheckBoxStatus cbs = new CheckBoxStatus(<checkbox instance>, false); //pass false as default value;
alCBS.add(cbs);
//Modified loop
for (int i = 0; i<boxes.size(); i++){
CheckBox cb = boxes.get(i);
CheckBoxStatus cbs = new CheckBoxStatus(cb, cb.isChecked());
boxes.set(i, cbs);
}
For example i have a JComboBox with values :
{"weapon","armor","weapon"}
If currently selected index is 0 (weapon) and I select index 2 (weapon), it does not trigger an ItemStateChanged in my ItemListener. Although if currently selected index is 0 and I select index 1, it triggers an ItemStateChanged.
Here is my code as of now:
class CBListener implements ItemListener{
#Override
public void itemStateChanged(ItemEvent e){
JComboBox temp = (JComboBox) e.getSource();
int wordIndex = temp.getSelectedIndex(); // index of selected string in the list
int row = sTable.getSelectedRow(); // row of the cell
int col = sTable.getSelectedColumn(); // column of the cell
sTable.setValueAt(listE.get(row)[wordIndex], row, 0);
//System.out.println(listE.get(row)[wordIndex]);
sTable.setValueAt(listI.get(row)[wordIndex], row, 1);
sTable.setValueAt(listD.get(row)[wordIndex], row, 3);
}
}
How can I modify my code so that I can get an index similar to index 2 in my example?
I would still recommend some differentiation between the two items, but if you really want them to be the same, I think you'll have to create an object that has a toString value of "weapon", but for which an equals returns false. Something like:
public BuyableItem( String description, int index ) {
:
:
}
public String toString() {
return this.description;
}
public boolean equals( BuyableItem item ) {
boolean retVal = this.description.equals( item.description );
if( retVal ) {
retVal = this.index == item.index;
}
return retVal;
}
Then your JComboBox values could be
{ new BuyableItem( "weapon", 0 ), new BuyableItem( "armor", 1 ), new BuyableItem( "weapon", 2 ) };
Is there an easy way to check if an item already exists in a JComboBox besides iterating through the latter? Here's what I want to do:
Item item = ...;
boolean exists = false;
for (int index = 0; index < myComboBox.getItemCount() && !exists; index++) {
if (item.equals(myComboBox.getItemAt(index)) {
exists = true;
}
}
if (!exists) {
myComboBox.addItem(item);
}
Thanks!
Use a DefaultComboBoxModel and call getIndexOf(item) to check if an item already exists. This method will return -1 if the item does not exist. Here is some sample code:
DefaultComboBoxModel model = new DefaultComboBoxModel(new String[] {"foo", "bar"});
JComboBox box = new JComboBox(model);
String toAdd = "baz";
//does it exist?
if(model.getIndexOf(toAdd) == -1 ) {
model.addElement(toAdd);
}
(Note that under-the-hood, indexOf does loop over the list of items to find the item you are looking for.)
Check with this:
if(((DefaultComboBoxModel)box.getModel()).getIndexOf(toAdd) == -1) {
box.addItem(toAdd );
}
or
if(((DefaultComboBoxModel)box.getModel()).getIndexOf(toAdd) < 0) {
box.addItem(toAdd );
}
Update:
myComboBox.setSelectedIndex(-1);
String strItem="exists";
myComboBox.setSelectedItem(strItem);
if(myComboBox.getSelectedIndex()>-1){
//exists
}