Search code examples
javaswingjpanelupdatepanel

Java JPanel object updated but update not visible on the screen


I am quite new to GUI programming and I don't know how to update an object and show the change on the screen. I have a class Sudoku which extends JPanel. I have a JFrame and the sudoku is part of it. I have a button, which calls the function openFile. Here is how it is called:

private void openFileActionPerformed(java.awt.event.ActionEvent evt) {                                         
    sudoku = FileManagement.openFile(this, sudoku);
}

The sudoku object has a 9x9 grid and when I debug it it's okay, the new values are in the grid. But I don't know how to display the new values on the screen. I read a few comments and tried sudoku.validate(), sudoku.repaint() or just packing the JFrame again but it didn't work. So I would appreciate if someone tells me how to fix it. If my explanation is insufficient or unclear, please tell me what else to add in the description. Thanks!

Edit - added code:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import javax.swing.JFileChooser;
import javax.swing.JFrame;

public class Sample extends javax.swing.JFrame {
    public Sample() {
        initComponents();
    }

    private void initComponents() {
        sudoku = new sudoku.Sudoku();
        openFile = new javax.swing.JButton();

        openFile.setText("Open");
        openFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openFileActionPerformed(evt);
            }
        });
        /*sorry for that part - automaticlly generated, don't know how to make it less*/
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(sudoku)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(openFile)))));
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(sudoku)
                .addComponent(openFile)));
        pack();
    }                     

    private void openFileActionPerformed(java.awt.event.ActionEvent evt) {                                         
        sudoku = openFile(this, sudoku);
    }                                        

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Sample().setVisible(true);
            }
        });
    }

    private javax.swing.JButton openFile;
    private sudoku.Sudoku sudoku;                  

    public static Sudoku openFile(JFrame frame, Sudoku sudoku) {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int result = fileChooser.showOpenDialog(frame);
        if (result == JFileChooser.CANCEL_OPTION) {
            return sudoku;
        }

        File fileName = fileChooser.getSelectedFile();

        try (ObjectInputStream input = new ObjectInputStream(new FileInputStream(fileName))) {
            sudoku = (Sudoku) input.readObject();
        } catch (IOException | ClassNotFoundException ioException) {
            System.out.println(ioException);
        }
        return sudoku;
    }
}

Solution

  • A quick fix for the problem would be to remove the JPanel from the JFrame, change its value, and then re-add the JPanel to the JFrame. This can be seen in the example below.

    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    
    @SuppressWarnings("serial")
    public class PanelFix extends JFrame {
        JFrame frame = this;
        private JPanel view = a();
    
        PanelFix() {
            super("Panel Fix");
            setSize(400, 400);
            setLocationRelativeTo(null);
            getContentPane().add(view);
            setVisible(true);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    
        private JPanel a() {
            JPanel panel = new JPanel();
            JButton but = new JButton("Press Me");
            but.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    getContentPane().remove(view);
                    view = b();
                    getContentPane().add(view);
                    repaint();
                    validate();
                }
            });
            panel.add(but);
            return panel;
        }
    
        private JPanel b() {
            JPanel panel = new JPanel();
            panel.add(new JLabel("Second Panel"));
            return panel;
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(() -> new PanelFix());
        }
    }
    

    If this does not fix the problem, like Andrew Thompson said, add an MCVE. This should allow us to help fix the exact problem you have