简体   繁体   中英

JFrame either not displaying components or using multiple times actionListener in Java Swing

I work on a Swing application displaying different "sub"JFrames from a main JFrame. I have an issue on a specific "sub"JFrame called FrameStratigraphie.

For others "sub"JFrames when I am done with them I just dispose them and recreate them later if needed. But this one, when I dispose it and recreate it, the action listener triger X times and X is the number of times I created this frame.

Here is how I set my action listener :

        bouton.addActionListener(lambda -> dispose());

I am really new to lambda expressions so the issue could come from here.

I tried to work around by just setVisible(false) my FrameStratigraphie and try to [removeAll + revalidate + repaint] but if I open any other "sub"JFrame and then try to recreate it, the frame is just grey. Like no component is added to it. (But I can still see the correct FrameStratigraphie for 0.1 second before it is removeAll() ). I'd like to know why.

To summarize :

  • Why my actionListener method is triggered multiple times if I do JFrame.dispose()

  • Why nothing appear after setting my frame to visible(false)

This is my first post on stackoverflow and I am sorry if I have done any mistake on appearance, spelling or relevance and for my french comments in my code...

Thank you in advance for any information, track, advice, comment or answer related to my issue.

Stratigraphie.java



    package vue.forage.quart;

    import java.util.ArrayList;

    import javax.swing.JButton;
    import javax.swing.JLabel;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;

    import vue.AbstractFrame;
    import vue.AbstractFrame2;
    import vue.FrameStratigraphie;
    import vue.forage.Quart;

    public class Stratigraphie{

        /**
         * 
         */
        private static FrameStratigraphie frame;
        private static final long serialVersionUID = 1L;
        private static JTextField textField = new JTextField(5);
        private static JTextField textField2 = new JTextField(5);
        private static JTextField textField3 = new JTextField(10);
        private static JLabel label = new JLabel();
        private static JLabel label2 = new JLabel();
        private static JLabel label3 = new JLabel();
        private static JLabel label4 = new JLabel();
        private static JLabel label5 = new JLabel();
        private static JLabel label6 = new JLabel();
        private static JLabel label7 = new JLabel();
        private static JTextArea textArea = new JTextArea();
        private static JButton bouton = new JButton();
        private static String[] couchesPrecedentes = new String[3];
        private static ArrayList liste; 

        public Stratigraphie(FrameStratigraphie frameStratigraphie) {
            frame = frameStratigraphie;
            liste = Quart.getStrat();
            bouton.addActionListener(lambda -> dispose());
        }

        public void stratigraphie() {
            getInit();
            frame.getContentPane().removeAll();
            frame.setTitle("Stratigraphie");

            if (couchesPrecedentes != null) {
                frame.setLabel(0, 0, couchesPrecedentes[0], label4); //recupere la valeur finale de la derniere couche
                frame.setLabel(1, 0, couchesPrecedentes[1], label5);
                frame.setLabel(2, 0, couchesPrecedentes[2], label6);
            }
            frame.setLabel(0, 1, "Profondeur initiale", label);
            frame.setLabel(1, 1, "Profondeur finale", label2);
            frame.setTextAreaAsLabel(2, 1, "Description stratigraphique", textArea);
            if(liste.size() > 0)
                frame.setLabel(0, 2, Integer.toString(liste.get(liste.size()-1).getFinale()), label7);
            else
                frame.setTextField(0, 2, "", textField);
            frame.setTextField(1, 2, "", textField2);
            frame.setTextField(2, 2, "", textField3);
            frame.setBouton("Retour", 0, 3, bouton);

            frame.getContentPane().revalidate();
            frame.getContentPane().repaint();
        }

        public static void getInit()//Sorry, in this function I use html
     //tags in order to format my JLabel so everything do not appear on stack
    // overflow because I am bad with HTML. But I do not think this function
    // contain anything important for my issue.
        {
            couchesPrecedentes[0] = "";
            couchesPrecedentes[1] = "";
            couchesPrecedentes[2] = "";
            for (int i = 0; i " + Integer.toString(liste.get(i).getInitiale());
                    couchesPrecedentes[1] += "
" + Integer.toString(liste.get(i).getFinale()); couchesPrecedentes[2] += "
" + liste.get(i).getDescription(); } } couchesPrecedentes[0] += ""; couchesPrecedentes[1] += ""; couchesPrecedentes[2] += ""; } public void dispose() { System.out.println("on a un dispose"); Strate strate = null; if(liste.size() > 0) strate = new Strate(Integer.parseInt(label7.getText()), Integer.parseInt(textField2.getText()),textField3.getText()); else strate = new Strate(Integer.parseInt(textField.getText()), Integer.parseInt(textField2.getText()),textField3.getText()); Quart.addStrate(strate); frame.setVisible(false); // frame.dispose(); Quart.visible(true); } public static void visible(boolean bool) { frame.setVisible(bool); } }

How I start my FrameStratigraphie



        private static void ouvreStratigraphie(){
    //      if(frameStratigraphique == null)
                frameStratigraphique = new FrameStratigraphie();
    //      else{
    //          frameStratigraphique.getStratigraphie().stratigraphie();
    //          frameStratigraphique.setVisible(true);
    //      }
            frame.setVisible(false);
        }

FrameStratigraphie



    package vue;

    import vue.forage.quart.Stratigraphie;

    public class FrameStratigraphie extends AbstractFrame2 {

        private Stratigraphie stratigraphie = new Stratigraphie(this);
        public FrameStratigraphie() {
            super();
            stratigraphie.stratigraphie();
        }

        public Stratigraphie getStratigraphie()
        {
            return stratigraphie;
        }
    }

AbstractFrame2



    package vue;

    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Panel;

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextArea;

    import model.personnel.Personne;
    //frame secondaire dont héritent les JFrame secondaires (FrameCommentaire etc..)

    public abstract class AbstractFrame2 extends AbstractFrame{

        private static final long serialVersionUID = 1L;

        public AbstractFrame2() {
            super(new JPanel(new GridBagLayout()),new GridBagConstraints());
            dimension = Frame.initDimension();
            this.setSize(dimension[0], dimension[1]);
            this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            this.setLocationRelativeTo(null);
            this.setContentPane(pan);
            this.setVisible(true);
            c.weightx = 1;
        }
    }

AbstractFrame



    package vue;

    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Panel;
    import java.awt.TextArea;
    import java.awt.Toolkit;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.nio.charset.StandardCharsets;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.util.Date;
    import java.util.stream.Stream;

    import javax.imageio.ImageIO;
    import javax.swing.DefaultComboBoxModel;
    import javax.swing.Icon;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JPasswordField;
    import javax.swing.JSpinner;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    import javax.swing.JSpinner.DateEditor;

    //modele de frame qui regroupe toutes les methodes de placement de composants

    public abstract class AbstractFrame extends JFrame {

        protected static int[] dimension;
        protected static JPanel pan;
        protected static GridBagConstraints c;
        protected static BufferedImage bufferedImage;

        public AbstractFrame(JPanel panel, GridBagConstraints g)
        {
            pan = panel;
            c = g;
        }

        public static int[] initDimension() {
            Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
            int[] dim = new int[2];
            dim[1] = (int) dimension.getHeight() / 2;
            dim[0] = (int) dimension.getWidth() / 2;
            return dim;
        }

        public void setTime(int x, int y, JSpinner spinner, DateEditor timeEdit){
            spinner.setEditor(timeEdit);
            spinner.setValue(new Date());
            c.gridx = x;
            c.gridy = y;
            pan.add(spinner, c);
        }

        public void setLabel(int x, int y, String text, JLabel component) {
            c.gridx = x;
            c.gridy = y;
            component.setText(text);
            pan.add(component, c);
        }

        public void setTextAreaAsLabel(int x, int y, String text, JTextArea component){
            component.setText(text);
            component.setFont(new Font("Serif", Font.ITALIC, 16));
            component.setLineWrap(true);
            component.setWrapStyleWord(true);
            component.setOpaque(false);
            component.setEditable(false);
        }

        public void setImageLabel(int x, int y, String chemin, JLabel component) {
            component.removeAll();
            c.gridx = x;
            c.gridy = y;
            c.weightx = 1;
            c.gridwidth = GridBagConstraints.REMAINDER;
            try {
                bufferedImage = ImageIO.read(new File(chemin));
            } catch (IOException e) {
                System.out.println("ERREUR setImageLabel chemin " + chemin);
                e.printStackTrace();
            }
            Icon icon = new ImageIcon(bufferedImage);
            component.setIcon(icon);
            pan.add(component, c);
            c.gridwidth = 1;
        }

        public void setBouton(String text, int x, int y, JButton bouton) {
            bouton.setText(text);
            c.gridx = x;
            c.gridy = y;
            pan.add(bouton, c);
        }

        public void setTextField(int x, int y, String text, JTextField component) {
            c.gridx = x;
            c.gridy = y;
            component.setText(text);
            pan.add(component, c);
        };

        public void setPasswordField(int x, int y, JPasswordField component) {
            c.gridx = x;
            c.gridy = y;
            pan.add(component, c);
        }

        public void setTextArea(int x, int y, String text, TextArea component) {
            c.gridx = x;
            c.gridy = y;
            component.setText(text);
            pan.add(component, c);
        }

        public void setComboBox(int x, int y, String chemin, JComboBox combo) {
            Stream streamString = null;
            try {
                streamString = Files.lines(Paths.get(chemin), StandardCharsets.UTF_8);
            } catch (IOException e) {
                System.out.println("setComboBox " + chemin);
                e.printStackTrace();
            }
            String[] choix = streamString.toArray(size -> new String[size]);
            DefaultComboBoxModel model = (DefaultComboBoxModel) combo.getModel();
            model.removeAllElements();
            for (String s : choix) {
                model.addElement(s);
            }
            c.gridx = x;
            c.gridy = y;
            pan.add(combo, c);
        }

        public void setComboBoxString(int x, int y, String[] text, JComboBox combo){
            ((DefaultComboBoxModel)combo.getModel()).removeAllElements();
            for(int i = 0; i )combo.getModel()).addElement(text[i]);
            }
            c.gridx = x;
            c.gridy = y;
            pan.add(combo, c);
        }

        public void setTextArea(String text, int x, int y, JTextArea bouton) {
            bouton.setText(text);
            bouton.setMaximumSize(getPreferredSize());
            c.gridx = x;
            c.gridy = y;
            pan.add(bouton, c);
        }


    }

Every time you create a new Stratagraphie you invoke:

bouton.addActionListener(lambda -> dispose());

All the variables in your Stratagraphie class are static, which means they don't get recreated every time a new instance is created, so you continually keep adding a new ActionListener to the button.

Get rid of all the static variables!!!

Check out examples from the Swing tutorial on creating frames and variables used by the class. The TextDemo from How to Use Text Areas has a simple xample.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM