I have 14 JFrame
classes and one JFrame
class holding a JTable
which acts as a calendar. I want the date of a text field or any other component in any of the 14 JFrame
classes to be changed when the user selects the date from the JTable
calendar . Now, the frames appear one at a time and the jtable is instantiated from a JButton
on any of the 14 JFrame classes.
My dilemma is how to identify the JFrame
class that has instantiated the JFrame
that contains the JTable
so that it's text field value can be changed.
Code that instantiates the JFrame containing the table:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
JFrame frmMain = new Calender();
frmMain.setVisible(true);
frmMain.setSize(367, 342);
}
Code that changes the value of the textfield from one of the 14 JFrame
classes :
@Override
public void mouseClicked(MouseEvent me) {
if (me.getClickCount()==2){
int selected1 = jTable1.getSelectionModel().getLeadSelectionIndex();
int selected2 =jTable1.getColumnModel().getSelectionModel().getLeadSelectionIndex();
Object c = jTable1.getModel().getValueAt(selected1, selected2);
SowInformation.jTextField4.setText(c.toString());
this.setVisible(false);
}
}
Where SowInformation
is one of the 14 JFrame
classes.
As @AndrewThompson wisely mentioned, the use of multiple JFrame is a bad practice. In this case a (non-)modal dialog would be a better choice.
Now let's assume you choose non-modal dialogs, then you still having the same problem. There are several ways to solve it but essentially you need to keep a reference to the frame/dialog which opened the calendar's frame. Even better, you can use interfaces to define a contract to update a text field isolating the desired behavior from the actual implementation. For example:
public interface IUpdateText {
public void updateText(String text);
}
Now your calendar's frame needs to keep a reference to a IUpdateText
compliant object:
class Calender extends JFrame {
...
private IUpdateText updateText;
...
public void setIUpdateText(IUpdateText ut) {
this.updateText = ut;
}
...
}
Then in your mouse listener implementation just call updateText()
method:
@Override
public void mouseClicked(MouseEvent me) {
if (me.getClickCount()==2){
int selectedRow = jTable1.getSelectedRow();
int selectedColumn = jTable1.getSelectedColumn();
if (selectedRow > -1 && selectedColumn > -1) {
Object value = jTable1.getValueAt(selectedRow, selectedColumn); // ask the value to the view, not the model. Otherwise you need to convert both row and column indexes
this.updateText.updateText(value.toString());
this.setVisible(false); // maybe this.dispose() instead ?
}
}
}
Of course all your other frames/dialogs that can open this calendar frame would have to implement IUpdateText
interface. For example SowInformation
frame:
class SowInformation extends JFrame implements IUpdateText {
...
private JTextField jTextField4;
...
@Override
public void updateText(String text) {
this.jTextfield4.setText(text);
}
...
}
And finally set the IUpdateText
compliant object to the calendar frame when you instantiate it:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Calender frmMain = new Calender();
calender.setIUpdateText(this); // assuming 'this' is an IUpdateText interface compliant
frmMain.pack();
frmMain.setVisible(true);
}
From an architectural point of view this problem might be better solved through an MVC pattern, having a Controller which acts as an intermediary for both frames/dialogs. There are multiple questions about MVC pattern and Swing here in SO but I really like the example/explanation shown in this answer by @MadProgrammer (a real Swing guru).