Reputation: 1
I'm trying to make a method that will get data items from the array present in one class, and then put that information into a JTable using for
loops. This is what I've come up with:
public void createLoginsTable()
{
String[] loginTableTitles = { "Username", "Password" }; //Creating arrays for my Table
String[][] loginTableLogins = new String[100][1];
for(int i=0;list.nextLogin>i;i++)
{
loginTableLogins[i][0] = list.listOfLogins[i].username;
loginTableLogins[i][1] = list.listOfLogins[i].password;
}
loginsScrollPane = new JScrollPane(loginsTable = new JTable(loginTableLogins, loginTableTitles));
loginsScrollPane.setBounds(400, 300, 200, 400);
testPanel.add(loginsScrollPane);
}
I made the normal array for the column headings of the table, and then I tried to use these for
loops to put in the usernames and passwords present in the regular array present in the other class. I'm quite new to java so I assumed that loginTableLogins[i][0]
means it will put the details in to the first column and the 'i' row. But this is in an action lisener of a button and every time I press the button, I get every error in the book popping up. Some advice would really help.
Upvotes: 0
Views: 1976
Reputation: 347294
A few things pop out.
You seem to already have an object that represents the data you want to display. Rather then having to translate it backwards and forwards between the table model, you should create a table model capable of managing/holding the original objects.
String[][] loginTableLogins = new String[100][1];
is declared wrong for two reasons. Firstly, what happens if you have more then or less then 100 rows? Secondly, you've only declared a single column, which obviously isn't what you want. You already have the number of elements that are contained in the list of objects, so you should be able to create an array which already contains the correct number of rows
Personally, I'd avoid DefaultTableModel
, by the time you override and implement all the functionality you need to, you've would have done the same amount of work as if you have started with a AbstractTableModel
.
For example...
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
public class SimpleTable {
public static void main(String[] args) {
new SimpleTable();
}
public SimpleTable() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
LoginTableModel model = new LoginTableModel();
model.add(new Login("Elma Thud", "Shh, I'm hunting rabbits".toCharArray()));
JTable table = new JTable(model);
table.getColumnModel().getColumn(1).setCellRenderer(new PasswordCellRenderer());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PasswordCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof char[]) {
char[] pass = (char[]) value;
StringBuilder sb = new StringBuilder(pass.length);
while (sb.length() < pass.length) {
sb.append("*");
}
value = sb.toString();
}
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
return this;
}
}
public class Login {
private String userName;
private char[] password;
public Login(String userName, char[] password) {
this.userName = userName;
this.password = password;
}
public String getUserName() {
return userName;
}
public char[] getPassword() {
return password;
}
}
public class LoginTableModel extends AbstractTableModel {
private List<Login> logins;
public LoginTableModel() {
logins = new ArrayList<>(25);
}
public void add(Login... login) {
int startAt = getRowCount();
logins.addAll(Arrays.asList(login));
int endAt = getRowCount();
fireTableRowsInserted(startAt, endAt - 1);
}
@Override
public int getRowCount() {
return logins.size();
}
@Override
public String getColumnName(int column) {
return column == 0 ? "Username" : "Password";
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Login login = logins.get(rowIndex);
Object value = null;
switch (columnIndex) {
case 0:
value = login.getUserName();
break;
case 1:
value = login.getPassword();
break;
}
return value;
}
}
}
Check out How to use tables for more details
Upvotes: 3
Reputation: 10959
A few things to note:
new String[100][1];
. This is the same as a 1D Array as the second dimension is 1 (i.e. 1 column), use new String[100][2];
instead.loginsScrollPane = new JScrollPane(loginsTable = new JTable(loginTableLogins, loginTableTitles));
into
loginsTable = new JTable(loginTableLogins, loginTableTitles)
loginsScrollPane = new JScrollPane(loginsTable);
for easier debugging.
Upvotes: 3