java - 按下切换按钮时 JButton 会改变大小

标签 java swing user-interface resize calculator

我的 GUI 存在问题,当我按下属于某个面板的切换按钮时,面板按钮会更改大小,标签会更改位置。我附上了一些屏幕截图来显示操作中的错误。我相信这是因为按钮共享相同的面板,但我不确定它是否可以修复,以便按钮大小保持静态,标签位置也是如此。

我的代码如下(抱歉,它很乱!我有很多嵌套的 BorderLayout JPanel,这可能是问题所在,但对我来说,这是获得正确布局的最简单方法。

package v2;

import javax.swing.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; 
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;

public class BmrCalcv2 extends JFrame {

    // Frames and main panels
    static JFrame mainFrame;
    static JPanel mainPanel;
    static JPanel combinedGAHWpanel; // combines genderPanel, agePanel, heightPanel, weightPanel - this
                                     // is a BorderLayout, whereas
                                     // gender/agePanel are FlowLayouts.
    static JPanel weightHeightPanel; // Combines weight and height panel into out flowlayout panel, which is then combined into the above borderlayout panel

    // Image components
    static JPanel imgPanel;
    private JLabel imgLabel;

    // Menu-bar components
    static JMenuBar menuBar;
    static JMenu saveMenu, optionMenu, helpMenu;

    // Age components
    static JPanel agePanel;
    private JLabel ageLabel;
    private JLabel yearsLabel;
    private JTextField ageTextField;

    // Gender components
    static JPanel genderPanel;
    private JLabel genderLabel;
    private JRadioButton genderMale;
    private JRadioButton genderFemale;


    // Height components
    static JPanel heightPanel;
    private JLabel heightLabel;
    private JTextField heightCMField;
    private JLabel heightFTLabel;
    private JLabel heightINCHLabel;
    private JTextField heightFTField;
    private JTextField heightINCHField;
    private JToggleButton cmButton;
    private JToggleButton feetButton;


    // Weight components
    static JPanel weightPanel;
    private JLabel weightLabel;
    private JTextField weightField;
    private JToggleButton kgButton;
    private JToggleButton lbButton;


    // TDEE and BMR Components
    static JPanel tdeePanel;
    static JPanel tdeeBMRPanel;
    static JPanel activityLevelPanel;
    static JPanel bmrTDEEValuesPanel;
    static JPanel bmrValuePanel;
    static JPanel tdeeValuePanel;
    private JLabel tdeeQuestionLabel;
    private JLabel activityLevelLabel;
    private JComboBox activityLevelBox;
    private JRadioButton tdeeYes;
    private JRadioButton tdeeNo;
    private JLabel bmrLabel;
    private JLabel tdeeLabel;




    // Default values for gender/weight/height

    String[] activityLevels = {"Sedentary", "Lightly Active", "Moderately Active", "Very Active", "Extra Active"};
    String genderSelection = "M";   
    String weightSelection = "kg";
    String heightSelection = "cm";
    String tdeeSelection = "no";




    public BmrCalcv2(String title) {

        // Main JFrame
        setTitle("BMR/TDEE Calculator");
        mainPanel = new JPanel();

        // All JPanel declarations
        menuBar = new JMenuBar();
        imgPanel = new JPanel();
        agePanel = new JPanel();
        genderPanel = new JPanel();
        heightPanel = new JPanel();
        weightPanel = new JPanel();
        weightHeightPanel = new JPanel(new BorderLayout());
        combinedGAHWpanel = new JPanel(new BorderLayout()); // Create a new panel used to combine
                                                            // genderPanel, agePanel, weightPanel, heightPanel below
        tdeeBMRPanel = new JPanel(new BorderLayout());
        tdeePanel = new JPanel();
        activityLevelPanel = new JPanel();
        bmrTDEEValuesPanel = new JPanel(new BorderLayout());
        bmrValuePanel = new JPanel();
        tdeeValuePanel = new JPanel();



        // Image panel declaration
        imgLabel = new JLabel(new ImageIcon("filesrc//mainlogo.png"));
        imgPanel.add(imgLabel);

        // JPanel layout managers
        agePanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        genderPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));


        // Menu JComponents
        saveMenu = new JMenu("Save");
        optionMenu = new JMenu("Options");
        helpMenu = new JMenu("Help");
        menuBar.add(saveMenu);
        menuBar.add(optionMenu);
        menuBar.add(helpMenu);

        // Age JComponents
        ageLabel = new JLabel("Age:");
        yearsLabel = new JLabel("<html><i>years</i><html>");
        ageTextField = new JTextField(5);
        agePanel.add(ageLabel);
        agePanel.add(ageTextField);
        agePanel.add(yearsLabel);

        // Gender JComponents
        genderLabel = new JLabel("Gender:");
        genderMale = new JRadioButton("Male", true);
        genderFemale = new JRadioButton("Female");



        genderPanel.add(genderLabel);
        genderPanel.add(genderMale);
        genderPanel.add(genderFemale);


        ButtonGroup genderGroup = new ButtonGroup(); // groups male and female radio buttons together so that only one can be selected
        genderGroup.add(genderMale);
        genderGroup.add(genderFemale);


        genderMale.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
              String genderSelection = "M";   
            } 
        });

        genderFemale.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
              String genderSelection = "F";
            } 
        });

        // Height JComponents
        heightLabel = new JLabel("Height:");
        heightCMField = new JTextField(4);
        heightFTField = new JTextField(3);
        heightFTLabel = new JLabel("ft");
        heightINCHLabel = new JLabel("inch");
        heightINCHField = new JTextField(3);
        cmButton = new JToggleButton("cm", true);
        feetButton = new JToggleButton("feet");
        heightPanel.add(heightLabel);

        ButtonGroup heightGroup = new ButtonGroup();
        heightGroup.add(cmButton);
        heightGroup.add(feetButton);

        heightPanel.add(heightCMField);

        cmButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                  heightSelection = "cm";
                  heightPanel.remove(heightCMField);
                  heightPanel.remove(cmButton);
                  heightPanel.remove(feetButton);
                  heightPanel.remove(heightFTField);
                  heightPanel.remove(heightFTLabel);
                  heightPanel.remove(heightINCHField);
                  heightPanel.remove(heightINCHLabel);
                  heightPanel.add(heightCMField);
                  heightPanel.add(cmButton);
                  heightPanel.add(feetButton);
                  weightHeightPanel.add(heightPanel, BorderLayout.CENTER);
                  combinedGAHWpanel.add(weightHeightPanel, BorderLayout.SOUTH);
                  mainPanel.add(combinedGAHWpanel);
                  add(mainPanel);
                  setVisible(true);
                }
            });

        feetButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                  heightSelection = "feet";
                  heightPanel.remove(heightCMField);
                  heightPanel.remove(cmButton);
                  heightPanel.remove(feetButton);
                  heightPanel.add(heightFTField);
                  heightPanel.add(heightFTLabel);
                  heightPanel.add(heightINCHField);
                  heightPanel.add(heightINCHLabel);
                  heightPanel.add(cmButton);
                  heightPanel.add(feetButton);
                  weightHeightPanel.add(heightPanel, BorderLayout.CENTER);
                  combinedGAHWpanel.add(weightHeightPanel, BorderLayout.SOUTH);
                  mainPanel.add(combinedGAHWpanel);
                  add(mainPanel);
                  setVisible(true);
                }
            });

        heightPanel.add(cmButton);
        heightPanel.add(feetButton);


        // Weight JComponents
        weightLabel = new JLabel("Weight:");
        weightField = new JTextField(4);
        kgButton = new JToggleButton("kg", true);
        lbButton = new JToggleButton("lbs");

        weightPanel.add(weightLabel);
        weightPanel.add(weightField);
        weightPanel.add(kgButton);
        weightPanel.add(lbButton);

        ButtonGroup weightGroup = new ButtonGroup();
        weightGroup.add(kgButton);
        weightGroup.add(lbButton);


        kgButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                weightSelection = "kg"; 
            }
        });

        lbButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                weightSelection = "lb"; 
            }
        });


        // tdee JComponents
        tdeeQuestionLabel = new JLabel("Calculate TDEE Also?");
        tdeeYes = new JRadioButton("Yes");
        tdeeNo = new JRadioButton("No", true);

        ButtonGroup tdeeButton = new ButtonGroup();
        tdeeButton.add(tdeeYes);
        tdeeButton.add(tdeeNo);

        tdeePanel.add(tdeeQuestionLabel);
        tdeePanel.add(tdeeYes);
        tdeePanel.add(tdeeNo);


        // activitylevel JComponents

        activityLevelLabel = new JLabel("Activity Level: ");
        activityLevelBox = new JComboBox(activityLevels);
        activityLevelBox.setSelectedIndex(0);

        activityLevelPanel.add(activityLevelLabel);
        activityLevelPanel.add(activityLevelBox);
        activityLevelBox.setEnabled(false);

        tdeeYes.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                  tdeeSelection = "yes";
                  activityLevelBox.setEnabled(true);
                }
            });

        tdeeNo.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                  tdeeSelection = "no";
                  activityLevelBox.setEnabled(false);
                }
            });



        // tdee and BMR value components

        bmrLabel = new JLabel("BMR: ");
        tdeeLabel = new JLabel("TDEE: ");
        bmrLabel.setFont(new Font("Monotype Corsiva",1,20));
        tdeeLabel.setFont(new Font("Monotype Corsiva",1,20));


        bmrTDEEValuesPanel.add(new JButton("Calculate"), BorderLayout.NORTH);
        bmrTDEEValuesPanel.add(bmrLabel, BorderLayout.CENTER);
        bmrTDEEValuesPanel.add(tdeeLabel, BorderLayout.SOUTH);





        // Adding sub JPanels to main JPanel
        mainPanel.add(imgPanel);

        combinedGAHWpanel.add(agePanel, BorderLayout.NORTH); // Combine genderPanel and agePanel (which are both flowLayouts) into a
                                                             // single BorderLayout panel where agePanel is given the Northern spot and
                                                             // genderPanel is given the center spot in the panel
        weightHeightPanel.add(weightPanel, BorderLayout.NORTH); // Nested borderlayouts, the weightHeightPanel is another borderLayout which is nested
                                                                 // into the southern position of the combinedGAHW border layout.
        weightHeightPanel.add(heightPanel, BorderLayout.CENTER);
        weightHeightPanel.add(tdeeBMRPanel, BorderLayout.SOUTH);




        combinedGAHWpanel.add(genderPanel, BorderLayout.CENTER);
        combinedGAHWpanel.add(weightHeightPanel, BorderLayout.SOUTH);


        mainPanel.add(combinedGAHWpanel);


        // adding to tdeeBMRPanel
        tdeeBMRPanel.add(tdeePanel, BorderLayout.NORTH);
        tdeeBMRPanel.add(activityLevelPanel, BorderLayout.CENTER);


        tdeeBMRPanel.add(bmrTDEEValuesPanel, BorderLayout.SOUTH);


        // Adding main JPanel and menubar to JFrame
        setJMenuBar(menuBar);
        add(mainPanel);
    }


    public static void main(String[] args) {

        BmrCalcv2 gui = new BmrCalcv2("BMR/TDEE Calculator");

        gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        gui.setVisible(true);
        gui.setSize(330, 500);
        gui.setResizable(false);

    }
}

enter image description here enter image description here

最佳答案

这是您对 UI 所做的更改(添加/删除标签/字段)和 BorderLayout 的复合使用的组合。

当您在“脚”和“CM”之间切换时,实际上不需要更改标签/字段,因为用户需要的所有信息都已经可供他们使用(以按钮的形式)。

我会去掉 heightFTFieldheightINCHField 并将其设为单个字段,使用 JToggleButton 选择 状态以确定应如何计算值。我还会删除 heightFTLabelheightINCHLabel 标签,它们对切换按钮已经在做的 UI 没有增加什么值(value)。

现在,完成后,您可以删除 cmButtonfeetButtonActionListener,因为它们不提供有用的操作。

将来,您可能会发现更改组件的可见性状态更加容易。

基于评论,一个基本示例

这演示了如何使用单个字段 ButtonGroup 来管理 JToggleButton 的选择,并使用 JToggleButton#isSelected 来控制逻辑路径

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class JavaApplication63 {

    public static void main(String[] args) {
        new JavaApplication63();
    }

    public JavaApplication63() {
        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 TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JTextField height;
        private JToggleButton cmBtn;
        private JToggleButton feetBtn;

        public TestPane() {
            setLayout(new GridBagLayout());
            height = new JTextField(10);
            cmBtn = new JToggleButton("CM");
            feetBtn = new JToggleButton("Ft");

            ButtonGroup bg = new ButtonGroup();
            bg.add(cmBtn);
            bg.add(feetBtn);
            feetBtn.setSelected(true);

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(2, 2, 2, 2);

            add(height, gbc);
            gbc.gridx++;
            add(cmBtn, gbc);
            gbc.gridx++;
            add(feetBtn, gbc);

            gbc.gridx = 0;
            gbc.gridy++;
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            JButton calc = new JButton("Calculate");
            calc.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    double valueInCms = 0;
                    if (cmBtn.isSelected()) {
                        valueInCms = Double.parseDouble(height.getText());
                    } else if (feetBtn.isSelected()) {
                        String text = height.getText().replace("'", ".").replace("\"", "");
                        double feet = Double.parseDouble(text);
                        valueInCms = feet * 30.48;
                    }

                    System.out.println("valueInCms = " + valueInCms);
                }
            });
            add(calc, gbc);
        }

    }

}

关于java - 按下切换按钮时 JButton 会改变大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30879970/

相关文章:

user-interface - Xamarin 表单 UI 测试

java - 在 Apache Kafka 中创建主题时出错

java - 在 Swing 中控制间距

user-interface - 用于绘制 GUI 的免费工具

java - 如何让每个切换按钮执行不同的操作?

java - 使用 if-else 防止 JTextfield 中的字符串为 null

java - 将 Pentaho Reporting 与 Java Web 应用程序集成

java - 如何在 JXPath 表达式中使用字符串的子字符串

java - 编辑 .json 文件 : adding lines in certain parts of the file?

java - 在 JScrollPane 上停用 ScrollOnExpand