Home > database >  Updating JPanel with Label Texts
Updating JPanel with Label Texts

Time:01-22

I am working on an app which will get info from the user through the buttons and text frames in the MyPanel class. I want to display the courses-infos the user entered in the DisplayTable panel. I want it to update each time the add course button in the MyPanel class is pressed. I tried calling the setLabelText method from the MyPanel class, and what the actual function is supposed to do is update the panel and display the text for each element in the passed lists when the button is clicked, But still could not update. Could you tell me how can I update the DisplayPanel's infoLabel text each time the addCourseButton is pressed?

enter image description here

Class Main

public class Main {
    //TODO
    // PREVENT TYPE MISMATCH IN TEXT FIELDS
    // DISPLAY A TABLE OF COURSE NAMES - COURSE CREDITS - COURSE NAME AND THE GPA
    // CLEAN UP
    public static void main(String[] args) {
        new MyFrame();
    }
}

Class MyFrame

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MyFrame extends JFrame{

    MainPanel mainPanel;

    MyFrame(){
        mainPanel = new MainPanel();

        this.add(mainPanel);
        this.setTitle("GPA Calculator");
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(500,500);
        this.pack();
        this.setLocationRelativeTo(null);

        this.setVisible(true);
    }

}

Class MainPanel

import javax.swing.*;

public class MainPanel extends JPanel {

    DisplayPanel displayPanel = new DisplayPanel();
    MyPanel myPanel = new MyPanel(displayPanel);

    MainPanel() {
        this.add(myPanel);
        this.add(displayPanel);
    }
}

Class MyPanel

import javax.swing.*;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;

public class MyPanel extends JPanel implements ActionListener{

    ArrayList<String> courseNames;
    ArrayList<Integer> courseCredits;
    ArrayList<Double> courseGrades;
    Thread thread;
    JLabel nameLabel;
    JLabel creditLabel;
    JLabel gradeLabel;
    JTextField nameField;
    JTextField creditField;
    JTextField gradeField;
    JButton calculateButton;
    JButton addCourseButton;
    JButton resetButton;
    JLabel message;

    DisplayPanel displayPanel;

    double result = 0;
    int tempInt = 0;
    double tempDouble = 0;

    MyPanel(DisplayPanel displayPanel) {

        this.displayPanel = new DisplayPanel();

        message = new JLabel();
        message.setHorizontalAlignment(JLabel.CENTER);
        message.setFont(new Font("Helvetica Neue", Font.PLAIN, 35));
        message.setForeground(new Color(0xA1683A));
        message.setAlignmentX(JLabel.CENTER_ALIGNMENT);

        courseNames = new ArrayList();
        courseCredits = new ArrayList();
        courseGrades = new ArrayList();

        nameLabel = new JLabel();
        nameLabel.setHorizontalAlignment(JLabel.CENTER);
        nameLabel.setText("Course Name");
        nameLabel.setFont(new Font("Helvetica Neue", Font.PLAIN, 25));
        nameLabel.setForeground(new Color(0xA1683A));
        nameLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);

        nameField = new JTextField();
        nameField.setPreferredSize(new Dimension(300,30));
        nameField.setMaximumSize(nameField.getPreferredSize());

        creditLabel = new JLabel();
        creditLabel.setHorizontalAlignment(JLabel.CENTER);
        creditLabel.setText("Course Credits(ECTS)");
        creditLabel.setFont(new Font("Helvetica Neue", Font.PLAIN, 25));
        creditLabel.setForeground(new Color(0xA1683A));
        creditLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);

        creditField = new JTextField();
        creditField.setPreferredSize(new Dimension(300,30));
        creditField.setMaximumSize(creditField.getPreferredSize());

        gradeLabel = new JLabel();
        gradeLabel.setHorizontalAlignment(JLabel.CENTER);
        gradeLabel.setText("Your Grade");
        gradeLabel.setFont(new Font("Helvetica Neue", Font.PLAIN, 25));
        gradeLabel.setForeground(new Color(0xA1683A));
        gradeLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);

        gradeField = new JTextField();
        gradeField.setPreferredSize(new Dimension(300,30));
        gradeField.setMaximumSize(gradeField.getPreferredSize());


        resetButton = new JButton("Reset");
        resetButton.setAlignmentX(JLabel.CENTER_ALIGNMENT);
        resetButton.addActionListener(this);
        addCourseButton = new JButton("Add Course");
        addCourseButton.setAlignmentX(JLabel.CENTER_ALIGNMENT);
        addCourseButton.addActionListener(this);
        calculateButton = new JButton("Calculate GPA");
        calculateButton.setAlignmentX(JLabel.CENTER_ALIGNMENT);
        calculateButton.addActionListener(this);

        //spacing and adding the elements
        this.add(Box.createRigidArea(new Dimension(0,20)));
        this.add(nameLabel);
        this.add(Box.createRigidArea(new Dimension(0,10)));
        this.add(nameField);
        this.add(Box.createRigidArea(new Dimension(0,20)));
        this.add(creditLabel);
        this.add(Box.createRigidArea(new Dimension(0,10)));
        this.add(creditField);
        this.add(Box.createRigidArea(new Dimension(0,20)));
        this.add(gradeLabel);
        this.add(Box.createRigidArea(new Dimension(0,10)));
        this.add(gradeField);
        this.add(Box.createRigidArea(new Dimension(0,20)));
        this.add(addCourseButton);
        this.add(Box.createRigidArea(new Dimension(0,5)));
        this.add(calculateButton);
        this.add(Box.createRigidArea(new Dimension(0,5)));
        this.add(resetButton);
        this.add(Box.createRigidArea(new Dimension(0,30)));
        this.add(message);

        this.setPreferredSize(new Dimension(500, 500));
        this.setBackground(new Color(0xEED2CC));
        this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
    }

    //calculate the GPA
    public double calculateGPA(){
        for (Integer courseCredit : courseCredits) {
            tempInt  = courseCredit;
        }
        for(int i = 0; i<courseGrades.size();i  ){
            tempDouble  = courseGrades.get(i) * courseCredits.get(i);
        }
        return tempDouble/tempInt;
    }

    @Override
    public void actionPerformed(ActionEvent e) throws NumberFormatException {

        if(e.getSource().equals(addCourseButton)){

            //add items from the textFields to lists
            String tempText = nameField.getText();
            int tempCredit = Integer.parseInt(creditField.getText());
            double tempGrade = Double.parseDouble(gradeField.getText());
            courseNames.add(tempText);
            courseCredits.add(tempCredit);
            courseGrades.add(tempGrade);

            //set textFields to empty
            nameField.setText("");
            creditField.setText("");
            gradeField.setText("");

            //display a message for 3 seconds
            thread = new Thread();
            thread.start();
            message.setText("Course Added Successfully!");
            Timer timer = new Timer(3000, a -> message.setText(null));
            timer.setRepeats(false);
            timer.start();

            //add to table panel
            displayPanel.setLabelText(courseNames,courseCredits,courseGrades);
            //displayPanel.update();

        }

        //calculate the GPA, initialize the display panel
        //to display the courses names-credits-results and the gpa
        //as a table
        if(e.getSource().equals(calculateButton)){
            result = calculateGPA();
            message.setText(result   "");
        }

        //clear the lists,text fields and the message
        //get rid of the table panel
        if(e.getSource().equals(resetButton)){
            courseNames.clear();
            courseGrades.clear();
            courseCredits.clear();
            tempDouble = 0;
            tempInt = 0;
            displayPanel.removeAll();
            displayPanel.repaint();
            nameField.setText("");
            creditField.setText("");
            gradeField.setText("");
            message.setText(null);
        }
    }
}

Class DisplayPanel

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

public class DisplayPanel extends JPanel {

    JLabel infoLabel;

    public DisplayPanel() {

        this.setPreferredSize(new Dimension(500, 500));
        this.setBackground(new Color(0xEED2CC));
        this.setLayout(null);

        infoLabel = new JLabel();
        infoLabel.setHorizontalAlignment(JLabel.LEFT);
        infoLabel.setFont(new Font("Helvetica Neue", Font.PLAIN, 35));
        infoLabel.setForeground(new Color(0xA1683A));
        infoLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
        infoLabel.setBackground(Color.RED);
        infoLabel.setOpaque(true);


        this.add(infoLabel);
    }


    public void setLabelText(ArrayList<String> courseNames, ArrayList<Integer> courseCredits, ArrayList<Double> courseGrades) {

        this.removeAll();
        this.add(infoLabel);
        this.repaint();
        this.revalidate();

        for (String name : courseNames) {
            infoLabel.setText(name   "\t"   courseCredits.get(courseNames.indexOf(name))   "\t"   courseGrades.get(courseNames.indexOf(name)));
        }

        infoLabel.setOpaque(true);

    }
}

CodePudding user response:

You're creating two DisplayPanels, adding one to the GUI and trying to change the state of the other non-displayed DisplayPanel.

class MainPanel extends JPanel {

    DisplayPanel displayPanel = new DisplayPanel(); // *** HERE ***
    MyPanel myPanel = new MyPanel(displayPanel); 

    MainPanel() {
        this.add(myPanel);
        this.add(displayPanel);
    }
}
public class MyPanel extends JPanel implements ActionListener {

    // ....

    DisplayPanel displayPanel;

    // ...

    MyPanel(DisplayPanel displayPanel) {

        this.displayPanel = new DisplayPanel();   // *** and HERE ***

        // ...
    }

    // ...
}

And in fact, in the MainPanel, you are trying to add your DisplayPanel object to two different containers, which is not legal in Swing, and only the second add method will count.

Suggestions:

  • Create one and only one component, add it and change its state when needed.
  • Use a JList or better a JTable to display the data.
  • Avoid null layouts and setBounds and instead use the layout managers. Check out the layout manager tutorial here: Layout manager tutorial here: Layout Manager Tutorial
  • Avoid parallel arrays or ArrayLists. Instead create a class to hold a row of data, and a single ArrayList of this type that you fill-up.
  • Focus first on getting your GUI working, and secondarily making it pretty and such. In other words, make sure things work and display before worrying about fonts, colors, and such.

e.g.,

public class CourseInfo {
    private String name;
    private int credits;
    private double grades;

    public CourseInfo(String name, int credits, double grades) {
        this.name = name;
        this.credits = credits;
        this.grades = grades;
    }

    public String getName() {
        return name;
    }

    public int getCredits() {
        return credits;
    }

    public double getGrades() {
        return grades;
    }

}

and

List<CourseInfo> courseInfoList = new ArrayList<>();

CodePudding user response:

I will concentrate on fixing your immediate problem, i.e. displaying text in the infoLabel in class DisplayPanel.

You have three problems. The first is in the constructor of class MyPanel.

MyPanel(DisplayPanel displayPanel) {
    this.displayPanel = new DisplayPanel();

You are ignoring the constructor parameter and creating a new instance of DisplayPanel. Hence member displayPanel of class MyPanel is not the same object that you created in class MainPanel. So you are calling methods on a DisplayPanel that was not added to MainPanel. You need to change that line to the following.

MyPanel(DisplayPanel displayPanel) {
    this.displayPanel = displayPanel;

The second problem is that you set a null layout in DisplayPanel. When there is no layout manager you need to explicitly set the bounds of any components you add to the JPanel. You aren't doing that and hence your JLabel is not displayed. Simply remove this line from the constructor of DisplayPanel

this.setLayout(null);

Finally, in method setLabelText, of class DisplayPanel, you only need to change the JLabel text, via method setText. No need to remove all the components and add them again. The method should be as follows.

public void setLabelText(ArrayList<String> courseNames, ArrayList<Integer> courseCredits, ArrayList<Double> courseGrades) {
    StringBuilder sb = new StringBuilder();
    for (String name : courseNames) {
        sb.append(name   "\t"   courseCredits.get(courseNames.indexOf(name))   "\t"   courseGrades.get(courseNames.indexOf(name)));
    }
    infoLabel.setText(sb.toString());
}

Edit

If I were tasked with making this application, I would do it something like the following.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.text.ParseException;

import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.MaskFormatter;

public class GpaCalcs implements Runnable {
    private DefaultTableModel  tableModel;
    private JFormattedTextField  courseCreditsTextField;
    private JFormattedTextField  gradeTextField;
    private JFrame  frame;
    private JTable  table;
    private JTextField  courseNameTextField;

    public void run() {
        try {
            createAndDisplayGui();
        }
        catch (Exception x) {
            throw new RuntimeException(x);
        }
    }

    private void addCourse(ActionEvent event) {
        Object[] row = new Object[3];
        row[0] = courseNameTextField.getText();
        row[1] = courseCreditsTextField.getValue();
        row[2] = gradeTextField.getValue();
        tableModel.addRow(row);
    }

    private void createAndDisplayGui() throws ParseException {
        frame = new JFrame("GPA Calculator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(createMainPanel(), BorderLayout.CENTER);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private void createButtonsPanel(JPanel formPanel, GridBagConstraints gbc) {
        JPanel buttonsPanel = new JPanel();
        JButton addCourseButton = new JButton("Add Course");
        addCourseButton.addActionListener(this::addCourse);
        buttonsPanel.add(addCourseButton);
        JButton calcGpaButton = new JButton("Calculate GPA");
        buttonsPanel.add(calcGpaButton);
        JButton resetButton = new JButton("Reset");
        resetButton.addActionListener(this::reset);
        buttonsPanel.add(resetButton);
        gbc.gridwidth = 3;
        formPanel.add(buttonsPanel, gbc);
    }

    private JScrollPane createDisplayPanel() {
        String[] columns = new String[]{"Course", "Credits", "Grade"};
        tableModel = new DefaultTableModel(columns, 0);
        table = new JTable(tableModel);
        JScrollPane scrollPane = new JScrollPane(table);
        return scrollPane;
    }

    private JPanel createFormPanel() throws ParseException {
        JPanel formPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.LINE_START;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets.bottom = 5;
        gbc.insets.left = 5;
        gbc.insets.right = 5;
        gbc.insets.top = 5;
        JLabel courseNameLabel = new JLabel("Course Name");
        formPanel.add(courseNameLabel, gbc);
        gbc.gridx = 1;
        courseNameTextField = new JTextField(10);
        formPanel.add(courseNameTextField, gbc);
        gbc.gridx = 0;
        gbc.gridy = 1;
        JLabel courseCreditLabel = new JLabel("Course Credits (ECTS)");
        formPanel.add(courseCreditLabel, gbc);
        gbc.gridx = 1;
        MaskFormatter formatter = new MaskFormatter("####"); // throws java.text.ParseException
        courseCreditsTextField = new JFormattedTextField(formatter);
        courseCreditsTextField.setColumns(10);
        formPanel.add(courseCreditsTextField, gbc);
        gbc.gridx = 0;
        gbc.gridy = 2;
        JLabel gradeLabel = new JLabel("Your Grade");
        formPanel.add(gradeLabel, gbc);
        gbc.gridx = 1;
        formatter = new MaskFormatter("#.##");
        gradeTextField = new JFormattedTextField(formatter);
        gradeTextField.setColumns(10);
        formPanel.add(gradeTextField, gbc);
        gbc.gridx = 0;
        gbc.gridy = 3;
        createButtonsPanel(formPanel, gbc);
        return formPanel;
    }

    private JPanel createMainPanel() throws ParseException {
        JPanel mainPanel = new JPanel(new GridLayout(0, 2));
        mainPanel.add(createFormPanel());
        mainPanel.add(createDisplayPanel());
        return mainPanel;
    }

    private void reset(ActionEvent event) {
        courseNameTextField.setText("");
        courseCreditsTextField.setText("");
        gradeTextField.setText("");
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new GpaCalcs());
    }
}
  •  Tags:  
  • Related