JTable is not displayed in Jframe - java

I can't manage to display the JTable in a JFrame. Actually I have extracted the data from an ArrayList and filled the JTable row by row. I have checked that the JTable is filled, the number of rows is equal to the rows in the original ArrayList. Yet running the function shows a blank GUI. I really do not see the problem in my code:
public Graphicalinterface4() {
//super (new GridLayout(1,0));
//panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
getdata2 in=new getdata2();
try {
ArrayList<Piece> test=in.getList();
ArrayList<Piece> classified=in.classify(test);
JTable table=getlocaltable(classified);
table.setFillsViewportHeight(true);
JScrollPane scrPane=new JScrollPane(table);
//scrPane.setSize(800,690);
//scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
this.add(scrPane);
//scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
catch (IOException ex) {
ex.printStackTrace();
}
}
public JTable getlocaltable(ArrayList<Piece> in) {
//new Object[]{"Type","Company","reference","description","price","To order"}));
//DefaultListModel<Piece> testlst=new DefaultListModel<Piece>();
int sz=in.size();
String[] columns=new String[] {
"Type","Company","reference","description","price","To order"
};
DefaultTableModel model = new DefaultTableModel();
//JTable table=new JTable(null, in.toArray());
for (int i=0;i<sz;i++) {
Piece p=in.get(i);
String type=p.gettype();
String company=p.getasc();
String reference=p.getref();
String description=p.getdesc();
String price=p.getprice();
String image=p.getimage();
System.out.println(type);
//DefaultTableModel model=(DefaultTableModel) table.getModel();
model.addRow(new Object[]{type,company,reference,description,price,Integer.toString(0)});
}
JTable table=new JTable(model);
System.out.println(table.getRowCount());
return table;
}
static Graphicalinterface4 ssp;
public static void main(String[] args) throws IOException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {ssp=new Graphicalinterface4();}
});
}

DefaultTableModel model = new DefaultTableModel();
You have 0 columns in the TableModel. The columns displayed is determined by the columns in the TableModel, not the number of items in each row. So adding rows of data has no effect.
Read the DefaultTableModel API for the proper constructor to use that will accept the "columns" variable as a parameter.

Thanks! I had not initialized the DefaultTableModel correctly. In the API the String[] and Object[][]{} are inverted(DefaultTableModel(String, Object[][]{}), but this works for me.
public JTable getlocaltable(ArrayList<Piece> in) {
//new Object[]{"Type","Company","reference","description","price","To order"}));
int sz=in.size();
String[] columns=new String[] {
"Type","Company","reference","description","price","To order"
};
DefaultTableModel model = new DefaultTableModel(new Object[][]{}, columns);
//JTable table=new JTable(model);
for (int i=0;i<sz;i++) {
Piece p=in.get(i);
String type=p.gettype();
String company=p.getasc();
String reference=p.getref();
String description=p.getdesc();
String price=p.getprice();
String image=p.getimage();
System.out.println(type);
//DefaultTableModel model=(DefaultTableModel) table.getModel();
model.addRow(new Object[]{type,company,reference,description,price,Integer.toString(0)});
}
JTable table=new JTable(model);
System.out.println(table.getRowCount());
return table;
}

Related

JTable not refreshing after insert using DefaultTableModel

Java program with GUI controlling derby database using DefaultTableModel:
I've a method which successfully inserts a new record to my database. When I restart the program, the new record is visible in JTable (GUI). However, I can't get the JTable to refresh and display the added record promptly.
I've read through a lot of answered questions here but nothing has worked for me so far. Any idea?
GUI class:
public class GUIClients {
ClientDatabase cDB = new ClientDatabase();
DefaultTableModel tableModel = new DefaultTableModel();
JTable table = new JTable(tableModel);
JScrollPane scrollPane = new JScrollPane(table);
JPanel panel = new JPanel(new BorderLayout());
public JPanel createPanel() {
cDB.createTable(tableModel);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
panel.add(scrollPane);
panel.add(table, BorderLayout.CENTER);
panel.add(table.getTableHeader(), BorderLayout.NORTH);
...
return panel;
}
Insert dialogue with save button:
public class InsertDialog extends GUIClients {
...
saveB = new JButton("Save");
saveB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
cl = cDB.getClient(InsertDialog.this);
cDB.insert(cl);
tableModel.setRowCount(0);
cDB.createTable(tableModel);
table.setModel(tableModel);
dialogPanel.dispose();
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
}
});
dialogPanel.add(saveB);
...
Method for creating DefaultTableModel from database data:
public class ClientDatabase implements Database {
public static ResultSet rs;
public void createTable(DefaultTableModel d) {
try {
d.addColumn("ID");
d.addColumn("Name");
d.addColumn("Surname");
d.addColumn("Mobile");
d.addColumn("Email");
d.addColumn("Notes");
rs.beforeFirst();
while (rs.next()) {
int id = rs.getInt("ID");
String name = rs.getString("NAME");
String surname = rs.getString("SURNAME");
String mobile = rs.getString("MOBILE");
String email = rs.getString("EMAIL");
String notes = rs.getString("NOTES");
d.addRow(new Object[]{id, name, surname, mobile, email, notes});
}
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
...
I've a method which successfully inserts a new record to my database.
Then you are also responsible for adding the data to the TableModel at the same time.
You can either use the addRow(...) or insertRow(..) method of the DefaultTableModel to update the date in your TableModel and the JTable will then be updated.
Or the other approach is to redo the query and then use the JTable.setModel(...) method to replace the old TableModel with the new TableModel.
There is no automatic synching of database and TableModel.

synchronize view of two JTable

I have two JTables one in main viewport and one in footer viewport, using JideScrollPane.
the problem is when the main JTable's view is customized, the footer JTable remains the
same, is there any way to synchronize their view?
thanks.
EDIT:
Here's a demo that will synch up the resizing of two tables that have similar columns. The idea is:
Create a custom TableColumnModelListener for each table's column model.
Upon resize, sync up the column widths. You'll have to disable the other listener temporarily, while this is happening.
For moving of columns, implement that logic in columnMoved(...) [left as an exercise]
This shows two-way synching:
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class JTableResizeColumnsDemo implements Runnable
{
JTable table1, table2;
TableColumnModelListener columnListener1, columnListener2;
Map<JTable, TableColumnModelListener> map;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new JTableResizeColumnsDemo());
}
public void run()
{
Vector<String> names = new Vector<String>();
names.add("One");
names.add("Two");
names.add("Three");
table1 = new JTable(null, names);
table2 = new JTable(null, names);
columnListener1 = new ColumnChangeListener(table1, table2);
columnListener2 = new ColumnChangeListener(table2, table1);
table1.getColumnModel().addColumnModelListener(columnListener1);
table2.getColumnModel().addColumnModelListener(columnListener2);
map = new HashMap<JTable, TableColumnModelListener>();
map.put(table1, columnListener1);
map.put(table2, columnListener2);
JPanel p = new JPanel(new GridLayout(2,1));
p.add(new JScrollPane(table1));
p.add(new JScrollPane(table2));
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(p);
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
class ColumnChangeListener implements TableColumnModelListener
{
JTable sourceTable;
JTable targetTable;
public ColumnChangeListener(JTable source, JTable target)
{
this.sourceTable = source;
this.targetTable = target;
}
public void columnAdded(TableColumnModelEvent e) {}
public void columnSelectionChanged(ListSelectionEvent e) {}
public void columnRemoved(TableColumnModelEvent e) {}
public void columnMoved(TableColumnModelEvent e) {}
public void columnMarginChanged(ChangeEvent e)
{
TableColumnModel sourceModel = sourceTable.getColumnModel();
TableColumnModel targetModel = targetTable.getColumnModel();
TableColumnModelListener listener = map.get(targetTable);
targetModel.removeColumnModelListener(listener);
for (int i = 0; i < sourceModel.getColumnCount(); i++)
{
targetModel.getColumn(i).setPreferredWidth(sourceModel.getColumn(i).getWidth());
}
targetModel.addColumnModelListener(listener);
}
}
}
You can apply an Observer pattern: the first JTable observes the second and vice versa. Then you add listners to both tables so that, when one is "customized", the other is notified. Basically, "being notified" consists in a method invocation that causes the update of the JTable.
In order to do that, you have two options:
You define a class Observer with a "register" method and a
"notify" method. When creating a JTable, you register it with the
Observer. Then, the listener you create and associate to each JTable
invoke the "notify" method of the observer, which informs all other
registered JTables of the change
You define a sort of "callback method" notify in the class that contains and declares the JTable. This "notify" method is invoked within the listner and updates the correct JTable. You can also create two methods: one for updating one JTable and one for the other JTable
Usually this is done by using the same model for different ui components. Sadly the JTable contains a bug that will cause problems when sharing the TableColumnModel.
But you can work around it using this JTable
class ShareableColumnModelTable extends JTable {
/**
* Fixes http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4816146 and
* more...
*
*/
#Override
public void columnMarginChanged(ChangeEvent e) {
if (isEditing()) {
removeEditor();
}
TableColumn resizingColumn = null;
if (tableHeader != null) {
resizingColumn = tableHeader.getResizingColumn();
}
if (resizingColumn != null) {
if (autoResizeMode == AUTO_RESIZE_OFF) {
resizingColumn.setPreferredWidth(resizingColumn.getWidth());
} else { // this else block is missing in jdk1.4 as compared to
// 1.3
TableColumnModel columnModel = getColumnModel();
/**
* Temporarily disconnects this column listener to prevent
* stackoverflows if the column model is shared between
* multiple JTables.
*/
columnModel.removeColumnModelListener(this);
try {
doLayout();
} finally {
columnModel.addColumnModelListener(this);
}
repaint();
return;
}
}
resizeAndRepaint();
}
}
With the ShareableColumnModelTableshowed above you can share one column model bettween multiple tables.
public static void main(String[] args) {
JFrame frame = new JFrame("Column Sync");
Container contentPane = frame.getContentPane();
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
splitPane.setResizeWeight(0.5d);
contentPane.add(splitPane);
JTable table1 = new ShareableColumnModelTable();
JTable table2 = new ShareableColumnModelTable();
TableColumnModel tableColumnModel = createTableColumnModel();
table1.setModel(createTableModel1());
table2.setModel(createTableModel2());
table1.setColumnModel(tableColumnModel);
table2.setColumnModel(tableColumnModel);
splitPane.setLeftComponent(new JScrollPane(table1));
splitPane.setRightComponent(new JScrollPane(table2));
showFrame(frame);
}
private static TableColumnModel createTableColumnModel() {
TableColumnModel tableColumnModel = new DefaultTableColumnModel();
TableColumn column1 = new TableColumn(0);
column1.setHeaderValue("1. column");
tableColumnModel.addColumn(column1);
TableColumn column2 = new TableColumn(1);
column2.setHeaderValue("2. column");
tableColumnModel.addColumn(column2);
return tableColumnModel;
}
private static TableModel createTableModel1() {
DefaultTableModel tableModel = new DefaultTableModel();
tableModel.setColumnCount(2);
tableModel.addRow(new Object[] { "a", "b" });
return tableModel;
}
private static TableModel createTableModel2() {
DefaultTableModel tableModel = new DefaultTableModel();
tableModel.setColumnCount(2);
tableModel.addRow(new Object[] { "c", "d" });
return tableModel;
}
private static void showFrame(JFrame frame) {
frame.setSize(240, 400);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}

java - JTable setValueAt not working

I'm doing a chess game and I need to make a log table that prints every move. The LogTable class is like this:
public class LogTable {
private DefaultTableModel model;
private JTable table;
public LogTable(JPanel panel){
String[] columnNames = {"Move No.",
"White",
"Black"};
model = new DefaultTableModel(columnNames, 0);
table = new JTable();
//model.isCellEditable(i, i1)
table.setModel(model);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
panel.add(scrollPane);
}
public void newMove(chessPiece piece){
if (piece.getColor() == 0){
Object[] newRow = new Object[3];
newRow[0] = model.getRowCount()+1;
newRow[1] = piece.sayPos();
newRow[2] = " ";
model.addRow(newRow);
}
else {
model.setValueAt(piece.sayPos(), model.getRowCount(), model.getColumnCount());
}
}
}
But in the first black move it thows an ArrayOutOfBoundsException. The newMove function is called at the chessPiece class:
public void move(int newX, int newY, JPanelSquare jPanelSquareGrid[][], LogTable logTable){
resetShowValidMoves(jPanelSquareGrid);
logTable.newMove(this);
}
The rest of the move code is in each piece, which call super. I'm using the DefaultTableModel.
From Java API :
public DefaultTableModel(Object[] columnNames,int rowCount)
Constructs a DefaultTableModel with as many columns as there are elements in
columnNames and rowCount of null object values. Each column's name
will be taken from the columnNames array.
You instantiate the DefaultTableModel with 0 rows. So you can't set the value of an item in row 0 since it doesn't exist.

Getting a row of names from the first column of JTable

I have a JTable with the column names " Names " , " Quantity " and " Unit " .
I'm coding a program where you get the ingredients names.
So i need to get the whole row of one column and String it all up together,
because i need to store it in mySql and i have already set it all as String.
Any idea how i can do this ?
My code are as follows :
JTable Code:
DefaultTableModel model = (DefaultTableModel)table.getModel();
if(!txtQty.getText().trim().equals("")){
model.addRow(new Object[]{ingCB.getSelectedItem().toString(),txtQty.getText(),unitCB.getSelectedItem().toString()});
}else{
JOptionPane.showMessageDialog(null,"*Quantity field left blank");
}
Getting the values and for storing :
for(int i = 1; i<= i ; i++){
ingredients = table.getName();
}
This is for loop is wrong and it does not work because i have a constructor to take in Ingredients but because it is inside the loop, it cannot take it in.
Any suggestions please ? Thank you.
Constructor :
Food e2 = new Food(Name, Description, priceDbl, Image, Category, Ingredients, promotion );
e2.createFood();
I'm coding a program where you get the ingredients names. So i need to get the whole row of one column and String it all up together, because i need to store it in mySql and i have already set it all as String.
Want to do so, try this. Here I am getting result into ArrayList and String, as I am commented ArrayList you can avoid it.
public class TableValuePrint extends JFrame implements ActionListener{
private final JButton print;
private final JTable table;
private String str="";
public TableValuePrint() {
setSize(600, 300);
String[] columnNames = {"A", "B", "C"};
Object[][] data = {
{"Moni", "adsad", "Pass"},
{"Jhon", "ewrewr", "Fail"},
{"Max", "zxczxc", "Pass"}
};
table = new JTable(data, columnNames);
JScrollPane tableSP = new JScrollPane(table);
JPanel tablePanel = new JPanel();
tablePanel.add(tableSP);
tablePanel.setBackground(Color.red);
add(tablePanel);
setTitle("Result");
setSize(1000,700);
print=new JButton("Print");
JPanel jpi1 = new JPanel();
jpi1.add(print);
tablePanel.add(jpi1,BorderLayout.SOUTH);
print.addActionListener(this);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
TableValuePrint ex = new TableValuePrint();
ex.setVisible(true);
}
});
}
#Override
public void actionPerformed(ActionEvent ae) {
if(ae.getSource()==print){
// ArrayList list = new ArrayList();
for(int i = 0;i<table.getModel().getRowCount();i++)
{
//list.add(table.getModel().getValueAt(i, 0)); //get the all row values at column index 1
str=str+table.getModel().getValueAt(i,0).toString();
}
//System.out.println("List="+list);
System.out.println("String="+str);
}
}
}
Output
String=MoniJhonMax

Setting the height of a row in a JTable in java

I have been searching for a solution to be able to increase the height of a row in a JTable. I have been using the setRowHeight(int int) method which compiles and runs OK, but no row[s] have been increased. When I use the getRowHeight(int) method of the row I set the height to, it does print out the size I increased the row to, so I'm not sure what is wrong. The code below is a rough illustration how I am trying to solve it.
My class extends JFrame.
String[] columnNames = {"Column 1", "Column 2", "Column 1 3"};
JTable table = new JTable(new DefaultTableModel(columnNames, people.size()));
DefaultTableModel model = (DefaultTableModel) table.getModel();
int count =1;
for(Person p: people)
{
model.insertRow(count,(new Object[]{count, p.getName(), p.getAge()+"",
p.getNationality}));
count++;
}
table.setRowHeight(1, 15);//Try set height to 15 (I've tried higher)
Can anyone tell me where I am going wrong? I am trying to increase the height of row 1 to 15 pixels?
You can use:
table.setRowHeight(int par1);
or if you wanted to set the row height for a specific row, use:
table.setRowHeight(int par1, int par2);
Not sure what is the intention of leaving the first row at index 0 empty. Rows in JTable run from index 0. It is best if you could post a complete example (ie SSCCE) that demonstrates the issues. Compare to this simple example that works OK:
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class DemoTable {
private static void createAndShowGUI() {
JFrame frame = new JFrame("DemoTable");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultTableModel model = new DefaultTableModel();
model.setColumnIdentifiers(new Object[] {
"Column 1", "Column 2", "Column 3" });
JTable table = new JTable(model);
for (int count = 0; count < 3; count++){
model.insertRow(count, new Object[] { count, "name", "age"});
}
table.setRowHeight(1, 30);
frame.add(new JScrollPane(table));
frame.setLocationByPlatform(true);
frame.pack();
frame.setVisible(true);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Right click on the JTable in JFrame and click Properties.
Scroll down and set the rowHeight value.
You can also add a tableModelListener?
model.addTableModelListener(new TableModelListener() {
#Override public void tableChanged(final TableModelEvent e) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
table.setRowHeight(e.getFirstRow(), 15); //replace 15 with your own height
}
});
}
});

Categories