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

时间:2016-06-13 15:29:08

标签: java swing

我在Swing应用程序上工作,显示来自主JFrame的不同" sub" JFrame。 我在一个名为FrameStratigraphie的特定" sub" JFrame上遇到了问题。

对于其他人" sub" JFrames,当我完成它们时,我只需处理它们并在以后需要时重新创建它们。但是这个,当我处理它并重新创建它时,动作侦听器会跳过X次,X就是我创建这个帧的次数。

以下是我设置动作监听器的方法:

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

我是lambda表达式的新手,所以问题可能来自这里。

我尝试通过setVisible(false)我的FrameStratigraphie来解决这个问题并尝试[removeAll + revalidate + repaint]但是如果我打开任何其他" sub" JFrame然后尝试重新创建它,那么框架只是灰色。就像没有添加任何组件一样。 (但是在removeAll()之前我仍然可以看到正确的FrameStratigraphie 0.1秒。我想知道原因。

总结:

  • 如果我执行JFrame.dispose()

  • ,为什么我的actionListener方法被多次触发
  • 将我的框架设置为可见(false)后,为什么没有显示

这是我关于stackoverflow的第一篇文章,如果我在外观,拼写或相关性方面有任何错误,并且在我的代码中发表法语评论,我很抱歉......

提前感谢您提供与我的问题相关的任何信息,跟踪,建议,评论或答案。

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); } }

我如何启动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);
        }


    }

1 个答案:

答案 0 :(得分:2)

每次创建新的Stratagraphie时,都会调用:

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

Stratagraphie类中的所有变量都是静态的,这意味着每次创建新实例时都不会重新创建它们,因此您不断向该按钮添加新的ActionListener。

摆脱所有静态变量!!!

查看Swing教程中有关创建类使用的框架和变量的示例。来自How to Use Text AreasTextDemo有一个简单的例子。