设置 JTextFrame 的高度

Setting the height of a JTextFrame

下面的 class 创建了一个表单 (Jpanel),其任务是从用户那里获取多个字符串并对其进行处理。它在功能上正常工作,但让我感到困扰的是 JTextFields(允许修改 one 文本行的组件)的高度会自动调整并且可以成为非常大。

我试过方法setBounds(),但是:

  1. 我不想计算 JTextField 的位置或宽度,只计算它的高度;和
  2. 限制 JTextField!
  3. 的高度

有什么建议吗?

public class MultiplesStrings extends JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = 1106317992372206473L;

    /** The greater {@link JPanel}.                                                                 */
    private JPanel contentPane;

    private JPanel[] interaction;
    private JLabel[] text;
    private JTextField[] insertText;


    /** The {@link JButton} that submits the form information.                                      */
    JButton button;

    @SuppressWarnings("unused")
    private Consumer<MultiplesStrings> instructions;

    // =========================================================            
        // TODO | Constructor

    /**
     * Create the frame.
     */
    public MultiplesStrings(String title, String[] messages, 
                int x, int y, int width, int height, 
                Consumer<MultiplesStrings> instructions) {

        // ===== MAIN FRAME DEFINITION =====

        this.setTitle(title);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setBounds(x, y, width, height);

        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(10, 10, 10, 10));
        setContentPane(contentPane);
        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.PAGE_AXIS));
    //  contentPane.setBackground(Colours.newColor("DDDDDD"));

        // ===== INTERACTION FRAME DEFINITION =====

        this.interaction = new JPanel[messages.length];
        this.text       = new JLabel[messages.length];
        this.insertText = new JTextField[messages.length];
        for(int i=0 ; i<messages.length ; i++)
            {
            interaction[i] = new JPanel();
            interaction[i].setLayout(new BoxLayout(interaction[i], BoxLayout.LINE_AXIS));
            interaction[i].setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
            interaction[i].add(Box.createHorizontalGlue());

            // ===== TEXT =====
            text[i] = new JLabel(messages[i]);
            text[i].setAlignmentY(RIGHT_ALIGNMENT);
        //  text.setBounds(0, imageResolution + margin, Width, buttonHeight);

            interaction[i].add(text[i]);

            // ===== INSERT TEXT FIELD =====
            insertText[i] = new JTextField();
        //  this.insertTextField.setBounds(Width + margin, imageResolution + margin, moveWidth, buttonHeight);
            insertText[i].setColumns(10);

            interaction[i].add(insertText[i]);

            this.add(interaction[i]);
            }

        // ===== SUBMIT BUTTON DEFINITION =====

        this.button = new JButton("Submit");

        // Button behavior
        MultiplesStrings support = this;
        button.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {         }
            } );
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {     
                instructions.accept(support);       
        //      support.setVisible(false);
                }
            } );
        this.getRootPane().setDefaultButton(button);


        this.add(button);
    }

    // =========================================================            
        // TODO | Input-output manipulation

    /** Acquires all {@link String}s written by the user in the {@link JTextField}s used for {@code interactions}.  */
    public String[] acquireInputs() {
        String[] output = new String[interaction.length];
        for(int i=0 ; i<output.length ; i++)
            output[i] = insertText[i].getText();
        return output;
    }


    // =========================================================            
        // TODO | Main

    public static final int width   = 300;
    public static final int height  = 500;

    private static String[] input;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() { public void run() {
            try {
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
                double screenWidth = screenSize.getWidth();
                double screenHeight = screenSize.getHeight();

                // Creates a centered form
                MultiplesStrings ms = new MultiplesStrings("Test", 
                    new String[] { "Insert first string: ", "Insert second string: ", "Insert third string: "},
                    (int) (screenWidth-width)/2,    (int) (screenHeight-height)/2, width, height, 
                    (MultiplesStrings obj) ->
                        {
                        input = obj.acquireInputs();
                        for(int i=0 ; i<input.length ; i++)
                            System.out.println("The " + i + "-th input is: " + input[i]);
                        }
                    );
                ms.setVisible(true); 

                } catch (Exception e) {         e.printStackTrace();                                }
        }
    });
}


}

这是因为 BoxLayout 使用了容器的整个 space。换句话说,它拉伸所有组件以利用总可用高度 space(因为您使用 PAGE_AXIS,它指的是可用高度)。

其中一个解决方案是使用 BorderLayout 作为外部容器,并在内部添加此 BoxLayout-ed 面板 at,具有 BorderLayout.PAGE_START 约束。 PAGE_START 约束指的是 "Hey you BoxLayout, there is no available space for you"。看看这个例子:

public class BoxLayoutSample extends JFrame {
    public BoxLayoutSample() {
        super("");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Container contentPane = getContentPane();
        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));

        contentPane.add(new JTextField(15));
        contentPane.add(new JTextField(15));

        setLocationByPlatform(true);
        pack();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new BoxLayoutSample().setVisible(true));
    }

}

它给了我们:

这就是你现在所拥有的。

但是如果你使用外部 BorderLayout-ed 面板:

public class BoxLayoutSample extends JFrame {
    public BoxLayoutSample() {
        super("");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Container contentPane = getContentPane(); //This is the outer panel
        contentPane.setLayout(new BorderLayout());

        JPanel boxLayoutPanel = new JPanel(); //This is the nested panel
        boxLayoutPanel.setLayout(new BoxLayout(boxLayoutPanel, BoxLayout.Y_AXIS));

        //Components to nested panel
        boxLayoutPanel.add(new JTextField(15));
        boxLayoutPanel.add(new JTextField(15));


        //PAGE_START to wrap it on the top
        contentPane.add(boxLayoutPanel, BorderLayout.PAGE_START);

        setLocationByPlatform(true);
        pack();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new BoxLayoutSample().setVisible(true));
    }
}

你得到:

此外,如果组件包含布局,则调用 setBounds 方法将被忽略。为了看到 setBounds 效果,您必须 container.setLayout(null) 因为布局负责组件的边界。但是,不推荐这样做改用布局管理器。让他们为你工作。