I try to update my JTable with the fireTableChanged() Method after i imported the names of spreadsheets from excel in my datastructure but the Method is not executed. I confirmed with a test that the data is correctly imported and that the jtable should have the necessary informationen.
What do i have to do that the JTable is correctly updated?
I found several other links to this topic but none of them worked for me:
Refresh Jtable
How to make JTable show refreshed data after updating database?
JTable How to refresh table model after insert delete or update the data.
AbstractDataTable fireTableDataChanged() does not refresh jtable
Can't refresh my JTable with new data
Model:
public class Model extends Observable {
String[][] data;
List<Arbeitsmappe> AMList = new LinkedList<>();
.....
public void setAMList(List<Arbeitsmappe> aMList) {
AMList = aMList; //new List replace the old
this.getData(); //The 2dimensional Array is filled with the names from the list
setChanged();
notifyObservers(Controller.Command_Excel_Eingelesen);
}
}
View:
JTextField cellEditorTF = new JTextField();
cellEditorTF.setEditable(false);
DefaultCellEditor cellEditor = new DefaultCellEditor(cellEditorTF);
ContentTable = new JTable(model.getData(), Model.columnNames);
//Cell Editable FALSE
ContentTable.getColumnModel().getColumn(0).setCellEditor(cellEditor);
//Single Interval Selection
ContentTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
//Cell Listener - When Cell is edited the new informationen is safed in AMLISt
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
TableCellListener tcl = (TableCellListener)e.getSource();
Model.AMList.get(tcl.getRow()).Speichername = String.valueOf(tcl.getNewValue());
// System.out.println("Row: " + tcl.getRow() + " " + Model.data[tcl.getRow()][1]);
}
};
TableCellListener tcl = new TableCellListener(ContentTable, action);
JScrollPane scrollPane = new JScrollPane(ContentTable);
ContentTable.setFillsViewportHeight(true);
ContentTable.getTableHeader().setReorderingAllowed(false);
this.add(BorderLayout.NORTH,ButtonPanel);
this.add(BorderLayout.SOUTH,scrollPane);
}
#Override
public void update(Observable arg0, Object arg1) {
if(arg0 instanceof Model){
Model model = (Model) arg0;
String cmd = (String) arg1;
if(cmd.equals(Controller.Command_Excel_Eingelesen)){
((AbstractTableModel)ContentTable.getModel()).fireTableDataChanged();
ContentTable.repaint();
this.repaint();
}
}
((AbstractTableModel)ContentTable.getModel()).fireTableDataChanged(); is called out of models definitions, it should't be, must be part of code, class void that override AbstractTableModel and its methods
as aside this method reseting all custom properties for model, and important part of methods for JTable (e.g. override for XxxTableCellRenderer/Editor)
read API in part methods for fireTableXxxXxx, there are notifiers for all JTable/AbstractTableModel's lifecycle, be sure that youare used the correct notifier for every actions/event
Related
I'm on Vaadin 7.7 and I switch tables to the grid. Only I can not personalize my cells as I would like. Here I would like to add comboboxes on a column from an arraylist and retrieve the chosen value.
Here's some of my code:
Here I create my IndexedContainer
IndexedContainer indexedContainer = new IndexedContainer();
indexedContainer.addContainerProperty("Type de véhicule",String.class,"");
Here I add my items:
indexedContainer.addItem(listValue);
indexedContainer.getContainerProperty(listValue,
key.get(0)).setValue(
String.valueOf(listValue.get(0)));
Finally I put my object in editable and I use this function to do actions during the backup:
grid.getEditorFieldGroup().addCommitHandler(new FieldGroup.CommitHandler() {
#Override
public void preCommit(FieldGroup.CommitEvent commitEvent) throws FieldGroup.CommitException {
}
#Override
public void postCommit(FieldGroup.CommitEvent commitEvent) throws FieldGroup.CommitException {
If you have any ideas or suggestions do not hesitate :)
Good night
You could use something like this:
List<String> values = obtainValues();
IndexedContainer container = new IndexedContainer();
//Add other properties...
container.addContainerProperty("comboBox", ComboBox.class, null);
//Do more stuff
ComboBox cb = new ComboBox();
cb.addItems(values);
item.getItemProperty("comboBox").setValue(cb);
And, in grid declaration, you may use an addon that allows grid to render components.
Grid grid = new Grid();
//Even more stuff
grid.setContainerDataSource(container);
grid.getColumn("comboBox").setRenderer(new ComponentRenderer());
To obtain the value of the comboBox:
Item item = container.getItem(itemId);
ComboBox cb = item.getItemProperty("comboBox").getValue();
String value = (String) cb.getValue();
Try this:
grid.getColumn("state").setEditorField(getComboState());
where getComboState is:
private Field<?> getComboState() {
ComboBox comboBox = new ComboBox();
comboBox.addItem("approve");
comboBox.addItem("no-approve");
comboBox.setImmediate(true);
comboBox.setNullSelectionAllowed(false);
return comboBox;
}
I'm a bit new to programming so sorry if there is a few things that could have been done better
My combobox is successfully filled with my string array and the auto-complete works fine. I just cant get the text in the combobox.
returns java.lang.NullPointerException
private ArrayList<String> arrRekening;
private ArrayList<String> arrEienaar;
private String[] sarrRekening;
private String[] sarrEienaar;
public NewConnectionPoint() {
arrAccount = new ArrayList<String>();
arrOwner = new ArrayList<String>();
FillCombo(arrAccount , "Owners", "OwnerName");
FillCombo(arrOwner , "Accounts", "AccountName");
sarrOwner= arrOwner.toArray(new String[arrOwner .size()]);
sarrAccount= arrAccount.toArray(new String[arrAccount.size()]);
JComboBox<String> comboAccount = new JComboBox<String>();
AutoCompleteSupport<String> supAccount = AutoCompleteSupport.install(comboRekening, GlazedLists.eventList(Arrays.asList(sarrAccount)));
supAccount.setStrict(true);
JComboBox<String> comboOwner = new JComboBox<String>();
AutoCompleteSupport<String> supOwner = AutoCompleteSupport.install(comboOwner,GlazedLists.eventList(Arrays.asList(sarrOwner)));
supOwner.setStrict(true);
JButton btnShow = new JButton("ShowSelectedr");
btnShow.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//Error occurs at this line
JOptionPane.showMessageDialog(null, comboOwner.getSelectedItem().toString());
});}
}
//Data loaded into arraylists from a Database with sql
private void FillCombo(ArrayList<String> ComboElements, String sTable, String sColumn){
try{
Data.changeQuery(sTable);// database connection fine returns and fills combobox
while(MyData.rs.next()){
String sReturn= MyData.rs.getString(sColumn);
ComboElements.add(sReturn);
}
}catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
The fundamental difficulty you're experiencing here is that you're trying to leverage the GlazedLists package without properly embracing it's core utility: EventLists.
You can easily side-step your difficulties if you use EventLists rather than ArrayLists.
If you really want to you can keep your FillCombo method returning an ArrayList (perhaps better name as getElements()) but straight-away initiate an EventList, use the GlazedLists EventComboBoxModel to link the EventList to the JComboBox and then you'll find your combobox getSelectedItem() should work fine.
The modified code to hook a list up to a combobox with autocomplete support will look something like this:
...
FillCombo(arrOwner , "Owners", "OwnerName");
EventList<String> ownerEventList = GlazedLists.eventList(arrOwner);
EventComboBoxModel<String> ownerModel = new EventComboBoxModel<String>(ownerEventList);
JComboBox comboOwner = new JComboBox(ownerModel);
AutoCompleteSupport<String> supOwner = AutoCompleteSupport.install(comboOwner,ownerEventList);
supOwner.setStrict(true);
...
I've created a small application that reads data about university subjects from an XML file.
I can add new subjects, etc.
My problem however is that I have another frame with a JComboBox in it which is filled only via one method, which is called whenever I make a change (either reading from an XML file or adding a subject which is then added to my JTable and the XML file).
When I initially start my application it will automatically open a default XML file and read the contents, and add every subject to the combo box, just as I want. However, subsequent calls (like adding a subject or opening a new file) seem to have no effect, whatsoever.
The code in question:
public void fillComboBoxSubject(ArrayList<Subject> subjectList)
{
DefaultComboBoxModel<String> cbm = new DefaultComboBoxModel<String>();
for ( Subject subject : subjectList )
{
cbm.addElement( subject.getName() ); //getName() returns a String
System.out.println(subject.getName());
}
comboBoxSubject.setModel(cbm);
}
The println will display me every single subject if I open a new file, the combo box is not updated, though.
Regards,
LML
edit: SSCCE
Contains all appearances of the combo box:
public class FEnterMark extends JFrame
{
private JComboBox<String> comboBoxSubject;
public FEnterMark()
{
comboBoxSubject = new JComboBox<String>();
comboBoxSubject.setBounds(83, 8, 140, 20);
contentPane.add(comboBoxSubject);
}
public void fillComboBoxSubject(ArrayList<Subject> subjectList)
{
DefaultComboBoxModel<String> cbm = new DefaultComboBoxModel<String>();
for ( Subject subject : subjectList )
{
cbm.addElement( subject.getName() );
System.out.println(subject.getName());
}
comboBoxSubject.setModel(cbm);
}
}
DefaultTableModel modeltable = new DefaultTableModel(8,8);
table = new JTable(modeltable);
table.setBorder(BorderFactory.createLineBorder (Color.blue, 2));
int height = table.getRowHeight();
table.setRowHeight(height=50);
table.setColumnSelectionAllowed(true);
table.setDragEnabled(true);
le1.setFillsViewportHeight(true);
panel.add(table);
panel.setSize(400,400);
DnDListener dndListener = new DnDListener();
DragSource dragSource = new DragSource();
DropTarget dropTarget1 = new DropTarget(table, dndListener);
DragGestureRecognizer dragRecognizer2 = dragSource.
createDefaultDragGestureRecognizer(option1,
DnDConstants.ACTION_COPY, dndListener);
DragGestureRecognizer dragRecognizer3 = dragSource.
createDefaultDragGestureRecognizer(option2,
DnDConstants.ACTION_COPY, dndListener);
}
}
i have a problem with adding mouse listeners to "table" which is drop target, to accept drop component wherever it drops from the mouse. in this code when component drops in to a drop target it always goes to a default position. i cant customize the position on drop target. please someone help me with this.
thanks in advance
Those listeners are far too low-level. The appropriate approach for implementing dnd is to implement a custom TransferHandler and set that custom handler to your table.
public class MyTransferHandler extends TransferHandler {
public boolean canImport(TransferHandler.TransferSupport info) {
// we only import Strings
if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) {
return false;
}
JTable.DropLocation dl = (JTable.DropLocation)info.getDropLocation();
// ... your code to decide whether the data can be dropped based on location
}
public boolean importData(TransferHandler.TransferSupport info) {
if (!info.isDrop()) {
return false;
}
// Check for String flavor
if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) {
displayDropLocation("Table doesn't accept a drop of this type.");
return false;
}
JTable.DropLocation dl = (JTable.DropLocation)info.getDropLocation();
// ... your code to handle the drop
}
}
// usage
myTable.setTransferHandler(new MyTransferHandler());
For details, see the example in the online tutorial linked to in the Swing tag description, namely the chapter Drag and Drop The code snippet above is c&p'ed from the BasicDnD example.
I have a JTable with four columns, the first one containing either a number or a text, the other three only text. I'm trying to filter this table with the help of a RowFilter:
sorter = new TableRowSorter<TableModel>(myOwnTableModel);
The checkboxFilter I got works well enough:
sorter.setRowFilter(RowFilter.regexFilter("^[0-9]$", 0));
This sorter is activated or deactivate depending on a checkbox that is either set or not.
The second filtering happens if a user puts some text in a textfield. For itself, this works fine already:
String regex = "(?i)" + Pattern.quote(s); // s = input Text of user
sorter.setRowFilter(RowFilter.regexFilter(regex, 1,2,3));
What I can't do, is to activate both filters at the same time. Maybe I'm thinking way too far, my idea has been to "concatenate" the two filters, the checkboxFilter should be "and" the other "or". I tried several things, to me the most promising looked something like:
String regex = "(?i)" + Pattern.quote(s);
bookFilter = RowFilter.regexFilter(regex, 1,2,3);
sorter.setRowFilter(bookFilter.andFilter(Arrays.asList(
RowFilter.regexFilter("^[0-9]$", 0))));
Unfortunately, this doesn't lead to any usable result. Any ideas appreciated :)
The solution is to add an ActionListener to the JCheckBox to update the filter state if the checkbox is toggled and to add a DocumentListener to the JTextField's underlying Document to update the filter state if the contents of the field is updated.
The other bug in your code is that you are calling the static andFilter method on your bookFilter instance and are only passing in the newly constructed regex filter (i.e. you are only passing in one parameter to andFilter). The correct usage is:
RowFilter andFilter = RowFilter.andFilter(filter1, filter2, etc);
Example Event Listeners
JCheckBox cb = ...
cb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
updateFilters();
}
});
JTextField tf = ...
tf.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) { updateFilters(); }
public void removeUpdate(DocumentEvent e) { updateFilters(); }
publci void changedUpdate(DocumentEvent e) { updateFilters(); }
});
... and then define your updateFilters() method to install a new filter based on when the checkbox is selected and whether the text field is empty or not.
Example Filter Update Method
public void updateFilters() {
if (cb.isSelected()) {
if (tf.getText().length() > 0) {
// Both filters active so construct an and filter.
sorter.setRowFilter(RowFilter.andFilter(bookFilter, checkBoxFilter));
} else {
// Checkbox selected but text field empty.
sorter.setRowFilter(checkBoxFilter);
}
} else if (tf.getText().length() > 0) {
// Checkbox deselected but text field non-empty.
sorter.setRowFilter(bookFilter);
} else {
// Neither filter "active" so remove filter from sorter.
sorter.setRowFilter(null); // Will cause table to re-filter.
}
}