4

I've spent a bit of time browsing Stack Overflow and the internet looking for the answer to my question, but I found all the answers hard to understand and I was quite unsure if any of them related to my problem, so I decided I needed help in the right context.

I am creating a program that will give a series of solutions based on a particular type of graph inputted. I am sincerely struggling with taking the data from my JComboBox in the first JFrame, and displaying it in the second.

I have two classes, GraphEquationSolverGUI and DefineEquation. I am using the Netbeans IDE and GraphEquationSolverGUI is my "project."

GraphEquationSolverGUI:

private void graphSelectionActionPerformed(java.awt.event.ActionEvent evt) {                                               
    String graphSelectionGUI = (String)graphSelection.getSelectedItem();
    //graphSelectedTextField.setText(graphSelectionGUI);
    DefineEquation graphSelectedObj = new DefineEquation(graphSelectionGUI);
    graphSelectedObj.addItem(graphSelectionGUI);

This is the JComboBox in which I want the selection to send data to another class. The JComboBox is called graphSelection. You will notice the the commented text is me setting a JTextField to the value of the JComboBox, this is inside of this JForm and was used by myself to test to make sure the data was being input right, it works and I can display the data in this same JFrame. The other code following is my attempt to create an object and pass the data through it, I'm a bit rusty with objects as I haven't worked with them for a while, sorry if I make you cry.

DefineEquation:

public DefineEquation(String graphSelected) {
    this.graphSelected = graphSelected;
} //If anyone cares here is my constructor for the object

public void addItem(String graphSelectedString1){
    DefineEquation graphSelectedObj = new DefineEquation(graphSelected);
    String graphSelectedStringMAIN = graphSelectedString1.toString();
    selectedGraph.setText(graphSelectedStringMAIN);
}

The above is the method I created to add the data to a JTextField called selectedGraph. You will notice I have graphSelectedString1 and graphSelectedStringMAIN in which I convert a String to a String which is obviously redundant. I did this just in case, it is redundant, sorry for making you cringe.

I understand that this may be hard to follow, and you may find it hard to understand what I am asking. So simply put, how would I pass data from one JFrame JComboBox to a JTextField in a separate JFrame? Would I use Objects? Please try to walk me through it if you can, I am very confused. I will paste all my code below if you wish to read through everything.

GraphEquationSolverGUI:

/*
* To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package GUI;

/**
 *
 * @author MatthewAlanTroutman
 */

public class GraphEquationSolverGUI extends javax.swing.JFrame {

/**
 * Creates new form GraphEquationSolverGUI
 */

public GraphEquationSolverGUI() {
    initComponents();
}


/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jSpinner1 = new javax.swing.JSpinner();
    welcome = new javax.swing.JLabel();
    programDescription = new javax.swing.JLabel();
    graphsOffered = new javax.swing.JLabel();
    linear = new javax.swing.JLabel();
    bilinear = new javax.swing.JLabel();
    quadratic = new javax.swing.JLabel();
    cubic = new javax.swing.JLabel();
    exponential = new javax.swing.JLabel();
    graphSelectionText = new javax.swing.JLabel();
    graphSelection = new javax.swing.JComboBox();
    help = new javax.swing.JButton();
    close = new javax.swing.JButton();
    next = new javax.swing.JButton();
    graphSelectedTextField = new javax.swing.JTextField();
    graphSelectedLabel = new javax.swing.JLabel();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("GraphEquationSolver");
    setBackground(new java.awt.Color(255, 255, 255));

    welcome.setFont(new java.awt.Font("Lucida Grande", 0, 48)); // NOI18N
    welcome.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
    welcome.setText("Welcome");
    welcome.setPreferredSize(new java.awt.Dimension(800, 100));

    programDescription.setFont(new java.awt.Font("Lucida Grande", 0, 14)); // NOI18N
    programDescription.setText("You can use this program to find a variety of solutions for different types of graphs, please select a graph to begin");
    programDescription.setPreferredSize(new java.awt.Dimension(800, 75));

    graphsOffered.setFont(new java.awt.Font("Lucida Grande", 0, 18)); // NOI18N
    graphsOffered.setText("Graphs we offer:");

    linear.setFont(new java.awt.Font("Lucida Grande", 0, 14)); // NOI18N
    linear.setText("- Linear");

    bilinear.setFont(new java.awt.Font("Lucida Grande", 0, 14)); // NOI18N
    bilinear.setText("- Bilinear");

    quadratic.setFont(new java.awt.Font("Lucida Grande", 0, 14)); // NOI18N
    quadratic.setText("- Quadratic");

    cubic.setFont(new java.awt.Font("Lucida Grande", 0, 14)); // NOI18N
    cubic.setText("- Cubic");

    exponential.setFont(new java.awt.Font("Lucida Grande", 0, 14)); // NOI18N
    exponential.setText("- Exponential");

    graphSelectionText.setFont(new java.awt.Font("Lucida Grande", 0, 18)); // NOI18N
    graphSelectionText.setText("Please select your graph");

    graphSelection.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Linear", "Bilinear", "Quadratic", "Cubic", "Exponential" }));
    graphSelection.setToolTipText("");
    graphSelection.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            graphSelectionActionPerformed(evt);
        }
    });

    help.setFont(new java.awt.Font("Lucida Grande", 0, 48)); // NOI18N
    help.setText("Help");

    close.setFont(new java.awt.Font("Lucida Grande", 0, 48)); // NOI18N
    close.setText("Close");
    close.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            closeActionPerformed(evt);
        }
    });

    next.setFont(new java.awt.Font("Lucida Grande", 0, 48)); // NOI18N
    next.setText("Next");
    next.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            nextActionPerformed(evt);
        }
    });

    graphSelectedTextField.setEditable(false);

    graphSelectedLabel.setFont(new java.awt.Font("Lucida Grande", 0, 18)); // NOI18N
    graphSelectedLabel.setText("Graph Selected");

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(welcome, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(240, 240, 240))
        .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(240, 240, 240)
                    .addComponent(programDescription, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGroup(layout.createSequentialGroup()
                    .addGap(184, 184, 184)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(exponential)
                        .addGroup(layout.createSequentialGroup()
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(graphsOffered)
                                .addComponent(linear)
                                .addComponent(bilinear)
                                .addComponent(quadratic)
                                .addComponent(cubic))
                            .addGap(311, 311, 311)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addComponent(graphSelectionText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(graphSelection, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(graphSelectedTextField)
                                .addComponent(graphSelectedLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))))
                .addGroup(layout.createSequentialGroup()
                    .addGap(231, 231, 231)
                    .addComponent(help, javax.swing.GroupLayout.PREFERRED_SIZE, 255, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(18, 18, 18)
                    .addComponent(close, javax.swing.GroupLayout.PREFERRED_SIZE, 255, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(18, 18, 18)
                    .addComponent(next, javax.swing.GroupLayout.PREFERRED_SIZE, 255, javax.swing.GroupLayout.PREFERRED_SIZE)))
            .addContainerGap(240, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(34, 34, 34)
            .addComponent(welcome, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(programDescription, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(73, 73, 73)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(graphsOffered)
                .addComponent(graphSelectionText))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(graphSelection, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(linear)
                .addComponent(graphSelectedLabel))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(bilinear)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(quadratic))
                .addComponent(graphSelectedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(cubic)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(exponential)
                    .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGroup(layout.createSequentialGroup()
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 219, Short.MAX_VALUE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(help, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(close, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(next, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGap(169, 169, 169))))
    );

    graphSelection.getAccessibleContext().setAccessibleName("");
    help.getAccessibleContext().setAccessibleName("help");
    close.getAccessibleContext().setAccessibleName("close");

    pack();
}// </editor-fold>                        

private void graphSelectionActionPerformed(java.awt.event.ActionEvent evt) {                                               
    String graphSelectionGUI = (String)graphSelection.getSelectedItem();
    graphSelectedTextField.setText(graphSelectionGUI);
    //DefineEquation graphSelectedObj = new DefineEquation(graphSelectionGUI);
    //graphSelectedObj.addItem(graphSelectionGUI);

}                                              

private void closeActionPerformed(java.awt.event.ActionEvent evt) {                                      
    System.exit(0);
}                                     

private void nextActionPerformed(java.awt.event.ActionEvent evt) {                                     
    this.setVisible(false);
    new DefineEquation().setVisible(true);
}                                    

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(GraphEquationSolverGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(GraphEquationSolverGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(GraphEquationSolverGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(GraphEquationSolverGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new GraphEquationSolverGUI().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JLabel bilinear;
private javax.swing.JButton close;
private javax.swing.JLabel cubic;
private javax.swing.JLabel exponential;
private javax.swing.JLabel graphSelectedLabel;
private javax.swing.JTextField graphSelectedTextField;
private javax.swing.JComboBox graphSelection;
private javax.swing.JLabel graphSelectionText;
private javax.swing.JLabel graphsOffered;
private javax.swing.JButton help;
private javax.swing.JSpinner jSpinner1;
private javax.swing.JLabel linear;
private javax.swing.JButton next;
private javax.swing.JLabel programDescription;
private javax.swing.JLabel quadratic;
private javax.swing.JLabel welcome;
// End of variables declaration                   
}

DefineEquation:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package GUI;

/**
 *
 * @author MatthewAlanTroutman
 */
public class DefineEquation extends javax.swing.JFrame {
//public class DefineEquation extends GraphEquationSolverGUI {
public String graphSelected;

/**
 * Creates new form DefineEquation
 */
public DefineEquation() {
    initComponents();
}
public DefineEquation(String graphSelected) {
    this.graphSelected = graphSelected;
}



/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    selectedGraph = new javax.swing.JTextField();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    selectedGraph.setEditable(false);
    selectedGraph.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            selectedGraphActionPerformed(evt);
        }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(435, 435, 435)
            .addComponent(selectedGraph, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(596, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(126, 126, 126)
            .addComponent(selectedGraph, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(646, Short.MAX_VALUE))
    );

    pack();
}// </editor-fold>                        

private void selectedGraphActionPerformed(java.awt.event.ActionEvent evt) {                                              

}                                             
public void addItem(String graphSelectedString1){
    DefineEquation graphSelectedObj = new DefineEquation(graphSelected);
    String graphSelectedStringMAIN = graphSelectedString1.toString();
    selectedGraph.setText(graphSelectedStringMAIN);
}

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(DefineEquation.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(DefineEquation.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(DefineEquation.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(DefineEquation.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new DefineEquation().setVisible(true);
        }

    });
}

// Variables declaration - do not modify                     
private javax.swing.JTextField selectedGraph;
// End of variables declaration                   
}

You will notice I tried to "extend" my first JFrame, but this resulted in the second JFrame "window" somehow combining with the first JFrame "window."

Conceptual images:

enter image description here

Edit 1: Is this the best way to go through with it? If so, how would I go about moving the data around? Objects are currently confusing me along with some non static and static problems which don't seem valid as I don't have anything static. If this is not the best way of doing it, what should I do? I'm going to bed, please comment with your suggestions and help, not only am I desperate, but I feel lost.

Edit 2: I am trying to work with what m.cekiera's answer was, refer to his answer before answering as it might be helpful.

Edit 3: Still stuck and talk in need of detailed help, sorry to be so demanding but I can't wrap my head around this.

Edit 4: I think I've found a significant breakthrough. I've figured out how to work around the issue, but I really think I need to understand this. Anyway, I've got a new class and a new text field for a different class. I still have the problem, I can't display a value of of the textfield, but for some reason I can output the same value. I guess it's easier shown

So this is the class SelectSolutionsQuadratic:

public void displayText(String textToSet) {
    displayQuadraticEquation.setText(textToSet);
    System.out.println(textToSet);
}

And this is DefineEquationQuadratic:

private void nextActionPerformed(java.awt.event.ActionEvent evt) {                                     
    this.setVisible(false);
    new SelectSolutionsQuadratic().setVisible(true);
    SelectSolutionsQuadratic transferMe = new SelectSolutionsQuadratic();
    transferData = aQuadraticSpinner.getValue().toString() + " " + addSubQuadraticComboBox.getSelectedItem(); 
    transferMe.displayText(transferData);
}                     

So basically I'm just confused why I can send a value from DefineEquationQuadratic to SelectSolutionsQuadratic, output it with System.out.println(); but NOT set the textfield to be that value

  • 1
    The DefineEquation JFrame shouldn't be a JFrame at all, but rather it should be a *modal* JDialog. This way program flow from the calling program freezes when the dialog is displayed, and only resumes after the dialog has been dealt with and is no longer visible. At that point you could call "getter" or "accessor" methods to get the data from the DefineEquations class. Please see a [similar question here](http://stackoverflow.com/questions/1481405/how-to-make-a-jframe-modal-in-swing-java). – Hovercraft Full Of Eels May 17 '15 at 16:05
  • Thanks for the reply! I don't think I want a _modal_ JDialog, I think I do want this window. I know it may seem weird but there is a link to my poorly hand drawn concept for what the window would look like: [link](http://i.imgur.com/oqBBFyF.png). I'm sure I could use a JDialog, you're probably right, and it probably would be more efficient, but I feel as if it may flow more smoothly like this. I guess feel free to cast your opinion, I'm not too sure anymore... – Matthew Alan Troutman May 17 '15 at 16:14
  • 1
    The problem is not transferring data from one object to another as that's usually trivial -- give one class a getter method and have the calling class call it when the first class's object has the needed data. The real problem is usually ***when*** to extract the data, and for that you need some type of notification system. Easiest here is to use a modal dialog, but if that's not adequate, then you're going to have to create your own observer/listener/notification system, which is do-able but more complicated. It's up to you though. – Hovercraft Full Of Eels May 17 '15 at 16:17
  • Here is my full windows concept [link](http://i.imgur.com/sOEjkEc.png). You're saying the problem is **when** to extract the data, would it be appropriate to use my _next_ button I have in the first window to extract/transmit the data? – Matthew Alan Troutman May 17 '15 at 16:20
  • 1
    Based on your images, I've changed my recommendation -- you really want to use a CardLayout to swap views. Please read: [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/questions/9554636/the-use-of-multiple-jframes-good-bad-practice). – Hovercraft Full Of Eels May 17 '15 at 16:23
  • 1
    You may be painting yourself in a corner by having your GUI classes extend JFrame, forcing you to create and display JFrames, when often more flexibility is called for. In fact, I would venture that most of the Swing GUI code that I've created and that I've seen does **not** extend JFrame, and in fact it is rare that you'll ever want to do this. More commonly your GUI classes will be geared towards creating JPanels, which can then be placed into JFrames or JDialogs, or JTabbedPanes, or swapped via **CardLayouts**, wherever needed. This will greatly increase the flexibility of your GUI coding. – Hovercraft Full Of Eels May 17 '15 at 16:25
  • Sorry. By default it seems to extend JFrame, but the design I am working on I _believe_ is using JPanels. I guess what I'm asking for now is what would you recommend? And also I guess how/when would I pass my JComboBox data to an appropriate text field? – Matthew Alan Troutman May 17 '15 at 16:28
  • 1
    The class that holds the JComboBox should have a getter method, one that gets the selected item in the JComboBox. Any class with a ***valid*** reference to the *displayed* JComboBox holding class can then call this method when needed, but of course only after the data is available, after the user has interacted with the JComboBox (hence we're back at the timing issue, the *when* to extract data issue). The timing will likely be due to an event such as a button's ActionListener. – Hovercraft Full Of Eels May 17 '15 at 16:32
  • So does this have anything to do with this `private void graphSelectionActionPerformed(java.awt.event.ActionEvent evt) { String graphSelectionGUI = (String)graphSelection.getSelectedItem(); graphSelectedTextField.setText(graphSelectionGUI); //DefineEquation graphSelectedObj = new DefineEquation(graphSelectionGUI); //graphSelectedObj.addItem(graphSelectionGUI);`? – Matthew Alan Troutman May 17 '15 at 16:33
  • Also I'd just like to point out, for some reason, when I make objects and try to do stuff with them, it gives me the non static can't be reference in static context, but nothing is static!? Does anybody know what's going on? I am so confused right now and I can't find any answers. – Matthew Alan Troutman May 17 '15 at 17:50
  • 1
    Maybe you trying to use these objects in `main` methods of your classes, which are static. Keep it in mind. Right now are you trying just to send data about selection to another class? I see you even create a constructor of `DefineEquation(String graphSelected)`; so why don't you use it? – m.cekiera May 17 '15 at 18:51

3 Answers3

3

What I'm suggesting is that you create two JPanel classes, one that holds your JComboBox, and the other that displays or otherwise needs the results. Assuming you've done that and called the first class, HoldsComboBoxPanel, and your second class is called ShowSelectionPanel, then you would give the HoldsComboBoxPanel two methods, one to get the current selection, a "getter" method, and another to allow outside classes to add an ActionListener to the combobox. For instance in brief, something like so:

public class HoldsComboBoxPanel extends JPanel {
   public static final String NAME = "holds combobox panel";
   // sample data
   private static final String[] DATA = { "Monday", "Tuesday", "Wednesday",
         "Thursday", "Friday" };
   private JComboBox<String> comboBox = new JComboBox<>(DATA);

   public HoldsComboBoxPanel() {
       // add the comboBox into our class here
   }

   // method to add a listener
   public void addComboBoxListener(ActionListener listener) {
      comboBox.addActionListener(listener);
   }

   // getter method
   public String getComboSelection() {
      return (String) comboBox.getSelectedItem();
   }

}

Your second class, the one that needs the data would have a setter method to allow outside classes the ability to push the combo selection into it. Assuming it had a JTextField called displayField that showed the selection, its code could look like so:

public class ShowSelectionPanel extends JPanel {
   public static final String NAME = "show selection panel";
   private JTextField displayField = new JTextField(10);

   public ShowSelectionPanel() {
      // add the displayField to the JPanel here
   }

   // setter method
   public void setDisplayText(String text) {
      displayField.setText(text);
      // or do whatever else you want to do with the selection
   }
}

Then you'd have another class that used CardLayout and that allowed swapping between the view JPanels above, say called MainPanel. It could use the CardLayout to allow you to swap JPanels, have a public method to allow outside classes to swap "card" JPanels, and it would hold both a HoldsComboBoxPanel field and a ShowSelectionPanel field, and could link them by adding the ActionListener to the combobox like so:

public class MainPanel extends JPanel {
   private CardLayout cardLayout = new CardLayout();
   private MenuPanel menuPanel = new MenuPanel();
   private HoldsComboBoxPanel holdsComboBoxPanel = new HoldsComboBoxPanel();
   private ShowSelectionPanel showSelectionPanel = new ShowSelectionPanel();

   public MainPanel() {
      // add an ActionListener to the JComboBox
      holdsComboBoxPanel.addComboBoxListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent e) {
            // get the combo's selected String
            String selection = holdsComboBoxPanel.getComboSelection();
            if (selection != null) {
               // push it into showSelection
               showSelectionPanel.setDisplayText(selection);
            }
         }
      });

      setLayout(cardLayout);
      add(menuPanel, MenuPanel.NAME);
      add(holdsComboBoxPanel, HoldsComboBoxPanel.NAME);
      add(showSelectionPanel, ShowSelectionPanel.NAME);
   }

   // method that allows outside classes to swap views
   public void showCard(String key) {
      cardLayout.show(this, key);
   }
}

The whole thing with some additional code to allow movement through the "cards" could look something like this:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class SimpleMultPanels {
   private static void createAndShowGui() {
      // create JFrame
      JFrame frame = new JFrame("SimpleMultPanels");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

      // add our MainPanel to the JFrame
      frame.getContentPane().add(new MainPanel());
      frame.pack(); // pack it
      frame.setLocationByPlatform(true);
      frame.setVisible(true); // show it
   }

   public static void main(String[] args) {
      // this is for starting our Swing app on the event thread
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

@SuppressWarnings("serial")
class MainPanel extends JPanel {
   private CardLayout cardLayout = new CardLayout();

   // the three "card" JPanels that this JPanel displays:
   private MenuPanel menuPanel = new MenuPanel();
   private HoldsComboBoxPanel holdsComboBoxPanel = new HoldsComboBoxPanel();
   private ShowSelectionPanel showSelectionPanel = new ShowSelectionPanel();

   // Actions for our JButtons
   private ExitAction exitAction = new ExitAction();
   private ShowAction backToMenuAction = new ShowAction(this, "Back to Menu",
         MenuPanel.NAME, KeyEvent.VK_B);
   private ShowAction toHoldsComboAction = new ShowAction(this, "Combo Panel",
         HoldsComboBoxPanel.NAME, KeyEvent.VK_C);
   private ShowAction toShowSelectionAction = new ShowAction(this,
         "Show Selection", ShowSelectionPanel.NAME, KeyEvent.VK_S);

   public MainPanel() {
      // add an ActionListener to the JComboBox
      holdsComboBoxPanel.addComboBoxListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent e) {
            // get the combo's selected String
            String selection = holdsComboBoxPanel.getComboSelection();
            if (selection != null) {
               // push it into showSelection
               showSelectionPanel.setDisplayText(selection);
            }
         }
      });

      // add Actions to class to allow swapping of cards and
      holdsComboBoxPanel.addButtonAction(backToMenuAction);
      holdsComboBoxPanel.addButtonAction(toShowSelectionAction);
      holdsComboBoxPanel.addButtonAction(exitAction); // and to exit gui

      showSelectionPanel.addButtonAction(backToMenuAction);
      showSelectionPanel.addButtonAction(toHoldsComboAction);
      showSelectionPanel.addButtonAction(exitAction);

      menuPanel.addButtonAction(toHoldsComboAction);
      menuPanel.addButtonAction(toShowSelectionAction);
      menuPanel.addButtonAction(exitAction);

      setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

      // set our layout
      setLayout(cardLayout);

      // and add our "card" JPanels
      add(menuPanel, MenuPanel.NAME);
      add(holdsComboBoxPanel, HoldsComboBoxPanel.NAME);
      add(showSelectionPanel, ShowSelectionPanel.NAME);
   }

   // method that allows outside classes to swap views
   public void showCard(String key) {
      cardLayout.show(this, key);
   }
}

@SuppressWarnings("serial")
class HoldsComboBoxPanel extends JPanel {
   // constant String that will be used by the CardLayout
   public static final String NAME = "holds combobox panel";

   // sample data
   private static final String[] DATA = { "Monday", "Tuesday", "Wednesday",
         "Thursday", "Friday" };
   private JComboBox<String> comboBox = new JComboBox<>(DATA);

   // JPanel to hold buttons to allow moving between cards
   private JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));

   public HoldsComboBoxPanel() {
      comboBox.setSelectedIndex(-1);
      JPanel centerPanel = new JPanel();
      centerPanel.add(comboBox);

      setLayout(new BorderLayout());
      add(centerPanel, BorderLayout.CENTER);
      add(buttonPanel, BorderLayout.SOUTH);
   }

   // method to add a listener
   public void addComboBoxListener(ActionListener listener) {
      comboBox.addActionListener(listener);
   }

   // getter method
   public String getComboSelection() {
      return (String) comboBox.getSelectedItem();
   }

   // create a new JButton with an Action and add to buttonPanel
   public void addButtonAction(Action action) {
      buttonPanel.add(new JButton(action));
   }
}

@SuppressWarnings("serial")
class ShowSelectionPanel extends JPanel {
   public static final String NAME = "show selection panel";
   private static final int PREF_W = 300;
   private static final int PREF_H = PREF_W;
   private JTextField displayField = new JTextField(10);
   private JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));

   public ShowSelectionPanel() {
      displayField.setFocusable(false);

      JPanel centerPanel = new JPanel();
      centerPanel.add(displayField);

      setLayout(new BorderLayout());
      add(centerPanel, BorderLayout.CENTER);
      add(buttonPanel, BorderLayout.SOUTH);
   }

   // code to make our GUI a little larger
   @Override
   public Dimension getPreferredSize() {
      Dimension superSz = super.getPreferredSize();
      if (isPreferredSizeSet()) {
         return superSz;
      }
      int prefW = Math.max(superSz.width, PREF_W);
      int prefH = Math.max(superSz.height, PREF_H);
      return new Dimension(prefW, prefH);
   }

   // setter method
   public void setDisplayText(String text) {
      displayField.setText(text);
      // or do whatever else you want to do with the selection
   }

   public void addButtonAction(Action action) {
      buttonPanel.add(new JButton(action));
   }

}

@SuppressWarnings("serial")
class MenuPanel extends JPanel {
   public static final String NAME = "menu panel";
   private JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 0, 5));

   public MenuPanel() {
      setLayout(new GridBagLayout());
      add(buttonPanel);
   }

   public void addButtonAction(Action action) {
      buttonPanel.add(new JButton(action));
   }
}

@SuppressWarnings("serial")
class ShowAction extends AbstractAction {
   private MainPanel mainPanel;
   private String key;

   /**
    * Abstract Action used by JButtons
    * @param mainPanel: the JPanel that uses the CardLayout
    * @param name: The name displayed by the button
    * @param key: The key used in the CardLayout#show(String key) mehtod
    * @param mnemonic: the JButton's mnemonic char
    */
   public ShowAction(MainPanel mainPanel, String name, String key, int mnemonic) {
      super(name);
      putValue(MNEMONIC_KEY, mnemonic);
      this.mainPanel = mainPanel;
      this.key = key;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      // tell the mainPanel to show the card associated with the key
      mainPanel.showCard(key);
   }
}

// class of mine to allow disposing of a window
// It's a little complex to allow it to work with either a JButton
// or a JMenuItem
@SuppressWarnings("serial")
class ExitAction extends AbstractAction {
   public ExitAction() {
      super("Exit");
      putValue(MNEMONIC_KEY, KeyEvent.VK_X);
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      // get the button that caused this action
      Object source = e.getSource();
      if (source instanceof AbstractButton) {
         AbstractButton exitButton = (AbstractButton) source;

         // get the parent top level window
         Window topWindow = SwingUtilities.getWindowAncestor(exitButton);
         if (topWindow == null) { // if null, then likely in a JMenuItem
            // so we have to get its jpopupmenu parent
            Container parent = exitButton.getParent();
            if (parent instanceof JPopupMenu) {
               JPopupMenu popupMenu = (JPopupMenu) parent;

               // get the invoker for the pop up menu
               Component invoker = popupMenu.getInvoker();
               if (invoker != null) {
                  // and get *its* top level window
                  topWindow = SwingUtilities.getWindowAncestor(invoker);
               }
            }
         }
         if (topWindow != null) {
            // dispose of the top-level window
            topWindow.dispose();
         }
      }
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Sorry, I meant to comment on your post but I had to go and forgot. I really do appreciate the work you put in, even typing out all of the code. I read through all of it and I've tried to understand it, and I'm sure it'll work. That being said, I'm doing this for a school project and I'm trying to stick to things that I know or are close to what I know, I'm trying to do it at a basic level first. Your code make sense to me, sort of, but it's not the way I was taught to go about with GUI things and such I'm leaving it as my backup option. Sorry, I'll try to run it now. – Matthew Alan Troutman May 19 '15 at 01:36
  • Thank you for your help, I've managed to fix the problem, I had two instances created and was viewing one whilst editing the other. Thank you so much for your time. – Matthew Alan Troutman May 21 '15 at 02:54
2

If you just wont to send data to DefineEquation class, you should use your constructor with String argument in nextActionPerformed:

    new DefineEquation((String)graphSelection.getSelectedItem()).setVisible(true);

instead of:

    new DefineEquation().setVisible(true);

Also you need to chenge you constructor to:

public DefineEquation(String graphSelected) {
    this.graphSelected = graphSelected;
    initComponents();
}

Because right now without initComponents() it will display empty frame. At last, you need to setText() to JTextField in DefineEquation class, for example by:

 selectedGraph = new javax.swing.JTextField(graphSelected);

Do not use addItem()method, or rewrite it, becouse it creates new DefineEquation object which is unnecessary an even harmful. This way in new frame it display JTextField with chosen text. It worked for me, at least if I understood your problem correctly.

However, I would rather use enums instead of plain String, as they are more reliable. Your function set is constant, so you can create for example:

public enum Functions {NONE,LINEAR,BILINEAR,QUADRIATIC,CUBIC,EXPONENTIAL;}

This will required change of constructor, and JComboBox content, but you would be able to use it in whole application. Tou can call toString() or name() where you need String to display, but use enums in event handling, etc. I think you should also reconsider your approach to multiple JFrames, as suggested in comments. I also would not recommend that, but it is up to you. Good luck!

EDIT

If you dont't want to change initComponents() in DefineEquation, you can still modify addItem() like this:

public void addItem(){
    selectedGraph.setText(graphSelected);
}

but then you call call addItem() in constructor, to fill your JTextField with chosen text. Or you can pass graphSelected as argument of method, if so it don't have to be a class field.

m.cekiera
  • 5,365
  • 5
  • 21
  • 35
  • Hey, thanks for your help! I feel like yours might be the closest to what I want right now. Just a quick question, where should I put the `selectedGraph = new javax.swing.JTextField(graphSelected);`? Having a bit of trouble. – Matthew Alan Troutman May 18 '15 at 00:05
  • 1
    instead of `selectedGraph = new javax.swing.JTextField();` in `initComponents()` method, or just add `selectedGraph.setText(graphSelected);` below that. – m.cekiera May 18 '15 at 02:15
  • Sorry your language wasn't really clear. Are you suggesting I add that code to the initiComponents method? If so, it says this `/** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */` So I'm not too sure what to do, could you perhaps be a little bit clearer? Sorry to trouble you, I appreciate all the help you've given me. – Matthew Alan Troutman May 18 '15 at 03:46
  • @MatthewAlanTroutman sorry for my english. Yes, this is what I suggested, but if you don't want to modify `initComponents()` there is also another way. Pleas check edit to my answer. – m.cekiera May 18 '15 at 20:08
  • Thank you for your help, I've managed to fix the problem, I had two instances created and was viewing one whilst editing the other. Thank you so much for your time. – Matthew Alan Troutman May 21 '15 at 02:54
-1

So I was really dumb and had two instances created, one of which I was not viewing and the other of which I was but was not changing. Basically what I did was in graphSelectionActionPerformed I did:

this.graphSelectionGUI = (String)graphSelection.getSelectedItem();

Then in nextActionPerformed I did:

new DefineEquation_1(graphSelectionGUI).setVisible(true);

Following this, in the other class (DefineEquation), I took my constructor and did this:

public DefineEquation(String graphSelected) {
    this.graphSelected = graphSelected;
    initComponents();
    selectedGraph.setText(graphSelected);
}

And lastly I cried with tears realising how much trouble I gave you guys and how dumb I was, praise the lord!

Sorry for troubling everyone, my bad.