I have a vector of String type entries formed as:
Vector<String> nameLst = new Vector<String>();
nameLst.add("Jacob");
nameLst.add("Stacey");
[...etc]
I to not know the number of entries - hence the vector instead of array. I would like to be able to display those names in a tale (with possibility of editing). My problem is, that JTable uses only Vector but my implementation only uses a list (rather then a table)
I was trying to go through all the entries of nameLst and allocate then in a new vector:
Vector<Vector<String>> helper = new Vector<Vector<String>>
for (String nametmp : nameLst){
Vector<String> a = new Vector<String>();
a.add(nametmp);
helper.add((Vector<String>)a.clone())
}
However the table (while formated correct) remains empty. I would expect that the data should stay safe and not go out of scope since I'm cloning it into the helper vector.
Is there a way to get a Vector to populate a JTable?
EDIT: Example - I don't really have a minimum working example, but the relevant code is:
The Display (in the Gui class):
JPanel namPan;
JTable namTab
In the constructor:
namePan = new JPanel();
printNames() //method
public void printNames(){
Vector<String> label= new Vector<String>();
Vector<Vector<String>> helper = new Vector<Vector<String>>;
for(String nametmp :nameLst){
Vector<String> a = new Vector<String>();
a.add(nametmp);
helper.add((Vector<String>/*just a cast*/) a.clone());
}
label.add("Currently active:");
namTab = new JTable(helper, label);
namPan.add(new JScrollPane(namTab));
}
Afterwards I call the Gui Constructor, fill in the name list with some initial names and call the printNames() method.
I think the core problem is the mismatch of formats - The Vector looks like ['a' 'b' 'c'] wile it should be a column vector: [a] [b] [c]. or in other words be seen as 2d vector with one column and multiple rows.
EDIT2
Found it - Special thanks to Hovercraft Full Of Eels who pushed me to make a minimal working example. I could not find any critical differences between what He uploaded and what I made, however when I've made the minimum example - stripped all other gui elements and functionalities I saw the data!
What happened? I put some dimension restrictions on the window size and panel ratios (GridBagLayout) and the test strings were outside! When entire area was available to the table I could see the text. I decided to write that and look like a fool rather then shove it under the carpet and leave this post hanging.
Related
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);
i am trying to add an image that is in my database in a column in JTable
with a number and a code special to this image the problem is i got the number and the code but the image doesn't show i don't know why here is my code
String sql="SELECT id,chiffre,image FROM symbolique WHERE id BETWEEN 200 and 205";
try{
st=connexion.prepareStatement(sql);
res=st.executeQuery();
while(res.next()){
int j=0;
String [] code= new String[1000];
String [] chiffre1=new String[100];
code [j] = res.getString("id");
chiffre1[j] = Integer.toString(res.getInt("chiffre"));
Blob blob = res.getBlob("image");
is2 = new BufferedInputStream(blob.getBinaryStream());
Image raw = ImageIO.read(is2);
ImageIcon icon =new ImageIcon(raw);
Object [][] data = new Object[200][100];
data[j][1]= code [j];
data[j][2]= chiffre1[j];
data[j][3]=icon;
j++;
String title[] = {"image", "chiffre","code"};
DefaultTableModel model = new DefaultTableModel(data, title);
table.setModel(model);
}
}catch(Exception e){
JOptionPane.showMessageDialog(null, e);}
}
put Icon/ImageIcon to JTable better to the TableModel directly
you have to override getColumnClass for Icon/ImageIcon in XxxTableModel for showing this Object as image in the JTables view
for detailed informations (incl. working code examples) to read official Oracle tutorial - How to use Tables
This won't help solve the image problem but right now your code recreates the TableModel for every row in the ResultSet, which means you will only ever see one row of data.
Since you have looping code you need to create an empty DefaultTableModel before the loop starts.
Inside the loop you then use the addRow(...) method to add another row of data to the TableModel for every row in the ResultSet
When you finish the loop then you use the model to create the JTable.
Did you add any debug code? Did you attempt to display the width/height of the image to confirm that you are reading the image properly? Why don't you do a simple test that tries to read and display an image in a JLabel first since using a JTable is more complicated than using a JLabel. Then once you get that working you can apply the knowledge to using a JTable.
I'm trying to color the text of every row in a table depending on one of the columns in the table. I'm having trouble grasping the concept of renderers, and I've tried out several different renderers but don't seem to understand what they do.
I am trying to load the top ten racers from a certain API given to us by our lecturer into the table model, but colouring each row based on the gender of the racer (which is returned by the getCategory() method of a Finisher/Racer object).
FYI, DataTable is an object written by our lecturer. It's basically a 2D array object.
public void showRacers(DefaultTableModel tblModel,
#SuppressWarnings("rawtypes") JList listOfRaces) {
// Clear the model of any previous searches
tblModel.setRowCount(0);
// Initialize an object to the selected city
CityNameAndKey city = (CityNameAndKey) listOfRaces.getSelectedValue();
// Get the runners for this city
DataTable runners = this.getRunners(city);
// Set the column headers
this.setColumnHeaders(tblModel);
// Make an array list of object Finisher
ArrayList<Finisher> finisherList = new ArrayList<Finisher>();
// Make an array that holds the data of each finisher
Object[] finisherData = new Object[6];
// Make a finisher object
Finisher f;
for (int r = 0; r < 10; r++) {
// Assign the data to the finisher object
finisherList.add(f = new Finisher(runners.getCell(r, 0), runners
.getCell(r, 1), runners.getCell(r, 2), runners
.getCell(r, 3), runners.getCell(r, 4), runners
.getCell(r, 5)));
// Add the data into the array
finisherData[0] = f.getPosition();
finisherData[1] = f.getBibNo();
finisherData[2] = f.getTime();
finisherData[3] = f.getGender();
finisherData[4] = f.getCategory();
finisherData[5] = f.getRuns();
// Put it into the table model
tblModel.addRow(finisherData);
}
}
I would greatly appreciate an explanation, rather than just the answer to my question. Guidance to the answer would be great, and some code would be extremely helpful, but please no: "You should have written this: ten lines of code I don't get
Thank you very much! :)
Using a TableCellRenderer will only allow you to color one column. You would have to have one for each column. A much easier approach is to override prepareRenderer(...) in JTable to color an entire row.
See trashgod's answer here or camickr's answer here
I am working on a project and I am stuck on this area. I am reading text from a file and I am saving it into an arraylist. the problem is the content from the file appears in one line of text in the jtable but i want each line to be displayed in rows. I am passing the data from another class and I know this is working because I can see the contents printed out in the console row after row . I have tried a few different ways but I've run out of ideas. Any help appreciated.
Below is the code I have wrote.
for (String item : helper.getItems() )
{
System.out.println(item);
storage.add(item);
}
JTable t1 = new JTable();
t1.setModel(new DefaultTableModel(
new Object[][]{
{storage.toString()}
},
new String[]{
"Tool Equipment"
}
));
storage.toString() will give you string representation of your ArrayList. What you want is probably List#toArray
The best way to add items to a JTable using the DefaultTableModel object is to utilize the .addRow method of the DefaulTableModel. You'll need to parse the storage string to deliminate the values you want placed into each row/col
For Example:
DefaultTableModel model=new DefaultTableModel();
// parsing of the storage obj, to get individual values for each col/row
// depending on the structure of storage a looping construct would be beneficial here
String col1= storage.substring(startindex, endindex);
String col2=storage.substring(startindex, endindex);
//add items to the model in a new row
model.addRow(new Object[] {col1, col2});
// if you used a loop to parse the data in storage, end it here
// add model to the table
t1.setModel(model);
I have an ArrayList called conditionList which stores condition names.
Whenever one is added/edited or deleted, the Lists on my GUI update no problems.
You can see below that i use 2 models... a DefaultListModel called condListModel and a DefaultComboBoxModel called conditionModel.
The code i have below is for the method editCondition(), at this stage the text is already changed on the GUI and is being submitted here. On my GUI, after ive submitted the change, the ComboBox and JList change no problem so im sure that the model changes are correct.
HOWEVER MY PROBLEM IS: When i save the ArrayList conditionList through serialization, and then load it back up, the change is gone. SO I think there is problem in my code with changing the String Value in the ArrayList(named conditionList), can anyone have a look and see if u notice an issue
String conString = jListCondition.getSelectedValue().toString();
for(String c: conditionList)
{
if(conString.compareTo(c) == 0)
{
String temp = entConName.getText();
c = temp;
//edit the Condition jList model
int x = condListModel.indexOf(conString);
condListModel.setElementAt(temp, x);
jListCondition.setModel(condListModel);
//edit the Condition comboBox model
int i = conditionModel.getIndexOf(conString);
conditionModel.insertElementAt(temp, i);
conditionModel.removeElement(conString);
entCondition.setModel(conditionModel);
//reset buttons
editConConfirm.setEnabled(false);
editCon.setEnabled(false);
deleteCon.setEnabled(false);
entConName.setText("");
addCon.setEnabled(true);
}
}