2

这是我第一次来这里。
我正在编写一个 GUI 驱动的程序,它允许我对.txt文件执行凯撒密码。
但是,在添加ActionListeners 和ChangeListeners 之前,我决定测试 GUI。这是我得到的: 在此处输入图像描述

这是代码:

package implementation;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Frame extends JFrame{
    public Frame(){
        super("Caesar[E]");
        this.setVisible(true);
        this.setLocationRelativeTo(null);
        /*Adding the options to GUI*/
        factor.setPreferredSize(new Dimension(30,30));
        JToolBar toolbar = new JToolBar();
        radio.add(encrypt);
        radio.add(decrypt);
        toolbar.add(encrypt);
        toolbar.add(decrypt);
        toolbar.add(factor);
        toolbar.setFloatable(false);

        /*Adding the JTextArea for input*/
        Box inputBound = Box.createHorizontalBox();
        Box inputBound_text = Box.createVerticalBox();
        Box inputBound_buttons = Box.createVerticalBox();
        inputScroll.add(input);
        inputScroll.setEnabled(true);
        input.setEditable(true);
        inputScroll.setBorder(BorderFactory.createTitledBorder("Text/File for Encryption/" +
                "Decryption"));
        inputBound_text.add(inputScroll);
        inputBound_buttons.add(openFile);
        inputBound_buttons.add(cancelFileInput);
        inputBound.add(inputBound_text);
        inputBound.add(Box.createHorizontalStrut(25));
        inputBound.add(inputBound_buttons);

        /*Adding JTextArea for output*/
        Box outputBound = Box.createHorizontalBox();
        Box outputBound_text = Box.createVerticalBox();
        Box outputBound_buttons = Box.createVerticalBox();
        outputScroll.add(output);
        output.setEditable(true);
        outputScroll.setBorder(BorderFactory.createTitledBorder("Text After Encryption" +
                "/Decryption"));
        outputBound_text.add(outputScroll);
        outputBound_buttons.add(saveFile);
        outputBound_buttons.add(send);
        outputBound.add(outputBound_text);
        outputBound.add(Box.createHorizontalStrut(25));
        outputBound.add(outputBound_buttons);
        outputBound.setSize(150, 200);

        /*Adding JButton for performing the action*/
        this.add(performAction,BorderLayout.SOUTH);

        /*Adding the components to the Frame*/
        Box outerBox = Box.createVerticalBox();
        outerBox.add(toolbar,BorderLayout.NORTH);
        outerBox.add(inputBound);
        outerBox.add(outputBound);
        this.add(outerBox);
        this.setSize(500, 700);
    }
    boolean isFileInput = false;
    boolean isEncrypt = true;
    JButton performAction = new JButton("Encrypt!");
    JButton openFile = new JButton("Open a File");
    JButton cancelFileInput = new JButton("Cancel File Input");
    JButton saveFile = new JButton("Save File");
    JButton send = new JButton("Send");
    JTextArea input = new JTextArea();
    JTextArea output = new JTextArea();
    JFileChooser chooser = new JFileChooser();
    JScrollPane inputScroll = new JScrollPane();
    JScrollPane outputScroll = new JScrollPane();
    ButtonGroup radio = new ButtonGroup();
    JRadioButton encrypt = new JRadioButton("Encrypt",true);
    JRadioButton decrypt = new JRadioButton("Decrypt",false);
    JSpinner factor = new JSpinner(new SpinnerNumberModel(1,1,26,1));

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run(){
                new Frame();
            }
        });
    }
}

你能告诉我如何解决如图所示的问题吗?

  • 我知道我可以使用setPreferredSize(),但如何确保我输入正确的尺寸而无需反复试验?
  • 4

    4 回答 4

    2

    我喜欢 SpringLayout,它非常灵活,而且没有什么不能做的。特别是您将不再需要关心 setPreferredSize。随便找找,资源够用的。

    SpringLayout 允许您定义元素相对于其他元素的大小 - 例如,您可以确保按钮看起来相同。

    于 2012-12-11T14:41:10.970 回答
    1

    我会推荐MiGLayout作为 LayoutManager。类似的事情在 MiGLayout 中很容易

    于 2012-12-11T12:51:16.083 回答
    1

    反复试验绝不是获得所需布局的好方法。相反,请使用JTextArea可让您说出所需行数和列数的构造函数。

    JTextArea(int rows, int columns)
    

    JTextArea当您打开窗口时,将计算一个好的首选尺寸pack(),而您不需要setSize().

    编辑:您说,“JTextArea处于非活动状态。我无法在其中输入文本。”

    而不是add(),使用setViewportView()

    inputScroll.setViewportView(input);
    ...
    outputScroll.setViewportView(output);
    ...
    
    于 2012-12-11T13:30:19.993 回答
    0

    在这种情况下,我喜欢将我的应用程序划分为职责范围。这使代码保持干净和独立,允许我在需要时替换其中的部分,而不会对应用程序的其余部分产生不利影响。

    这也意味着您可以专注于每个部分的个别要求。

    对于复杂的布局,使用具有单独布局管理器的复合容器总是更好(恕我直言),它降低了复杂性和奇怪交叉行为的可能性。

    在此处输入图像描述

    public class BadLayout07 {
    
        public static void main(String[] args) {
            new BadLayout07();
        }
    
        public BadLayout07() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new MasterPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class MasterPane extends JPanel {
    
            public MasterPane() {
                EncryptSettings encryptSettings = new EncryptSettings();
                InputPane inputPane = new InputPane();
                OutputPane outputPane = new OutputPane();
    
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.weightx = 1;
                gbc.fill = GridBagConstraints.HORIZONTAL;
    
                add(encryptSettings, gbc);
    
                gbc.gridy++;
                gbc.weighty = 1;
                gbc.fill = gbc.BOTH;
                add(inputPane, gbc);
    
                gbc.gridy++;
                add(outputPane, gbc);
            }
    
        }
    
        public class EncryptSettings extends JPanel {
    
            private JRadioButton encrypt;
            private JRadioButton decrypt;
            private JSpinner factor;
    
            public EncryptSettings() {
                encrypt = new JRadioButton("Encrypt");
                decrypt = new JRadioButton("Decrypt");
                ButtonGroup bg = new ButtonGroup();
                bg.add(encrypt);
                bg.add(decrypt);
    
                factor = new JSpinner(new SpinnerNumberModel(new Integer(1), new Integer(1), null, new Integer(1)));
    
                setLayout(new FlowLayout(FlowLayout.LEFT));
                add(encrypt);
                add(decrypt);
                add(factor);
            }
    
        }
    
        public class InputPane extends JPanel {
    
            private JTextArea input;
            private JButton open;
            private JButton close;
    
            public InputPane() {
                setBorder(new TitledBorder("Source Text"));
                input = new JTextArea();
                open = new JButton("Open");
                close = new JButton("Close");
    
                JPanel tb = new JPanel(new FlowLayout(FlowLayout.LEFT));
                tb.add(open);
                tb.add(close);
    
                setLayout(new BorderLayout());
                add(tb, BorderLayout.NORTH);
                add(new JScrollPane(input));
            }
    
        }
    
        public class OutputPane extends JPanel {
    
            private JTextArea output;
            private JButton save;
            private JButton send;
    
            public OutputPane() {
                setBorder(new TitledBorder("Encrypted Text"));
                output = new JTextArea();
                output.setEditable(false);
                save = new JButton("Save");
                send = new JButton("Send");
    
                JPanel tb = new JPanel(new FlowLayout(FlowLayout.LEFT));
                tb.add(save);
                tb.add(send);
    
                setLayout(new BorderLayout());
                add(tb, BorderLayout.NORTH);
                add(new JScrollPane(output));
            }
    
        }
    
    }
    

    我没有互连任何功能,但这是一个简单的案例,即根据需要提供适当的 setter 和 getter,以及适当的事件侦听器。

    于 2012-12-11T20:03:56.467 回答