【问题标题】:Setting the height of a JTextFrame设置 JTextFrame 的高度
【发布时间】:2020-09-02 06:42:47
【问题描述】:

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

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

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

有什么建议吗?

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


}

【问题讨论】:

    标签: java swing jtextfield


    【解决方案1】:

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

    其中一个解决方案是使用BorderLayout 作为外部容器,并在其中添加此BoxLayout-ed 面板,并带有BorderLayout.PAGE_START 约束。 PAGE_START 约束指的是“嘿,BoxLayout,没有可用空间”。看看这个例子:

    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) 因为布局负责组件的边界。但是,不建议这样做改用布局管理器。让他们为你工作。

    【讨论】:

    • 非常感谢您的帮助!
    猜你喜欢
    • 2015-03-16
    • 2017-03-13
    • 2020-08-12
    • 2016-08-21
    • 2017-12-22
    • 2012-05-31
    • 2013-04-27
    • 1970-01-01
    相关资源
    最近更新 更多