简体   繁体   English

JFrame不显示组件或在Java Swing中多次使用actionListener

[英]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. 我在一个Swing应用程序上工作,它显示了与主JFrame不同的“ sub” JFrame。 I have an issue on a specific "sub"JFrame called FrameStratigraphie. 我在一个称为FrameStratigraphie的特定“子” JFrame上有问题。

For others "sub"JFrames when I am done with them I just dispose them and recreate them later if needed. 对于其他“ sub” JFrame,当我处理完它们之后,我就将它们放置起来,然后在需要时重新创建它们。 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. 但是,这一次,当我处理它并重新创建它时,动作侦听器触发X次,而X是创建此框架的次数。

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. 我对lambda表达式真的很陌生,所以问题可能出在这里。

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. 我试图通过setVisible(false)来解决我的FrameStratigraphie问题,并尝试[removeAll + revalidate + repaint],但是如果我打开任何其他“ sub” JFrame然后尝试重新创建它,则该框架只是灰色的。 Like no component is added to it. 就像没有添加任何组件。 (But I can still see the correct FrameStratigraphie for 0.1 second before it is removeAll() ). (但是在removeAll()之前,我仍然可以在0.1秒内看到正确的FrameStratigraphie)。 I'd like to know why. 我想知道为什么。

To summarize : 总结一下:

  • Why my actionListener method is triggered multiple times if I do JFrame.dispose() 为什么我执行JFrame.dispose()会多次触发我的actionListener方法

  • Why nothing appear after setting my frame to visible(false) 为什么将我的框架设置为可见后什么也没出现(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... 这是我关于stackoverflow的第一篇文章,如果我在外观,拼写或相关性方面有任何错误,并且在我的代码中有我的法语注释,我也感到抱歉。

Thank you in advance for any information, track, advice, comment or answer related to my issue. 预先感谢您提供与我的问题有关的任何信息,追踪,建议,评论或答案。

Stratigraphie.java 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 我如何开始我的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 抽象框架2



    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. Stratagraphie类中的所有变量都是静态的,这意味着不会在每次创建新实例时都重新创建它们,因此您将不断向按钮添加新的ActionListener。

Get rid of all the static variables!!! 摆脱所有静态变量!!!

Check out examples from the Swing tutorial on creating frames and variables used by the class. 查看Swing教程中有关创建类使用的框架和变量的示例。 The TextDemo from How to Use Text Areas has a simple xample. 如何使用文本区域中TextDemo有一个简单的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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