I get [Ljava.lang.Object;# instead of data on my JTable - java

am trying to fill a JTable form from an existing Object[][][] Array the problem that i all the data or containing the [Ljava.lang.Object;# instead of my (integer) data even though i mad a System.out.println("") to print the data before putting them into the JTable but i always get the same problem ; here is the code next with a small shot screen and thanx for the help.
import java.awt.Component;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
public class gass extends JFrame {
String title[] ={"Box", "Weight", "Priority"};
public gass() {
int nb=interface1.BNumber;
Object[][][] data = new Object[nb][nb][nb];
int E1=0, E2=0;
for (int i=0;i<nb;i++)
{ data[i][0][0] = i+1;
E1 = (int) (Math.random() * 100);
data[0][i][0] = E1;
E2 = (int) (Math.random() * 10);
data[0][0][i] = E2;
}
for (int j=0;j<nb;j++)
{
System.out.println("*"+data[j][0][0]+"*"+data[0][j][0]+"*"+data[0][0][j]+"*");
}
JTable table = new JTable(data, title);
Component add = this.getContentPane().add(new JScrollPane(table));
this.setVisible(true);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
this.setSize(800,400);
}
}
Another problem that i get wrong data always in the first cases of the Object Array ***data[0][0][0] = wrong information !!***
next, a Link for a description of the output of my small application and thanks a lot for the help
Click in this link here to get Description Image

The JTable constructor takes an Object[][] as argument.
This array is an array of rows. So data[i] is a row, which is an array of columns.
And each row in the array is itself an array of columns. Each column (data[i][j]) should contain some data displayed in one cell of the JTable.
In your case, this data is itself an array. Since there is no specific renderer associated to object arrays, the toString() method of your array is used to display the array in the cell. And an array's toString() method returns something like [Ljava.lang.Object;#.
You should tell us what you would like to display in each cell, to get a better answer, explaining what you should do.
EDIT:
given what you want to display, you just need a two-dimensional array:
Object[][] data = new Object[nb][3]; // nb rows, 3 columns
for (int row = 0; row < nb; row++) {
data[row][0] = row + 1; // first column: row number
data[row][1] = Math.random(100); // second column: weight
data[row][2] = Math.random(10): // third column: priority
}

Related

Having only specific column selectable JTable and/or getting the data from only one column

I have a Swing program with a JTable, and there are two columns: one for names, and one for phone numbers associated with those names. Currently, the program allows for selection of rows, which causes data in both columns to become selected. I want selected data to be output to an array of strings, but only the data from within a certain column (that with phone numbers), no matter how many rows are selected. How would I go about this?
I was thinking of changing setColumnSelectionAllowed(false) to setColumnSelectionAllowed(true) and allowing a JHeader to be clicked to select an entire row, or somehow allowing for getValueAt(int row, int column) to be put into an array and only allow for reading of the phone numbers column.
Code for initializing table:
// Initializing the JTable
String[] columns = {"Student", "Phone"};
students = new JTable(data, columns);
students.setGridColor(Color.lightGray);
students.setPreferredScrollableViewportSize(new Dimension(500, 400));
TableColumnModel columnModel = students.getColumnModel();
columnModel.getColumn(0).setPreferredWidth(100);
columnModel.getColumn(1).setPreferredWidth(100);
students.setRowHeight(25);
students.setFillsViewportHeight(true);
students.setRowSelectionAllowed(true);
students.setColumnSelectionAllowed(false);
students.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
Table is made from CSV file as an array:
String[][] myNewArray1 = new String[30][30]; //creates an array
Scanner myScanner1 = new Scanner(filePath1); //creates a scanner which uses the text file
int k = 0;
while (myScanner1.hasNext()) {
myNewArray1[k] = myScanner1.nextLine().split(",");
k++;
}
return (myNewArray1);
}
// Driver method
public static void main(String[] args) throws Exception {
File filePath1 = new File("C:\\Users\\cmorl\\IdeaProjects\\CompSciIA\\src\\CompSciIA.csv"); //file path
String[][] data1;
data1 = makeArrayFromTxt(filePath1);
new Database(data1);
}
TableModel model = table.getModel();
List <String> data = new ArrayList();
for (int count = 0; count < model.getRowCount(); count++){
data.add(model.getValueAt(count, 0).toString()); //Change 0 with 1 if you want column 2
}

How to create 2d arrayobject for a custom class

I have custom class called ButtonList, like a list of buttons, i am adding all the buttons that are going into the window to that 2d array object of button list.
ButtonList[][] buttonList;
buttonList = new ButtonList[5][3];
and I'm constantly getting Null pointer error when im am trying to add the
JButtons to the buttonList.
this.buttonList[column][row].addButton(buttonImage);
ButtonList and addButton method looks like so:
static class ButtonList{
int column = 0;
int row = 0;
JButton[][] arrayButton = new JButton[this.column][this.row];
void addButton(JButton BUTTON){
arrayButton[this.column][this.row] = BUTTON;
System.out.println("Row: " + this.row + " Column: " + this.column);
this.column += 1;
this.row += 1;
System.out.println("button inserted at " + this.row);
}//end addButton
what is it that i am doin wrong?
thanks
int column = 0;
int row = 0;
JButton[][] arrayButton = new JButton[this.column][this.row];
You initialize your array before your constructor get called. So at this point your column and row are still 0. You initialize then an array of [0][0]. This is why later on you get a null pointer exception even though you may have changed the values of row and column in your constructor or later on in any method. But at the time of the creation they were 0.
Moreover
arrayButton[this.column][this.row] = BUTTON;
This is quite probable to give you a out of bounds exception because arrays in java are 0 indexed so your valid range is from [0,column-1][0,row-1] so you may want to fix this as well.
JButton[][] arrayButton = new JButton[this.column][this.row];
this line create an 2d array (without initialization), and infact is equivalent to this:
JButton[][] arrayButton = new JButton[0][0];
0 happens to be the value of the column and row at that time. Changing the value of these two variables does not take any effect on the array it self.
Solution:
If you know in advance the max value of column and row, use that value for array creation. If not, use ArrayList, you will be able to change your size later.

Java - Coloring Row in JTable depending on value in the tablemodel

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

How to use hidden column data of jTable in tooltip

I am trying to display the data of hidden column as tooltip. Hiding is working perfectly using the following code:
JTable table = new JTable(model){
//Implement table cell tool tips.
public String getToolTipText(MouseEvent e) {
String tip = null;
java.awt.Point p = e.getPoint();
int rowIndex = rowAtPoint(p);
int colIndex = columnAtPoint(p);
int realColumnIndex = convertColumnIndexToModel(colIndex);
try {
tip = getValueAt(rowIndex, 8).toString();
} catch (RuntimeException e1) {
//catch null pointer exception if mouse is over an empty line
}
return tip;
}
};
TableColumnModel tcm = table.getColumnModel();
TableColumn tc;
for(int i = 1; i <= 7; i++){
tc = tcm.getColumn(8);
tcm.removeColumn(tc);
}
But the tooltip is not showing the data of hidden column (getValue function is not returning value). So do hiding the column delete the data as well ?
You do not need to for loop as you do not use the i variable ;-)
The removeColumn on the JTable does not remove the data from the model, as clearly stated in the javadoc
Removes aColumn from this JTable's array of columns. Note: this method does not remove the column of data from the model; it just removes the TableColumn that was responsible for displaying it.
There is no mention in the javadoc for the same method on the TableColumnModel, but I would assume it works the same way, but you can always give it a try to call it on the JTable instead
The real problem in your code is the use of getValueAt, which uses the row and column index of the table, and not of the model
Note: The column is specified in the table view's display order, and not in the TableModel's column order. This is an important distinction because as the user rearranges the columns in the table, the column at a given index in the view will change. Meanwhile the user's actions never affect the model's column ordering.
And since you removed that column, it simply does not exists for the table. Call the getValue method on the model instead, and do not forget to convert the row index

How can I create a JTable where the first column is always in the JScrollPane viewport?

What's the best way to set up a table in a JScrollPane such that the first column is always on the screen in the same position regardless of horizontal scrolling and overlaps columns that pass underneath?
When the scrollbar is at the farthest left, the columns look normal, but as the user scrolls to the right, the secondary columns (2 and on) move underneath the first until the last column appears on the far right of the viewport?
I found a sample taken from Eckstein's "Java Swing" book that sort of does this, but it doesn't allow resizing of the first column. I was thinking of some scheme where one JPanel held a horizontal struct and a table holding the secondary columns and another JPanel which floated over them (fixed regardless of scrolling). The struct would be to keep the viewport range constant as the first column floated around. Ideally I could do it with two tables using the same model, but I'm not sure if the whole idea is a naive solution.
I'd ideally like a setup where multiple tables are on the same scrollpane vertically, where all their first columns are aligned and move together and there are just little horizontal gaps between the individual tables.
Fixed Column Table does most of what you need.
It does not support resizing the fixed column so you would need to add code like:
MouseAdapter ma = new MouseAdapter()
{
TableColumn column;
int columnWidth;
int pressedX;
public void mousePressed(MouseEvent e)
{
JTableHeader header = (JTableHeader)e.getComponent();
TableColumnModel tcm = header.getColumnModel();
int columnIndex = tcm.getColumnIndexAtX( e.getX() );
Cursor cursor = header.getCursor();
if (columnIndex == tcm.getColumnCount() - 1
&& cursor == Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR))
{
column = tcm.getColumn( columnIndex );
columnWidth = column.getWidth();
pressedX = e.getX();
header.addMouseMotionListener( this );
}
}
public void mouseReleased(MouseEvent e)
{
JTableHeader header = (JTableHeader)e.getComponent();
header.removeMouseMotionListener( this );
}
public void mouseDragged(MouseEvent e)
{
int width = columnWidth - pressedX + e.getX();
column.setPreferredWidth( width );
JTableHeader header = (JTableHeader)e.getComponent();
JTable table = header.getTable();
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = (JScrollPane)table.getParent().getParent();
scrollPane.revalidate();
}
};
JTable fixed = fixedColumnTable.getFixedTable();
fixed.getTableHeader().addMouseListener( ma );
JScrollPane has an area specifically for this, the row header (see the diagram in the API:)
All you need to do is:
- create an extra JTable for this fixed area
- hook it up to the first column of your data model
- set it as the row header
- and in the main table omit or remove the first column of data.
When the scrollpane scrolls up and down both tables will scroll in sync with no added code. When the scrollpane scrolls horizontally the row header is always kept visible and only the main table scrolls.
For most cases the only added code you'll need is for the column resizing, like camickr's example.
Check out this class, extracted from http://fahdshariff.blogspot.sg/2010/02/freezing-columns-in-jtable.html
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;
public class FrozenTablePane extends JScrollPane{
public FrozenTablePane(JTable table, int colsToFreeze){
super(table);
TableModel model = table.getModel();
//create a frozen model
TableModel frozenModel = new DefaultTableModel(
model.getRowCount(),
colsToFreeze);
//populate the frozen model
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < colsToFreeze; j++) {
String value = (String) model.getValueAt(i, j);
frozenModel.setValueAt(value, i, j);
}
}
//create frozen table
JTable frozenTable = new JTable(frozenModel);
//remove the frozen columns from the original table
for (int j = 0; j < colsToFreeze; j++) {
table.removeColumn(table.getColumnModel().getColumn(0));
} table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
//format the frozen table
JTableHeader header = table.getTableHeader();
frozenTable.setBackground(header.getBackground());
frozenTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
frozenTable.setEnabled(false);
//set frozen table as row header view
JViewport viewport = new JViewport();
viewport.setView(frozenTable);
viewport.setPreferredSize(frozenTable.getPreferredSize());
setRowHeaderView(viewport);
setCorner(JScrollPane.UPPER_LEFT_CORNER,
frozenTable.getTableHeader());
}
}
Thereafter, just call the constructor method:
JTable table = new JTable( <yourData>, <yourColumns> );
FrozenTablePane frozenPane = new FrozenTablePane(table,1);//where 1 is the number of freezed column(s)
I think you are on the right track. What you conceptually have is a table with a 'header column' for each row. I would use two tables - one has the 'leftmost' column in and the other has all the others. Then I would present these in a JSplitPane with the 'leftmost column' table on the left and the rest on the right. There would be a single vertical scrollbar that controlled the y offset of both tables, and a single horizontal scrollbar controlling the right hand pane (only).
You can also use the advanced features of JScrollPane to set a 'header' component on the left of the main scroll area. I've never done it, but you might be able to use that as the 'headers' of your rows.

Categories

Resources