My question is based on my large app that I've recently decided to upgrade. There are a lot of panel, tables in my app that are needed to refresh after data have comen from server. As all parts of app I write at different time and different level of my knowledge, so I used different methods of updating that I need to standartised.
Now my question is what is best way to update components after refreshing data (all components in panels, their quantity and content are based on ArrayLists) from methods below (or another, that I didn't count)? And I search an answer that would be not an assumption, but documentation-based why it would be more correct to implement particular that way.
I suppose there are next ways to update components:
- In method that receive new data from server call the needed container and repaint().
Disadvantage: I would work only if you also call, for example textfield.setText(). And this method don't work if I just replace ArrayList to which this panel refers.
My code of receiving data from server (in case ADD I need to add action to update some panel or table):
public class ClientOperation {
private Socket socket;
private ObjectInputStream cin;
private ObjectOutputStream cout;
private DataStorage data = new DataStorage();
public static void main(String[] args) {
ClientOperation client = new ClientOperation();
client.clOperation();
}
public void clOperation() {
try {
socket = new Socket("localhost", 7800);
cin = new ObjectInputStream(socket.getInputStream());
cout = new ObjectOutputStream(socket.getOutputStream());
while ((request = (Request) cin.readObject()) != null) {
switch (request.getType()) {
case PROJECT:
switch (request.getAction()) {
case ADD:
data.getProjects().add((Base.Project) request.getData());
break;
}
break;
}
}
}
}
And support class as bundle for sending objects:
public class Request implements Serializable{
private static final long serialVersionUID = 1L;
private CatalogEnum.Type type;
private CatalogEnum.Action action;
private Object data;
public Request(CatalogEnum.Type type, CatalogEnum.Action action, Object data){
this.type = type;
this.action = action;
this.data = data;
}
}
- In method that receive new data from server call the needed container and updateUI().
Disadvantage: I found that this just update Look and Feel so it doesn't help me.
- In method that receive new data from server call all actions from removeAll() from container to add all new components
Disadvantage: Each time there are a lot of actions to create container, so it needs a separate class.
Addition: I realised that way through a separate class with all methods that refresh different panels from different classes and used getters and setters of panels.
Disadvantage of addition: I had to create a lot of examples of panels and tables. And it seems to me uncorrect to save them in memory. However, now it is the best way from others now.
In short view I show you code of this:
public class PanelContent implements PanelContentInterface {
private JPanel taskPanel = new JPanel();
private DataStorage data;
private JFrame mainwindow = new JFrame(nameFrame);
public JPanel getTaskPanel() {
taskPanel.updateUI();
return taskPanel;
}
public void setTaskPanel() {
taskPanel.removeAll();
for (int i = 0; i<data.getProjects().size();i++){
JButton btn = new JButton (data.getProjects().get(i).getTitle());
taskPanel.add(btn);
}
this.taskPanel = taskPanel;
mainframe.setContentPane(taskPanel);
}
public JFrame frameConstructor (JFrame mainframe, String nameFrame, JPanel panel) {
mainframe.setTitle(nameFrame);
mainframe.setJMenuBar(***.getMenuBar());
panel.setBackground(Color.WHITE);
mainframe.setContentPane(panel);
mainframe.setVisible(true);
return mainframe;
}
}
Imagine that frame is already visible and in case ADD in example of code before I add line like this through initializing PanelContent in ClientOperation:
case ADD:
data.getProjects().add((Base.Project) request.getData());
panelContent.setTaskPanel();
break;
This code works. However, it needs separating all panels to basic and static parts and dynamic parts.
- To last action we can add revalidate()
Disadvantage: I know that this method is called in any case because changes in base parametrs of container according documentation, so it calling doesn't have influence.
- Also for Tables and ComboBoxes I can mention fireTableDataChanged()
Disadvantage: I also read that this method is called automatically if there is any changes in model. But I often replace model, not changing it, so it doesn't fit me.
- As for me works in method that receive new data from server to call table and setModel to it.
Disadvantage: Because of using special class for setting all models I have to save and send a lot of variables as a structure. Example is below.
Panel.comboBox.setModel(Panel.model.comboBox(Panel.arraySchedule));
Ultimately, addition to method 3 for JPanels and method 6 for JTables and JComboBoxes seem to me as relatively suitable.
I ask you to add your point of view:
If you think the same, may be you can say that disadvantages that I added is not important.
If you think that I did other methods wrong, could you say why they are better refers to it properties.
Or you have other practicies?