In a java Jframe can I add/remove a Jlabel from view using a checkbox?

穿精又带淫゛_ 提交于 2020-01-03 03:11:44

问题


Im making an application that lets me perform hashes, at the top I want to have a group of check boxes basically saying the four different hash types I have. When the check boxes are selected I want the labels to appear showing the hashed entered text.

I've attached an image to hopefully make it easier to understand what I mean. The reason I'm doing this is so that when the final program is made with almost 10 rows of text boxes and labels it can be reduced only to show the ones that the user wishes to see.This hopefully should explain what I mean.

I've been able to get it so the checkboxes make it visible or not visible but that also then just leaves a blank space where one row of labels used to be rather than moving everything up a row

I've now added my coding so people can see how I'm doing it currently and help define where needs to be modified

import java.awt.*;
import java.awt.event.*;
import java.security.*;
import javax.swing.*;

public class Hasher extends JFrame implements ActionListener {
    String UserInput;
    private JTextField textInputField;
    private static JLabel MD5Hashed,MD5Label;
    private static JCheckBox MD5Check, SHA1Check, SHA256Check, FileCheck;
    private JFrame contentPane;

public Hasher() {
    this.setTitle("Hasher");
    Container contentPane = this.getContentPane();
    contentPane.setLayout(new GridLayout(0,1) );
    contentPane.setBackground(new Color(88,148,202));

    //CheckBoxes
        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());
        JPanel checkBoxPanel = new JPanel();
        MD5Check = new JCheckBox("MD5");
        MD5Check.addActionListener(new ActionListener() {
@Override
            public void actionPerformed(ActionEvent e) {
    boolean Visible = MD5Check.isSelected();
    MD5Hashed.setVisible(Visible);
    MD5Label.setVisible(Visible);
            }
        });
        checkBoxPanel.add(MD5Check);
        SHA1Check = new JCheckBox("SHA-1");
        checkBoxPanel.add(SHA1Check);
        SHA256Check = new JCheckBox("SHA-256");
        checkBoxPanel.add(SHA256Check);
        FileCheck = new JCheckBox("File Hashing");
        checkBoxPanel.add(FileCheck);
        mainPanel.add(checkBoxPanel);
        contentPane.add(mainPanel);


//Entered data to perform hash on
    contentPane.add(new JLabel ("   Enter text to hash"));
    textInputField = new JTextField();
    //HashingProcess inputListener = new HashingProcess( );
    //textInputField.addActionListener(inputListener);
    contentPane.add( textInputField);

//MD5 hash is completed 
    MD5Label = new JLabel( "   Using MD5 the hash is: " );
    contentPane.add( MD5Label);
    MD5Hashed = new JLabel( "??") ;
    contentPane.add( MD5Hashed );
    MD5Hashed.setVisible(false);
    MD5Label.setVisible(false);

}

public static void main(String[] args) {
    Hasher theWindow = new Hasher( );
    theWindow.setSize(400, 400 );
    theWindow.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    theWindow.setVisible(true);

}

}

回答1:


You have two frames...

public class Hasher extends JFrame implements ActionListener {
    //...
    private JFrame contentPane;
    //..

This immediately raises the question, which one is actually on the screen and which one are you actually interacting with? While this might not be directly related to your problem, it is confusing.

As a general rule of thumb, don't extend from top level containers like JFrame, it locks you into a single use case and can cause no end of confusion. Instead, start with a JPanel and add it to an instance of JFrame or any other container you like.

The "main probable" problem is, Swing is lazy. It won't update the UI until you tell it or the UI is resized.

When adding and removing components, you need to call revalidate and repaint on the container to trigger an update - this is what's actually going wrong in your code, you're referencing contentPane, by that is private JFrame contentPane; and not the contentPane of the JFrame from which Hasher extends ... see, confusion.

Happening dug around your code a bit, it's obvious that you have a lot of repeated operations going on, the only core difference is the algorithm used to hash the text.

So, with that in mind, we can create some basic classes to do most of the work, for example...

public class HashPane extends JPanel {

    private JLabel hashedLabel;
    private JLabel promptLabel;

    private HashAlgorithim algorithim;

    public HashPane(String labelText, HashAlgorithim algorithim) {
        setOpaque(false);
        this.algorithim = algorithim;
        setLayout(new FlowLayout(FlowLayout.LEFT));
        promptLabel = new JLabel(labelText);
        add(promptLabel);
        hashedLabel = new JLabel("??");
        add(hashedLabel);
    }

    public void setText(String text) {
        hashedLabel.setText(algorithim.generateHash(text));
    }

}

This is just two labels, which show a prompt and a result. The result is generated via a plug algorithm which is used to generate the hash for the supplied text

The algorithm itself is just a interface which defines the basic contract...

public interface HashAlgorithm {
    public String generateHash(String from);
}

You would then need to create an implementation of each algorithm you wanted to use

Now, making a panel visible/invisible simply becomes a matter of associating a JCheckBox with a HashPane which can be achieved through a simple Map...

public class Hasher extends JPanel {
    //...
    private Map<JCheckBox, HashPane> mapPanes;

    public Hasher() {
        //...
        HashPane md5Pane = new HashPane("MD5 hash = ", new NotAMD5Alorithim());
        //...
        HashPane sha1Pane = new HashPane("SHA-1 hash = ", new NotAMSHA1Alorithim());
        //..
        mapPanes = new HashMap<>(25);
        mapPanes.put(MD5Check, md5Pane);
        mapPanes.put(SHA1Check, sha1Pane);
        //...

You can then use a single ActionListener to manage all the JCheckBoxs

public class Hasher extends JPanel {
    //...
    private Map<JCheckBox, HashPane> mapPanes;

    public Hasher() {
        //...
        ActionHandler listener = new ActionHandler();
        for (Entry<JCheckBox, HashPane> entry : mapPanes.entrySet()) {
            entry.getKey().addActionListener(listener);
            entry.getValue().setVisible(false);
        }

    }

    protected class ActionHandler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            JCheckBox cb = (JCheckBox) e.getSource();
            HashPane hashPane = mapPanes.get(cb);
            hashPane.setVisible(cb.isSelected());
            revalidate();
            repaint();
        }

    }

And because I pretty much butchered your code...

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.FlowLayout;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    import javax.swing.JCheckBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;

    public class Hasher extends JPanel {

        String UserInput;
        private JTextField textInputField;
        private static JCheckBox MD5Check, SHA1Check, SHA256Check, FileCheck;

        private Map<JCheckBox, HashPane> mapPanes;

        public Hasher() {
            setLayout(new BorderLayout());
            setBackground(new Color(88, 148, 202));

            //CheckBoxes
            JPanel mainPanel = new JPanel();
            mainPanel.setLayout(new BorderLayout());
            JPanel checkBoxPanel = new JPanel();
            MD5Check = new JCheckBox("MD5");
            checkBoxPanel.add(MD5Check);
            SHA1Check = new JCheckBox("SHA-1");
            checkBoxPanel.add(SHA1Check);
            SHA256Check = new JCheckBox("SHA-256");
            checkBoxPanel.add(SHA256Check);
            FileCheck = new JCheckBox("File Hashing");
            checkBoxPanel.add(FileCheck);
            mainPanel.add(checkBoxPanel);
            add(mainPanel, BorderLayout.NORTH);

            JPanel centerPane = new JPanel(new BorderLayout());
            centerPane.setOpaque(false);
            JPanel inputPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
            inputPane.setOpaque(false);

    //Entered data to perform hash on
            inputPane.add(new JLabel("Enter text to hash: "));
            textInputField = new JTextField(20);
            inputPane.add(textInputField);

            centerPane.add(inputPane, BorderLayout.NORTH);

            JPanel output = new JPanel(new GridBagLayout());
            output.setOpaque(false);
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 1;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            HashPane md5Pane = new HashPane("MD5 hash = ", new NotAMD5Alorithim());
            output.add(md5Pane, gbc);

            gbc.gridx = 0;
            gbc.gridy++;
            HashPane sha1Pane = new HashPane("SHA-1 hash = ", new NotAMSHA1Alorithim());
            output.add(sha1Pane, gbc);

            // last pane
            gbc.gridy++;
            gbc.weighty = 1;
            output.add(new JLabel(), gbc);

            centerPane.add(output);

            add(centerPane);

            mapPanes = new HashMap<>(25);
            mapPanes.put(MD5Check, md5Pane);
            mapPanes.put(SHA1Check, sha1Pane);
            //...

            ActionHandler listener = new ActionHandler();
            for (Entry<JCheckBox, HashPane> entry : mapPanes.entrySet()) {
                entry.getKey().addActionListener(listener);
                entry.getValue().setVisible(false);
            }

        }

        protected class ActionHandler implements ActionListener {

            @Override
            public void actionPerformed(ActionEvent e) {
                JCheckBox cb = (JCheckBox) e.getSource();
                HashPane hashPane = mapPanes.get(cb);
                hashPane.setVisible(cb.isSelected());
                revalidate();
                repaint();
            }

        }

        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new Hasher());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }

        public interface HashAlgorithm {
            public String generateHash(String from);
        }

        public class NotAMD5Alorithim implements HashAlgorithm {

            @Override
            public String generateHash(String from) {
                return "bananas";
            }

        }

        public class NotAMSHA1Alorithim implements HashAlgorithm {

            @Override
            public String generateHash(String from) {
                return "bananas";
            }

        }

        public class HashPane extends JPanel {

            private JLabel hashedLabel;
            private JLabel promptLabel;

            private HashAlgorithm algorithim;

            public HashPane(String labelText, HashAlgorithm algorithim) {
                setOpaque(false);
                this.algorithim = algorithim;
                setLayout(new FlowLayout(FlowLayout.LEFT));
                promptLabel = new JLabel(labelText);
                add(promptLabel);
                hashedLabel = new JLabel("??");
                add(hashedLabel);
            }

            public void setText(String text) {
                hashedLabel.setText(algorithim.generateHash(text));
            }

        }

    }

Having said all that, I might be tempted to have the JCheckBox in the HashPane and has the HashPane always visible and simply disable the output text ... or simply not bother and always have all the algorithms available all the time




回答2:


you need to handle Events for all check-box while check/uncheck,

public void actionPerformed(ActionEvent actionEvent) {
       if(all check-box un-checked){
            // someLable.setVisible(false);
       }else if(MD5 checked){
           // peform operation based upon MD5
           // someLable.setVisible(true);
       }
       // likewise for all others
      }



回答3:


Change

public void actionPerformed(ActionEvent e) {
   boolean Visible = MD5Check.isSelected();
   MD5Hashed.setVisible(Visible);
   MD5Label.setVisible(Visible);
}

to:

public void actionPerformed(ActionEvent e) {
    boolean Visible = MD5Check.isSelected();
    MD5Hashed.setVisible(Visible);
    MD5Label.setVisible(Visible);
    contentPane.validate();
    contentPane.repaint();
 }

If You want to remove MD5Hashed and MD5Label then something like this:

{
if(MD5Check.isSelected()){
    MD5Hashed.remove();
    MD5Label.remove();
}
else{
    contentPane.add( MD5Label);
    contentPane.add( MD5Hashed );
}

    contentPane.validate();
    contentPane.repaint();
}


来源:https://stackoverflow.com/questions/36215775/in-a-java-jframe-can-i-add-remove-a-jlabel-from-view-using-a-checkbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!