Search code examples
javaswingjtablejtextfield

Changing the value of a textfied in JFrame class1, JFrame class2,... by selecting an item from jtable in Jframe class3


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.


Solution

  • 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);
    }
    

    Other comments

    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).