I have problem with DefaultTableModel it won't show me my columns in table, there is a part of code:
JTable table = new JTable() {
public boolean isCellEditable(int data, int columnNames) {
return false;
}
};
String columnNames[] = new String[] { "First Name", "Last Name", "Sport", "# of Years", "Vegetarian", "asd", "asd" };
DefaultTableModel dtm = new DefaultTableModel(0, 0);
dtm.setColumnIdentifiers(columnNames);
table.setModel(dtm);
for (Reservation r : reservation) {
rez.add(new Reservation(r.getID(), r.getA(), r.getB(), r.getC(), r.getD(), r.getE(), r.getF()));
}
for (int i = 0; i < rez.size(); i++) {
int id = rez.get(i).getID();
String l = rez.get(i).getA();
String w = rez.get(i).getB();
String z = rez.get(i).getC();
String o = rez.get(i).getD();
String d = String.valueOf(rez.get(i).getE());
String g = rez.get(i).getF();
dtm.addRow(new Object[] { id, l, w, z, d,o,g });
}
JScrollPane sp = new JScrollPane(dtm);
add(table);
}
Im trying to make a dynamic table. Data will be from data base (posgreSQL) using hibernate, and thats fine, it work's but I cant see a column names from
String columnNames[] = new String[] { "First Name", "Last Name", "Sport", "# of Years", "Vegetarian", "asd", "asd" };
Don't care about names of columns and name of getters i changed it for this post.
In addition I can't make it scrollable:
JScrollPane sp = new JScrollPane(dtm);
I'm not sure how this would be able to compile
JScrollPane sp = new JScrollPane(dtm);
add(table);
dtm is an instance of DefaultTableModel so it should never be possible to pass it to a JScrollPane,
Instead you should be using
JScrollPane sp = new JScrollPane(table);
add(sp);
See How to Use Tables and How to Use Scroll Panes for more details
Add the table rather than the TableModel to the JScrollPane
add(new JScrollPane(table));
Related
I have an ArrayList holding football matches and when the user types a date and presses "search" button, a new JTable opens showing you all matches played on that day. I have looped to get the date and compared it to the input inside the JTextField but it just gives me an empty table even if there is a record of a match played on the date the user enters. In this code below, I am just using hitting enter on JTextField to execute search because I do not know how to map JTextField to JButton. I have tried but it just prints the search Jbutton name.
public void searchMatch(ArrayList<Matches> searchMatch, String e)
{
DefaultTableModel searchModel = new DefaultTableModel();
for(int i = 0; i < searchMatch.size(); i++)
{
if(searchMatch.get(i).getM_date().equals(e))
{
System.out.println(searchMatch.get(i).getM_date());
String date = searchMatch.get(i).getM_date();
String teamName = searchMatch.get(i).getM_teamName();
String teamName2 = searchMatch.get(i).getM_teamName2();
int goalsScoredTeam1 = searchMatch.get(i).getGoalsTeam1();
int goalsScoredTeam2 = searchMatch.get(i).getGoalsTeam2();
Object[] row = {teamName, teamName2, goalsScoredTeam1, goalsScoredTeam2,date};
searchModel.addRow(row);
JTable searchTable = new JTable(searchModel);
searchTable.setFillsViewportHeight(true);
JPanel searchPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane(searchTable);
searchPanel.add(scrollPane);
JFrame frame = new JFrame("Searched Matches");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
searchTable.setOpaque(true);
frame.setContentPane(searchPanel);
frame.pack();
frame.setSize(500, 500);
frame.setVisible(true);
}
}
}
DefaultTableModel searchModel = new DefaultTableModel();
You TableModel has no columns to display.
Even though you add rows of data, none of the data can be displayed unless you also have defined the "column names" for the TableModel.
Your code should be something like:
String columnNames = { "Date", "Name", "..." };
DefaultTableModel searchModel = new DefaultTableModel(columnNames, 0);
Which will create an empty TableModel with just the column names. Your looping code will then add each row of data.
Note, you should also look at storing all the data in your TableModel and then just filter the TableModel. Read the section from the Swing tutorial on Sorting and Filtering for a working example.
I would like to ask how to display all rows in Java using JTable.
I tried using a while condition inside is a result.next() to be evaluated.
I tried printing it using System.out.println and it display all records however when I tried it on JTable it only displays the last row.
while(results.next()) {
String id = results.getString("id");
String date_collected = results.getString("date_collected");
String date_disposed = results.getString("date_disposed");
String person_in_charged = results.getString("person_in_charged");
String status = results.getString("status");
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][]){
{id, date_collected, date_disposed, person_in_charged, status}
},
new String [] {
"ID", "Date collected", "Date disposed", "person in charged",
"status"
}
));
jScrollPane1.setViewportView(jTable1);
if (jTable1.getColumnModel().getColumnCount() > 0) {
jTable1.getColumnModel().getColumn(0).setResizable(false);
jTable1.getColumnModel().getColumn(1).setResizable(false);
jTable1.getColumnModel().getColumn(2).setResizable(false);
jTable1.getColumnModel().getColumn(3).setResizable(false);
}
}
Can you help me? Thanks!
Summary of the solution:
Solved by Usagi Miyamoto and isaace
The solution was to create the List this way
List<Object[]> data = new ArrayList<>()
Reason:
List is an interface, an abstract, and cannot be instantiated directly
ArrayList is a class that implements List
Complete solution of Usagi Miyamoto
// to hold the data
List<Object[]> data = new ArrayList<>();
// loop through the ResultSet
while(results.next())
{
String id = results.getString("id");
String date_collected = results.getString("date_collected");
String date_disposed = results.getString("date_disposed");
String person_in_charged = results.getString("person_in_charged");
String status = results.getString("status");
// add a new row of data
data.add(new Object[] {id, date_collected, date_disposed, person_in_charged, status});
}
// after the loop: set the data as the model
jTable1.setModel(new javax.swing.table.DefaultTableModel(
// convert from List to array
data.toArray(new Object[][data.size()],
// column headers
new String [] { "ID", "Date collected", "Date disposed", "person in charged", "status" }
));
// other details from your code: moved outside of the loop...
jScrollPane1.setViewportView(jTable1);
if (jTable1.getColumnModel().getColumnCount() > 0)
{
jTable1.getColumnModel().getColumn(0).setResizable(false);
jTable1.getColumnModel().getColumn(1).setResizable(false);
jTable1.getColumnModel().getColumn(2).setResizable(false);
jTable1.getColumnModel().getColumn(3).setResizable(false);
}
Try cumulating the data, something like this:
// to hold the data
List<Object[]> data = new ArrayList<>();
// loop through the ResultSet
while(results.next())
{
String id = results.getString("id");
String date_collected = results.getString("date_collected");
String date_disposed = results.getString("date_disposed");
String person_in_charged = results.getString("person_in_charged");
String status = results.getString("status");
// add a new row of data
data.add(new Object[] {id, date_collected, date_disposed, person_in_charged, status});
}
// after the loop: set the data as the model
jTable1.setModel(new javax.swing.table.DefaultTableModel(
// convert from List to array
data.toArray(new Object[][data.size()],
// column headers
new String [] { "ID", "Date collected", "Date disposed", "person in charged", "status" }
));
// other details from your code: moved outside of the loop...
jScrollPane1.setViewportView(jTable1);
if (jTable1.getColumnModel().getColumnCount() > 0)
{
jTable1.getColumnModel().getColumn(0).setResizable(false);
jTable1.getColumnModel().getColumn(1).setResizable(false);
jTable1.getColumnModel().getColumn(2).setResizable(false);
jTable1.getColumnModel().getColumn(3).setResizable(false);
}
The DefaultTableModel should be created and set outside of the loop.
DefaultTableModel model = new DefaultTableModel();
model.addColumn("you column names");
model.addColumn("another column name");
//you can add all your column headers here
JTable table = new JTable();
table.setModel(model);
while(rs.next())
{
String id = results.getString("id");
String date_collected = results.getString("date_collected");
String date_disposed = results.getString("date_disposed");
String person_in_charged = results.getString("person_in_charged");
String status = results.getString("status");
model.addRow(new Object[]{id, date_collected, date_disposed, person_in_charge, status });
}
and continue with the rest of your code here.
The code below displays 2 JTables.
As they both will have exactly the same headers I wanted, for the sake of efficiency, to reuse the header from the first table.
However running the code results in the header appearing in the second table but not in the table it came from originally.
I am less interested in work-arounds, but - for the sake of learning and understanding - more interested in finding out why the header does not appear in the first table.
Here is the code:
public class HeaderTest1 {
public void doTheTest() {
JFrame testFrame = new JFrame("Header Test");
JPanel pane = new JPanel();
Container theContentPane = testFrame.getContentPane();
BoxLayout box = new BoxLayout(pane, BoxLayout.Y_AXIS);
pane.setLayout(box);
theContentPane.add(pane);
String theData[][]
= {
{"One", "two", "3"},
{"four", "5", "six"},
{"7", "8", "9.0"},
{"£10.00", "11", "twelve"}
};
String columnNames[] = {"Column 1", "Column 2", "Column 3"};
JTable firstTable = new JTable(theData, columnNames);
JScrollPane thisScrollPane = new JScrollPane(firstTable);
JTableHeader thisTableHeader = firstTable.getTableHeader();
pane.add(thisScrollPane);
buildTheSecondTable(thisTableHeader, firstTable, columnNames, pane);
testFrame.pack();
testFrame.setVisible(true);
}
private void buildTheSecondTable(JTableHeader headerFromTheFirstTable,
JTable firstTable, String[] columnNames, JPanel pane) {
JTable secondTable = new JTable();
int columnCount = columnNames.length;
JScrollPane thisScrollPane = new JScrollPane(secondTable);
secondTable.setTableHeader(headerFromTheFirstTable);
Object[][] emptyData = new Object[1][columnCount];
for (int n = 0; n < columnCount; n++) {
emptyData[0][n] = "";
}
DefaultTableModel thisTableModel = new DefaultTableModel();
thisTableModel.setDataVector(emptyData, columnNames);
secondTable.setModel(thisTableModel);
secondTable.setLayout(firstTable.getLayout());
secondTable.setCellEditor(firstTable.getCellEditor());
pane.add(thisScrollPane);
}
public static void main(String[] args) throws SQLException, ParseException {
HeaderTest thisTest = new HeaderTest();
thisTest.doTheTest();
}
Any advice would be appreciated
A Swing component can only have a single parent so you can't share the table header component.
You can however share the Array of column names:
JTable firstTable = new JTable(theData, columnNames);
In your buildTheSecondTable method you have access to the array of column names so just use:
//DefaultTableModel thisTableModel = new DefaultTableModel();
DefaultTableModel thisTableModel = new DefaultTableModel(columnNames);
Then you can add data to the model and the model to the table.
Then reorder the code to create the JScrollPane after you add the model to the table.
Also, get rid of the table.setLayout() code. You would never use a layout manager on a table. You don't add components to the table. The table renders the data itself without using real components.
I recently started using OpenCSV's CSVReader to get data from a CSV file to a JTable in java, but I keep getting an error. DaTroop gave the answer to how to get data from the CSV here: import csv to JTable . In my case I copied the code
CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
List myEntries = reader.readAll();
JTable table = new JTable(myEntries.toArray());
into Netbeans IDE 7.4, but I keep getting the error "Incompatible types - Object Cannot be converted to TableModel". in the
(myEntries.toArray());
Any ideas?
Thanks
As in comment, please find my whole code snippet. The JFrame works and views, so it should be called fine.
public static void LoadLog() throws FileNotFoundException, IOException {
LogViewer log = new LogViewer();
log.setVisible(true);
CSVReader reader = new CSVReader(new FileReader("testog.csv"));
String[][] rowData = {
{ "A", "B" },
{ "C", "D" }
};
List<String[]> myEntries = reader.readAll();
rowData = myEntries.toArray(new String[0][]);
String[] columnNames = { "Column 1", "Column 2" };
System.out.println(myEntries);
table1 = new JTable(rowData, columnNames);
log.pack();
log.setVisible(true);
}
First, note that reader.readAll() returns List<String[]>.
Also note that calling myEntries.toArray() returns Object[], and not Object[][], or more specifically String[][], which would be more preferable to work with.
The closest constructor for JTable that matches what you're trying to do would be this one:
JTable(Object[][] rowData, Object[] columnNames)
So you need to supply both rowData and columnNames. You can get the rowData like this:
List<String[]> myEntries = reader.readAll();
String[][] rowData = myEntries.toArray(new String[0][]);
Create a variable to hold the column names (or don't, your choice, but column names are still required):
String[] columnNames = { "Column 1", "Column 2" };
And then create your JTable:
JTable table = new JTable(rowData, columnNames);
Based on your comment, here's a short and simple code snippet for creating and displaying a table. As long as you initialize rowData and columnNames with the correct data, then it should work fine.
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String[][] rowData = {
{ "A", "B" },
{ "C", "D" }
};
String[] columnNames = { "Column 1", "Column 2" };
JTable table = new JTable(rowData, columnNames);
frame.add(new JScrollPane(table));
frame.pack();
frame.setVisible(true);
somehow in debugging data is fully retrieved and resultModel actually has got column names, and data for rows. Although when compiled and ran in Netbeans after a search, table disappears, no data is shown even column names. Here is the code:
private void search(){
String[][] rowData = new String[0][4];
String[] columns = {"appointmentid", "fname", "lname", "registration", "make", "model", "engine", "year", "mileage", "type", "date", "time"};
resultModel = new DefaultTableModel(rowData,columns);
add(new JScrollPane(jTable1));
jTable1 = new JTable(resultModel);
jTable1.setAutoCreateRowSorter(true);
try{
Model_Customer[] appointment = Controller_ManageCustomer.FindCustomers(Searchtxt.getText());
resultModel.setRowCount(0);
for(int i = 0; i < appointment.length; i++)
resultModel.insertRow(i,new Object[]{appointment[i].GetID(),appointment[i].GetFName(), appointment[i].GetLName(), appointment[i].GetRegistration(), appointment[i].GetMake(), appointment[i].GetModel(), appointment[i].GetEngine(), appointment[i].GetYear(), appointment[i].GetMileage(), appointment[i].GetType(), appointment[i].GetDate(), appointment[i].GetTime()});
}catch(Exception ex){
JOptionPane.showMessageDialog(this,ex.getMessage(),"Error",JOptionPane.ERROR_MESSAGE);
}
}
DefaultTableModel resultModel
It could just be me...but this looks very suspicious...
add(new JScrollPane(jTable1));
jTable1 = new JTable(resultModel);
Not to mention, you go a build and nice new DefaultTableModel but don't actually apply it to anything that is actually on the screen...
Try something more like...
resultModel = new DefaultTableModel(rowData,columns);
try{
Model_Customer[] appointment = Controller_ManageCustomer.FindCustomers(Searchtxt.getText());
resultModel.setRowCount(0);
for(int i = 0; i < appointment.length; i++) {
resultModel.insertRow(i,new Object[]{appointment[i].GetID(),appointment[i].GetFName(), appointment[i].GetLName(), appointment[i].GetRegistration(), appointment[i].GetMake(), appointment[i].GetModel(), appointment[i].GetEngine(), appointment[i].GetYear(), appointment[i].GetMileage(), appointment[i].GetType(), appointment[i].GetDate(), appointment[i].GetTime()});
}
if (jTable1 == null) {
jTable1 = new JTable(resultModel);
add(new JScrollPane(jTable1));
} else {
jTable1.setModel(resultModel);
}
}catch(Exception ex){
JOptionPane.showMessageDialog(this,ex.getMessage(),"Error",JOptionPane.ERROR_MESSAGE);
}
Now, personally, I would simply create the JTable and add it to the screen, and leave it alone, and simply change the TableModel when ever you wanted to update it's content...
Swing uses a form of the MVC paradigm, which means it separates the view from the model, meaning that when you want to change what the JTable is showing (the view), you simply change the model...