I have a problem in the display of two different JTables which are created by the same AbstractTableModel. I don't really think that is important to show the code of the AbstractTableModel, but if I am asked for I may present it as well.
I just call two times the same class that extends this AbstractTableModel for two arraylists that I am using to create the tables.
final SwitchTableModel model = new SwitchTableModel(user_decide);
final SwitchTableModel model1 = new SwitchTableModel(duplicates);
JTable table = new JTable(model);
JTable table1 = new JTable(model1);
JFrame frame = new JFrame ("Results");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel grid = new JPanel();
grid.add(toolbar);
grid.add(toolbar1);
grid.add(table);
grid.add(table1);
frame.add(grid);
frame.pack();
frame.setVisible(true);
I also create the toolbars which are the same, I also think that this is irrelevant, that is why I don't post the code - I would do it if you think it is needed.
The problem is that in the end I see the same JTable two times, so I suppose it has something to do with the way that I call the class.
The problem comes from an inappropriate static keyword.:
public static int [][] data;
static means that the value of that variable will be the same for all your instances. Instead, put your data inside your SwitchTableModel and don't make it static. This will solve your issues immediately.
Something like:
public class SwitchTableModel extends AbstractTableModel {
private int[][] data;
//... the rest of your current code.
}
I think both the value passed to the SwitchTableModel user_decide and duplicates are having same values. Otherwise there is no issue in the above code.
Try adding two seperate scroll panes to your panel, then add the JTables to the scroll panes. Other then that, your not clear on what exactly your display problem is, wheather the JTables are not showing up, or if the data is not different... ect
Related
This is driving me crazy. I read the Sun's tutorial regarding the creation of a basic table with a default data model, but cant figure out a simple example about how to load an array of data-objects like:
class dataObject{
String name;
String gender;
Byte age;
public dataObject (String name, String gender, Byte age){
this.name = name;
.
.
}
Then i create, for example, a vector of this stuff:
Vector v = new Vector(99);
v.addElement(new dataObject("Marrie", "Female", 33);
v.addElement(new dataObject("John", "Male", 32);
With dataObject i'd gather the info, now how the heck i show it in a table? Because this is not working:
JTable newTable = new Jtable(v, header) // header is another Vector.
I'm getting some errors that lead me to this last line. So, any help, even little, is apreciated. I know there are several threads about this, but those people already have a gasp about how JTable + TableModel works, I just barely get it.
Thanks a lot.
There are two ways you can create a JTable with a basic, prepared dataset:
a 2D Object array
a Vector whose elements are Vector
so you can do this:
Object [][] model = {{"Marrie", "Female","33"},{"John","Male","32"}};
JTable table = new JTable(model);
or you could do this:
Vector model = new Vector();
Vector row = new Vector();
row.add("Marrie");
row.add("Female");
row.add("33");
model.add(row);
row = new Vector();
row.add("John");
row.add("Male");
row.add("32");
model.add(row);
JTable table = new JTable(model);
The next step would be to implement your own TableModel to utilize the DataObject class that you have put together (note that Java classes start with caps). Extending AbstractTableModel makes life easy, as you only need to implement three methods to get started:
public int getRowCount();
public int getColumnCount();
public Object getValueAt(int row, int column);
the first two are easy, you can get the size of your Vector for row count and hard-code the val for column count. getValueAt is where you pull the data from your DataObject
Here is an example using an anonymous class, extending AbstractTableModel.
final Vector<DataObject> myDataObjects = new Vector<DataObject>();
myDataObjects.add(...);// add your objects
JTable table = new JTable(new AbstractTableModel() {
public int getRowCount() {return myDataObjects.size();}
public int getColumnCount() { return 3; }
public Object getValueAt(int row, int column){
switch (column) {
case 0:
return myDataObjects.get(row).getName();
case 1:
return myDataObjects.get(row).getGender();
case 2:
return myDataObjects.get(row).getAge();
default:
return "";
}
}
});
I have kept the Vector so as to keep it close to your current implementation. You can easily change that to an ArrayList in this example without any worries.
The problem is, the constructor you're using was designed to hold a vector which holds other vectors.
Each one with the information.
See this working sample to understand it better:
import javax.swing.*;
import java.util.Vector;
public class TableDemo {
public static void main( String [] args ){
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
Vector<Object> row = new Vector<Object>();
row.add( "Marie");
row.add( "Female");
row.add( 33);
data.add(row);
Vector<Object> otherRow = new Vector<Object>();
otherRow.add( "John");
otherRow.add( "Male");
otherRow.add( 32 );
data.add(otherRow);
Vector<String> headers = new Vector<String>();
headers.add("Name");
headers.add("Gender");
headers.add( "Age");
JTable table = new JTable( data, headers );
JFrame frame = new JFrame();
frame.add( new JScrollPane( table ));
frame.pack();
frame.setVisible( true );
}
}
Which creates:
something like this http://img695.imageshack.us/img695/2032/capturadepantalla201006r.png
Just in case, you should take a look at this:
http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
If you haven't done yet.
You can't load data objects into the DefaultTableModel. You need to create a custom TableModel to do this. The Bean Table Model is such a model that can make this process easier for you.
I've never used JTable before, but the documentation says that the constructor takes a "Vector of Vectors" as the first parameter, and not a Vector of dataObjects.
I know a lot of people can be wary of including yet another jar file, but to be honest, no matter how simple the JTable (or JList or JComboBox), I always utilise the GlazedLists library. Quite frankly it's one of the most amazing libs you'll ever use. It's very, very flexible. But a simple example consists of putting your beans into a special list called EventList. Then construct a table format; create the model by binding the format to the data list, and then set as the table's model.
Assume you have a Person class:
public class Person {
private String firstName;
private String surname;
private int age;
... standard constructors, getters and setters...
}
Now, to make your table display a list of these people:
EventList<Person> peopleEventList = new BasicEventList<Person>();
peopleEventList.add(... create some objects and add it the usual way ...);
...
String[] columnProperties = { "firstName", "surname", "age" };
String[] columnLabels = { "First name", "Surname", "Age" };
TableFormat personTableFormat = GlazedLists.tableFormat(columnProperties, columnLabels);
EventTableModel personTableModel = new EventTableModel(peopleEventList, personTableFormat);
myJTable.setModel(personTableModel);
I'm writing this from memory, but I think it's more or less correct. The great thing with using this library is it's seriously easy to add sorting and filtering to the table. Get the basic table working first, then start looking on the GlazedLists site to see what else you can do. There are some really good screencasts too.
PS I'm in no way affiliated with this library, I simply think it rocks!
Before I already asked question and could get value from dynamically added jTextFields and jComboBoxes using this answer for my question.
Now in my subPanel I have 3 jComboBoxes and 4 jTextFields.
To get value of jComponent I am using this code:
Component[] children = jPanel1.getComponents();
// iterate over all subPanels...
for (Component sp : children) {
if (sp instanceof subPanel) {
Component[] spChildren = ((subPanel)sp).getComponents();
// now iterate over all JTextFields...
for (Component spChild : spChildren) {
if (spChild instanceof JTextField) {
String text = ((JTextField)spChild).getText();
System.out.println(text);
}
}
}
}
I would like to ask is it possible to access to each jComboBoxes and jTextFields separately, i.e. can I manipulate each jComponent and set them different values? How can I achieve this?
Thank you in advance.
I would like to ask is it possible to access to each jComboBoxes and jTextFields separately, i.e. can I manipulate each jComponent and set them different values? How can I achieve this?
Rather than traversing the Component hierarchy (which is fragile to Layout changes), you can keep references to your Components. The following example is a class that contains instance variables for the Child components:
public class ComponentWrapper extends JComponent{
private JComboBox combo;
private JTextArea textArea;
public ComponentWrapper(){
combo = new JComboBox();
textArea = new JTextArea();
add(combo);
add(textArea);
}
public Text getTextArea(){
return textArea;
}
public JComboBox getComboBox(){
return comboBox;
}
}
The above class extends JComponent, adds the components within the constructor, and can be added to another Container elsewhere. Note the above class is just an example for how to do this, and may need to be further adapted depending upon your requirements. Usage:
ComponentWrapper wrapper = new ComponentWrapper ();
add(wrapper);
revalidate();//if adding 'dynamically'
//later, when you want to get the text
String text = wrapper.getTextArea().getText();
Since both of those classes (JComboBox and JTextField) extend JComponent you can make an ArrayList and add them to it. i.e.
ArrayList<JComponent> components = new ArrayList<JComponent>();
JComboBox pie = new JComboBox();
components.add(pie)
//pie is now stored in components as a JComponent
When you need to reference pie you can call:
JComboBox pie = (JComboBox) components.get(0);
This can be done with any JComponent and to reference it you just simply cast it on it's way out. This method, however, can lead to some confusion. So you should either remember the order you add them, or add them in a very specific way (i.e TextFields first, then ComboBoxes).
I saw some post quite similar but did not hit spot on.
I was thinking something like this:
Object[][] test = {
{"Name", new JTextField()},
{"Gender", new JComboBox()}
}
I tried something like this but i cannot use the method of the JTextField or the JComboBox. How do I instantiate this depending on there 1-index? Is this possible?
If you know for sure what it is, you can cast it when you get it out, like this
JComboBox box = (JComboBox)(test[1][1]);
box.whatever();
However, instead of using an Object[][], why not just make a class?
class UIWidgets {
JTextField name;
JComboBox gender;
}
You need to cast first before you can access methods specific to the type, since Java sees them all as instances of Object:
((JTextField)test[0][1]).CallMethodHere();
Or alternately:
JTextField tf = (JTextField)test[0][1];
// do something with tf
Try this:
((JTextField) test[0][1]).setText("someText");
This is driving me crazy. I read the Sun's tutorial regarding the creation of a basic table with a default data model, but cant figure out a simple example about how to load an array of data-objects like:
class dataObject{
String name;
String gender;
Byte age;
public dataObject (String name, String gender, Byte age){
this.name = name;
.
.
}
Then i create, for example, a vector of this stuff:
Vector v = new Vector(99);
v.addElement(new dataObject("Marrie", "Female", 33);
v.addElement(new dataObject("John", "Male", 32);
With dataObject i'd gather the info, now how the heck i show it in a table? Because this is not working:
JTable newTable = new Jtable(v, header) // header is another Vector.
I'm getting some errors that lead me to this last line. So, any help, even little, is apreciated. I know there are several threads about this, but those people already have a gasp about how JTable + TableModel works, I just barely get it.
Thanks a lot.
There are two ways you can create a JTable with a basic, prepared dataset:
a 2D Object array
a Vector whose elements are Vector
so you can do this:
Object [][] model = {{"Marrie", "Female","33"},{"John","Male","32"}};
JTable table = new JTable(model);
or you could do this:
Vector model = new Vector();
Vector row = new Vector();
row.add("Marrie");
row.add("Female");
row.add("33");
model.add(row);
row = new Vector();
row.add("John");
row.add("Male");
row.add("32");
model.add(row);
JTable table = new JTable(model);
The next step would be to implement your own TableModel to utilize the DataObject class that you have put together (note that Java classes start with caps). Extending AbstractTableModel makes life easy, as you only need to implement three methods to get started:
public int getRowCount();
public int getColumnCount();
public Object getValueAt(int row, int column);
the first two are easy, you can get the size of your Vector for row count and hard-code the val for column count. getValueAt is where you pull the data from your DataObject
Here is an example using an anonymous class, extending AbstractTableModel.
final Vector<DataObject> myDataObjects = new Vector<DataObject>();
myDataObjects.add(...);// add your objects
JTable table = new JTable(new AbstractTableModel() {
public int getRowCount() {return myDataObjects.size();}
public int getColumnCount() { return 3; }
public Object getValueAt(int row, int column){
switch (column) {
case 0:
return myDataObjects.get(row).getName();
case 1:
return myDataObjects.get(row).getGender();
case 2:
return myDataObjects.get(row).getAge();
default:
return "";
}
}
});
I have kept the Vector so as to keep it close to your current implementation. You can easily change that to an ArrayList in this example without any worries.
The problem is, the constructor you're using was designed to hold a vector which holds other vectors.
Each one with the information.
See this working sample to understand it better:
import javax.swing.*;
import java.util.Vector;
public class TableDemo {
public static void main( String [] args ){
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
Vector<Object> row = new Vector<Object>();
row.add( "Marie");
row.add( "Female");
row.add( 33);
data.add(row);
Vector<Object> otherRow = new Vector<Object>();
otherRow.add( "John");
otherRow.add( "Male");
otherRow.add( 32 );
data.add(otherRow);
Vector<String> headers = new Vector<String>();
headers.add("Name");
headers.add("Gender");
headers.add( "Age");
JTable table = new JTable( data, headers );
JFrame frame = new JFrame();
frame.add( new JScrollPane( table ));
frame.pack();
frame.setVisible( true );
}
}
Which creates:
something like this http://img695.imageshack.us/img695/2032/capturadepantalla201006r.png
Just in case, you should take a look at this:
http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
If you haven't done yet.
You can't load data objects into the DefaultTableModel. You need to create a custom TableModel to do this. The Bean Table Model is such a model that can make this process easier for you.
I've never used JTable before, but the documentation says that the constructor takes a "Vector of Vectors" as the first parameter, and not a Vector of dataObjects.
I know a lot of people can be wary of including yet another jar file, but to be honest, no matter how simple the JTable (or JList or JComboBox), I always utilise the GlazedLists library. Quite frankly it's one of the most amazing libs you'll ever use. It's very, very flexible. But a simple example consists of putting your beans into a special list called EventList. Then construct a table format; create the model by binding the format to the data list, and then set as the table's model.
Assume you have a Person class:
public class Person {
private String firstName;
private String surname;
private int age;
... standard constructors, getters and setters...
}
Now, to make your table display a list of these people:
EventList<Person> peopleEventList = new BasicEventList<Person>();
peopleEventList.add(... create some objects and add it the usual way ...);
...
String[] columnProperties = { "firstName", "surname", "age" };
String[] columnLabels = { "First name", "Surname", "Age" };
TableFormat personTableFormat = GlazedLists.tableFormat(columnProperties, columnLabels);
EventTableModel personTableModel = new EventTableModel(peopleEventList, personTableFormat);
myJTable.setModel(personTableModel);
I'm writing this from memory, but I think it's more or less correct. The great thing with using this library is it's seriously easy to add sorting and filtering to the table. Get the basic table working first, then start looking on the GlazedLists site to see what else you can do. There are some really good screencasts too.
PS I'm in no way affiliated with this library, I simply think it rocks!
I have a JTextArea in (multiple) JScrollPane in a JTabbedPane.
I need to access the JTextArea. If I didn't have the JScrollPane, I could do:
JTextArea c = (JTextArea)jTabbedPane1.getComponentAt(i);
How would I get it when in a JScrollPane?
Cheers,
Gazler.
Sounds like you'll get into a mess of references over there ( at least that's what have happened to me in the past ) .
I would suggest you to have a middle object in charge of those dependencies for you and to move the "business" methods there.
So instead of adding components and losing the references ( or worst, duplicating the references all over the place ) you can use this object which will have the reference:
class AppMediator {
private JTextArea area;
private JTabbetPane pane;
// etc.
public void doSomethingWithText() {
this.area.getText(); // etc
}
}
See the Mediator design pattern. The focus is to move all the "view" objects from where they are ( usually as references in subclasses ) to a common intermediate object.
This line looks complex, but I THINK this would do it.
JTextArea c = (JTextArea) (((JViewportView) (((JScrollPane) jTabbedPane1.getComponentAt(i)).getViewport()))).getView();
But I think it would be more interesting to store your TextArea's in an ArrayList.
So you can do this:
List<JTextArea> listAreas = new ArrayList<JTextArea>();
...
JTextArea c = listAreas.get(i);
Create a new one is something like this:
JTextArea c = new JTextArea();
jTabbedPane1.addTab("Title", new JScrollPane(c));
listAreas.add(c);
Hope this helps.
I prefer the AppMediator approach but you could also do
scrollPane.getViewport().getView()