I have a JList which is supposed to display a list of school tests. When I add values to this list in Swing Designer then it displays everything correctly, but when I try to display my own data it still shows the values initialized in Swing Designer. How to display my own set of data in JList? My initial update in code:
public void updateFrame(MainFrame mainFrame)
{
DefaultListModel<Test> listModel = new DefaultListModel<Test>();
for(int i = 0 ; i < this.getTestList().size() ; i++)
listModel.add(i, this.getTestList().get(i));
JList<Test> currList = new JList<>(listModel);
currList.setVisible(true);
mainFrame.setList(currList);
mainFrame.getList().setVisible(true);
}
Also my ListListener doesn't activate at any moment, but it's another problem, maybe easier to figure out after the first one.
class ListListener implements ListSelectionListener {
#Override
public void valueChanged(ListSelectionEvent e) {
DefaultListModel<Test> listModel = new DefaultListModel<Test>();
for(Test test : model.getTestList())
listModel.addElement(test);
JList<Test> currList = new JList<Test>(listModel);
mainFrame.setList(currList);
}
}
Again, don't swap components but rather models, something like:
public void updateFrame(MainFrame mainFrame) {
DefaultListModel<Test> listModel = new DefaultListModel<Test>();
for(int i = 0 ; i < this.getTestList().size() ; i++) {
listModel.add(i, this.getTestList().get(i));
}
// ***** get rid of this *****
// JList<Test> currList = new JList<>(listModel);
// currList.setVisible(true);
// mainFrame.setList(currList);
// ***** and instead simply do this *****
mainFrame.getList().setModel(listModel);
}
If this doesn't work, then yes, create and post your MCVE
Related
I am learning Java Swing. I am trying to develop as simple app for learning purpose. There is are multiple issues in following code. I try to read a csv file and populate JComboBox on button click.
public class MyForm {
private JButton btnRead;
private JButton btnRead2;
private JComboBox cbCodes;
private JPanel mainPanel;
private DefaultComboBoxModel comboBoxModel;
public MyForm(){
// issue 1: I always get null pointer exception in this line
comboBoxModel = new DefaultComboBoxModel();
cbCodes = new JComboBox(comboBoxModel);
btnRead.addActionListener( e -> {
List<String[]> data = readData();
comboBoxModel.removeAllElements();
data.forEach(item -> comboBoxModel.addElement(item));
});
// issue 2: Since DefaultComboBoxModel was not working. I tried without it. As this I get correct data in the array. But when I make JComboBox with array. Nothing is filled. It is empty.
btnRead2.addActionListener( e -> {
List<String[]> data = readData();
String[] array = new String[data.size()];
data.toArray(array);
cbCodes = new JComboBox(array);
});
}
// issue 3: I can't complie the code without this empty method. Why do I need it?
// error: Form contains components with Custom Create option but no createUIComponents() method
void createUIComponents(){
}
public List<String[]> readData() {
String file = "data.csv";
List<String[]> content = new ArrayList<>();
try(BufferedReader br = new BufferedReader(new FileReader(file))) {
String line = "";
while ((line = br.readLine()) != null) {
if(line.contains("\"")){
content.add(line.split(" "));
}
content.add(line.split(","));
}
} catch (FileNotFoundException e) {
//Some error logging
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
public static void main(String[] args) {
JFrame frame = new JFrame("MyForm");
frame.setContentPane(new MyForm().mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
I make my question in the source code with the comment to show exactly here those issues are involved.
You don't get the NullPointerException in the lines you indicated, but in the line btnRead.addActionListener( e -> { because btnRead has not been initialized yet!
When you create a new JComboBox, you have to add it to the panel, too. Just creating it with new will not display it. But the real problem behind it is: you're using the model wrong. Write
comboBoxModel.removeAllElements();
for (final String string : array) {
comboBoxModel.addElement(string);
}
to solve that.
The problem you have here does not lie within the code you provided, but from another component. At some point, someone used a UI designer. Those designers usually create initialization methods, just like createUIComponents. See where that method gets called.
Synopsis:
All in all, your code is really chaotic. Restructure from new, this will clean up a lot of problems.
And initialize UI components as soon as possible, best do it in the declaration line: private final JButton btnRead = new JButton("Read!");
I strongly recommend using an IDE like Eclipse or IntelliJ that will help you write clean code and see and correct problems easier.
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 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
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 want to define a maximum number of selected items in TwinColSelect in my vaadin ui. How can I achieve it. I want to allow the user to select only 4 planets out of available 8.My current code is
TwinColSelect table = new TwinColSelect();
table.setImmediate(true);
String planets[] = {"Mercury", "Venus", "Earth", "Mars",
"Jupiter", "Saturn", "Uranus", "Neptune"};
for (int pl=0; pl<planets.length; pl++)
table.addItem(planets[pl]);
table.addListener(new Property.ValueChangeListener() {
public void valueChange(ValueChangeEvent event) {
/*String [] arr=(String [] )event.getProperty().getValue();
if(arr.length>=4){
return;
}*/
}
});
You can implement something like this by changing select's value:
//Constant declared somewhere in the class
private static final int SELECTED_ITEMS_LIMIT = 4;
...
table.addListener(new Property.ValueChangeListener() {
#Override
public void valueChange(ValueChangeEvent event) {
Collection selectedItems = (Collection) event.getProperty().getValue();
if(selectedItems.size()>SELECTED_ITEMS_LIMIT) { //Set no more than SELECTED_ITEMS_LIMIT values
Set<String> noMoreThanLimitItems = new HashSet<String>(selectedItems.size());
int counter = 0;
for(Object item : selectedItems) {
if(counter>=SELECTED_ITEMS_LIMIT) {
break;
}
noMoreThanLimitItems.add((String) item);
counter++;
}
event.getProperty().setValue(noMoreThanLimitItems);
}
}
});
Drawbacks:
Code is server-side. So, more than four planets might appear as selected between browser requests.
Call to Property.setValue fires ValueChangeEvent. So, handling code will be executed twice every time when user tries to select more than four planets
Thanks to default locale in advance. Yesterday i made some eddits to the above code which remove the first drawback mentioned in the other answer, as well as changed the add which became decrepated.
The answer for Vaadin 7 would be as follows then
table.addValueChangeListener(new Property.ValueChangeListener() {
#Override
public void valueChange(ValueChangeEvent event) {
Collection selectedItems = (Collection) event.getProperty().getValue();
if(selectedItems.size()>SELECTED_ITEMS_LIMIT) { //Set no more than SELECTED_ITEMS_LIMIT values
Set<String> noMoreThanLimitItems = new HashSet<String>(selectedItems.size());
int counter = 0;
for(Object item : selectedItems) {
if(counter>=SELECTED_ITEMS_LIMIT) {
break;
}
noMoreThanLimitItems.add((String) item);
counter++;
}
event.getProperty().setValue(noMoreThanLimitItems);
//cast to twincol to get the needed functions
//markasdirty makes the object be repainted, so you wil not see more then 4 selected
((TwinColSelect)event.getProperty()).markasdirty();
}
}
});