I'm filling a JTable with a List of 68 nftDTO objects but the model paint only 48 nftDTO objects and I need to paint all of them. I paste the code:
private JTable setNftTable() {
List<NftDTO> nfts = mainWindow.getPeticiones().obtainNftAccount(user.getErd());
String[] columsName = new String[] { "Nu.","Name", "Collection name", "royalties", "website" };
DefaultTableModel model = new DefaultTableModel(4, columsName.length);
model.setColumnIdentifiers(columsName);
for (NftDTO nft : nfts) {
System.out.println(nft.getNftUrl());
if(nft.getNftUrl()==null) {
nft.setNftUrl("there is no URL");
}
model.addRow(
new Object[] { countNft(), nft.getNftName(), nft.getColletionName(), nft.getRoyalties(), nft.getNftUrl() });
}
model.removeRow(0);
model.removeRow(1);
nftTable = new JTable(model);
nftTable.setPreferredSize(new Dimension(500, 800));
return nftTable;
}
I paste by the way the list i receive and the painting of the method
The list I recieve,
the painting result
Any suggestion on how can I put all the objects on the JTable?
Related
Hi all I am not finding what's incorrect about my code below. It populates the table and headers just fine. However, when I change row 1, colum 1 to test and click off it does not color the row like I was expecting. Then clicking off the one I clicked on turns green and anywhere I click on the table from then on just changes green.
The column won't change from 1 (Company) as that will be the default column which changes will be made. The row is the only dynamic number here.
The flow to test:
double-click IBM.
type in test.
click on any another cell in order to save that cell value.
the row does not change (row 1).
click on the test cell again.
all rows will change to the green color.
The Expected flow:
double-click IBM.
type in test.
click on any another cell in order to save that cell value.
the cell that was changed to test changes that row green.
click on Shares for cell (3, 3).
double-click and change 4000 to 1000.
click on any another cell in order to save that cell value.
the cell that was changed to 1000 changes that row red.
Populated the table and headers:
Clicking and changing the row 1, column 1 value to test:
Clicking off that cell onto another one after edit:
And now, click on any other cell (notice the test row is not green as it should be):
Now clicking on the cell I edited to test:
And you see above it's just coloring each row I click on regardless of the logic I said
if ("test".equals(type)) {....
The java code:
#SuppressWarnings("serial")
public class TableRowRenderingTip extends JPanel {
public TableRowRenderingTip() {
Object[] columnNames = {"Type", "Company", "Shares", "Price", "Boolean"};
Object[][] data =
{
{"Buy", "IBM", new Integer(1000), new Double(80.5), Boolean.TRUE},
{"Sell", "Dell", new Integer(2000), new Double(6.25), Boolean.FALSE},
{"Short Sell", "Apple", new Integer(3000), new Double(7.35), Boolean.TRUE},
{"Buy", "MicroSoft", new Integer(4000), new Double(27.50), Boolean.FALSE},
{"Short Sell", "Cisco", new Integer(5000), new Double(20), Boolean.TRUE}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames) {
#SuppressWarnings({ "unchecked", "rawtypes" })
public Class getColumnClass(int column) {
return getValueAt(1, column).getClass();
}
};
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("Border", createBorder(model));
add(tabbedPane);
}
private JComponent createBorder(DefaultTableModel model) {
JTable table = new JTable(model) {
private Border outside = new MatteBorder(1, 0, 1, 0, Color.RED);
private Border _outside = new MatteBorder(1, 0, 1, 0, Color.GREEN);
private Border inside = new EmptyBorder(0, 1, 0, 1);
private Border highlight = new CompoundBorder(outside, inside);
private Border _highlight = new CompoundBorder(_outside, inside);
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
JComponent jc = (JComponent)c;
String type = (String)getModel().getValueAt(convertRowIndexToModel(row), 1);
if (isRowSelected(row)) {
if ("test".equals(type)) {
jc.setBorder( _highlight ); // Green color
jc.setBackground(Color.GREEN);
} else {
jc.setBorder( highlight ); //Red color
}
}
return c;
}
};
//table.setPreferredScrollableViewportSize(table.getPreferredSize());
//table.changeSelection(0, 0, false, false);
return new JScrollPane( table );
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI()
{
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Table Row Rendering");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TableRowRenderingTip() );
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
So needless to say I am a little frustrated to say the lest since I've been working on this for a few hours now trying to find out what could be the issue.
I'm sure it will be something simple that I'm looking over...
You're forgetting to set the border and highlighting back to default if the test condition is not true. For example
if (isRowSelected(row)) {
if ("test".equals(type)) {
jc.setBorder(_highlight); // Green color
jc.setBackground(Color.GREEN);
} else {
jc.setBorder(highlight); // Red color
}
} else {
jc.setBorder(null);
jc.setBackground(null);
}
I am writing a program where I need to open a JFrame if a button is clicked. I set the default close operation to Dispose_on_close so that when I close the window the program doesn't shutdown completely.
In the frame that will be opened, i want to put a JTable, so I wrote two methods, a createFrame() method and a mechanicListTableProperties() which is the method that creates the JTable and adds elements to it. I then call the mechanicListTableProperties inside the createFrame() and the createFrame inside the actionPerformed() method. When I open the frame 1 time, the table is shown inside the window, but if I close and reopen the frame, the table is also readded and I see 2 tables, when I am trying to just see the one table again. Here is my source code:
public class SeeMechanicsButtonHandler implements ActionListener {
JFrame mechanicListFrame;
boolean isOpen = false;
JTable mechanicListTable;
JPanel tablePanel = new JPanel(new GridLayout());
JScrollPane sp;
List<String> names = new ArrayList<String>();
String[] namesArray;
public void createFrame() {
mechanicListFrame = new JFrame();
mechanicListFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
mechanicListFrame.setSize(new Dimension(500,500));
mechanicListFrame.add(tablePanel);
mechanicListFrame.setVisible(true);
//Prevents the window from being opened multiple times
mechanicListFrame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
isOpen = false;
}
});
}
public void mechanicListTableProperties(){
mechanicListTable = new JTable(){
public boolean isCellEditable(int row, int column) {
return false;
}
};
DefaultTableModel model = new DefaultTableModel();
model.addColumn("Nome", namesArray);
//Creates a column with title as Nome and lines as the array
mechanicListTable.setModel(model); //adds column to the the table
mechanicListTable.setBounds(30, 40, 200, 300); //table size
mechanicListTable.setFont(new Font("Arial Rounded MT", Font.BOLD, 15));
// adding it to JScrollPane
sp = new JScrollPane(mechanicListTable);
tablePanel.add(sp);
}
public void actionPerformed(ActionEvent e) {
if(!isOpen) {
try {
//SQL code to get the data from mechanics table
ResultSet rs = ServerConnection.createQueryStatement("SELECT * FROM mechanics");
while (rs.next()){
//loop to add each entry in the table to an array list
names.add(rs.getString("nome"));
}
//creates an array to put the values from the arraylist
namesArray = new String[names.size()];
for (int iterate = 0; iterate < names.size(); iterate++){
//loop that iterates through the arraylist and puts the values in the array
namesArray[iterate] = names.get(iterate);
System.out.println(namesArray[iterate]);
//prints to the console for testing purposes
}
} catch (SQLException e1) {
e1.printStackTrace();
}
createFrame();
isOpen = true;
}
}
}
I want to update a swing table's row value in the DB, clear the model, and load the new model with the new updated value. The problem is that when I click the button to update the value, the model is cleared but no data is shown in the table. What am I doing wrong?
Parts of the code not relative to the table have been removed in order to make the example easier.
public class ShowValues extends JFrame {
//Attributes
private DefaultTableModel model;
private JTable table = new JTable()
{
public boolean isCellEditable(int row, int column)
{
return false;
};
};
public ShowValues() {
btnDeleteItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
int selectedRowNumber = table.getSelectedRow();
String selectedItemId = (String) table.getModel().getValueAt(selectedRowNumber, 0);
//code to change selected item's state to deleted in the DB
model.setRowCount(0); //clear model
showTable(); //load new model
labelMsg.setText("Item deleted");
}
});
btnDeleteItem.setBounds(200, 320, 203, 57);
contentPane.add(btnDeleteItem);
}
public void showTable()
{
String columnNames[] = {"Item Id", "Item Name", "Item price"};
//code to get the data form the DB
String dataValues[][] = new String[itemNum][3];
for(int i=0; i<itemNum; i++)
{
dataValues[i][0] = idItem[i];
dataValues[i][1] = nameItem[i];
dataValues[i][2] = priceItem[i];
}
model = new DefaultTableModel(dataValues, columnNames);
table.setModel(model);
scrollPane = new JScrollPane(table);
scrollPane.setBounds(17, 20, 490, 205);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
topPanel.add(scrollPane);
}
}
//code to change selected item's state to deleted in the DB
Why would you want to reload all the data just because the change the value of one property in the row? That is not very efficient.
Just use the setValueAt(...) method to change the value in the JTable.
The problem is that when I click the button to update the value, the model is cleared but no data is shown in the table
The problem is you create a new JTable, but you never add the table to the viewport of your JScrollPane.
The solution is to NOT create a new JTable. Just create a new TableModel. Then you can just use:
table.setModel( theNewlyCreateTableModel );
I have a program that allows the user to do a search in the warehouse. The result is returned in a JTable.
So far everything is good. When I attempt to do a second search, the old table is still showing.
Image:
Code:
public void panelTable(){
panelTable= new JPanel();
panelTable.setSize(400, 80);
panelTable.setOpaque(true);
panelTab = new JTable();
modele = new DefaultTableModel();
}
public void creerJTable(List<Pneu> liste){
String[] head= {"A", "B", "C"};
Object[][] data = null;
data = new Object[liste.size()][3];
Iterator<Pneu> it = liste.iterator();
int index = 0;
while(it.hasNext()){
Pneu unPneu = it.next();
data[index][0] = unPneu.descrip();
data[index][1] = unPneu.width();
data[index][2] = unPneu.height();
index++;
}
modele.setDataVector(data, head);
panelTab.setModel(modele);
panelTab.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
panelTab.setFillsViewportHeight(true);
panelTab.setPreferredScrollableViewportSize(new Dimension(500, 80));
panelTab.setModel(modeleColonnesNoEdit(data, entete));
panelTab.setRowSelectionInterval(0, 0);
panelTab.getColumnModel().getColumn(0).setPreferredWidth(250);
panelTab.getColumnModel().getColumn(1).setResizable(false);
panelTab.getColumnModel().getColumn(1).setPreferredWidth(50);
panelTab.getColumnModel().getColumn(2).setResizable(false);
panelTab.getColumnModel().getColumn(2).setPreferredWidth(50);
JScrollPane scrollPane = new JScrollPane(panelTab);
scrollPane.setPreferredSize(new Dimension(500, 60));
panelTable.add(scrollPane);
}
When clicking on the search button, you are taken to the class Listener which verifies that the button search was clicked. Once that is done, you have this code:
frame.creerJTable(liste);
This line of code, takes the list created from that search and calls the method creerJTable(List liste) that is shown in the above code.
Here's the code for the modeleColonnesNoEdit()
private DefaultTableModel modeleColonnesNoEdit(Object[][] data, String[] head) {
return new DefaultTableModel(data, head)
{
boolean[] columnEditables = new boolean[] { false, false, false};
public boolean isCellEditable(int row, int column) {
return columnEditables[column];
}
};
}
You should not be re-adding a JScrollPane or adding any new components to the GUI in the search. Instead, take the original JTable, simply change its TableModel, and that's it, do nothing more.
I have a JTable with rows that list files and folders in a directory. The folder rows have a button that hide and show rows listing the files in the folder. When the application starts up, the files rows that come after their folder row are hidden. I used RowFilter to initially hide these rows after the table was created in a subclass method:
...
public void createTable(){
//Create and populate table
...
//Add the filter to initially hide the subfile rows
TableRowSorter<DefaultTableModel> sorter = new TableRow Sorter<DefaultTableModel>(tableModel);
RowFilter hidefilter = getRowFilter();
sorter.setRowFilter(hidefilter);
myTable.setRowSorter(sorter);
}
...
private RowFilter getRowFilter() {
RowFilter<DefaultTableModel, Integer> filter = new RowFilter<DefaultTableModel, Integer>() {
#Override
public boolean include(RowFilter.Entry<? extends DefaultTableModel, ? extends Integer> entry) {
int modelRow = entry.getIdentifier();
if(/* current row column contains a certain flag */){
//Hide the row that represents a file in the folder
return false;
}
else return true;
}
};
return filter;
}
This code successfully hides the rows, but I'm wondering how to show and re-hide only some of the hidden rows. Can this be done with a filter class like the one I've already done? Is there a way for a filter function to be called by a button and filter based on a value found in a column?
The basic idea is that we need to have a Filter class that filters entries depending on the value of its fields (I only created one field to keep the example simple), and the filter also has methods that change the value of those fields.
Then we create a button that calls this method when pressed, followed by a call to table.getRowSorter().allRowsChanged(), which signals to the table that the data has changed so it has to redraw itself.
Here's a working example.
public class Test {
public static class Filter extends RowFilter<TableModel, Integer> {
private String includePrefix = "Foo";
#Override
public boolean include(
javax.swing.RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
return entry.getStringValue(0).startsWith( includePrefix );
}
// Calling this method changes the filter to allow a different prefix
public void swapPrefix() {
this.includePrefix = this.includePrefix.equals("Foo") ? "Bar" : "Foo";
}
}
public static void main(String[] args) {
//setup
JFrame frame = new JFrame();
frame.setLayout( new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
JTable table = new JTable( new Object[][]{ new Object[]{ "Foo 1" },
new Object[]{ "Bar 1" },
new Object[]{ "Foo 2" },
new Object[]{ "Foo 3" },
new Object[]{ "Bar 2" }},
new Object[] { "Foo"});
//create and configure sorter
Filter filter = new Filter();
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel());
sorter.setRowFilter(filter);
table.setRowSorter(sorter);
JButton changeFilter = new JButton( "Change filter");
// pressing the button changes the filter first, then tells the table sorter to update the display
changeFilter.addActionListener( e -> { filter.swapPrefix(); table.getRowSorter().allRowsChanged(); });
//display window
frame.add( table );
frame.add(changeFilter);
frame.pack();
frame.setVisible( true );
}
}