JFrame 中的 JTextField 在实际文本字段之外占用了太多空间

Posted

技术标签:

【中文标题】JFrame 中的 JTextField 在实际文本字段之外占用了太多空间【英文标题】:JTextField in a JFrame is taking too much space outside the actual text field 【发布时间】:2015-01-24 04:18:14 【问题描述】:

好的,我正在为我正在开发的程序创建菜单/GUI,但我对此没有太多经验,因此我需要一些有关组件组织和布局的帮助。

现在,当我运行此代码时,如图所示(抱歉,我没有足够的代表来嵌入它,*** 的新手)在 JTextField 和上一个按钮的位置之间有很大的空间/窗口边框是。如果有人可以帮我解决这个问题,那就太好了。 :) 谢谢。

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;

public class WindowWin extends JFrame implements ActionListener

JPanel[] row = new JPanel[4];
JButton[] button = new JButton[4];  
String[] buttonString = "Copy to Clipboard","Go","Back","Info";

int[] dimW = 400,200,65;
int[] dimH = 40,100;

Dimension keyDim = new Dimension(dimW[0],dimH[0]);
Dimension displayDimension = new Dimension(dimW[0],dimH[1]);
Dimension butDim = new Dimension(dimW[1],dimH[0]);
Dimension infoDim = new Dimension(dimW[2],dimH[0]);

JEditorPane display = new JEditorPane();
Font font = new Font("Times new Roman",Font.PLAIN, 14);

JTextField keyIn = new JTextField(24);
JEditorPane msgIn = new JEditorPane();

JScrollPane scrollerD = new JScrollPane(display,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JScrollPane scrollerM = new JScrollPane(msgIn,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);


public static void main(String[] args)

    WindowWin c = new WindowWin();


WindowWin()
    super("Test");

//  setDesign();
    //setSize(380,250);
    setSize(460,500);

    setResizable(true);

    setDefaultCloseOperation(EXIT_ON_CLOSE);

    GridLayout grid = new GridLayout(4,3);

    setLayout(grid);

    FlowLayout f1 = new FlowLayout(FlowLayout.CENTER);
    FlowLayout f2 = new FlowLayout(FlowLayout.CENTER,1,1);
    //FlowLayout South

    for(int i = 0; i < 4; i++)
        row[i] = new JPanel();

    row[0].setLayout(f1);

    for(int i = 1; i < 4; i++)
        row[i].setLayout(f2);

    for(int i = 0; i < 4; i++)
    
        button[i] = new JButton();
        button[i].setText(buttonString[i]);
        button[i].setFont(font);
        button[i].addActionListener(this);
    

    display.setFont(font);
    display.setEditable(false);
    display.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    display.setPreferredSize(displayDimension);

    keyIn.setFont(font);
    keyIn.setEditable(true);
    keyIn.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    keyIn.setPreferredSize(keyDim);

    msgIn.setFont(font);
    msgIn.setEditable(true);
    msgIn.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    msgIn.setPreferredSize(displayDimension);


    for(int i = 0; i < 2; i++)
    button[i].setPreferredSize(butDim);
    for(int i = 2; i < 4; i++)
    button[i].setPreferredSize(infoDim);

    row[0].add(scrollerD);
    add(row[0]);

    row[1].add(scrollerM);
    add(row[1]);


    row[2].add(button[0]);
    row[2].add(button[1]);
    add(row[2]);

    row[3].add(button[2]);
    row[3].add(keyIn);
    row[3].add(button[3]);
    add(row[3]);

    setVisible(true);



/*  public final void setDesign()
    
        try
        
        UIManager.setLookAndFeel(
                "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        
        catch(Exception e)
        
        
    
*/  
    public void actionPerformed(ActionEvent ae)
    

         if(ae.getSource() == button[0])
         


         

         if(ae.getSource() == button[1])
         
             display.setText("Test");
         
    

    public void clear()
    
        try
        
            display.setText("");
        
        catch(NullPointerException e)
        
        
    

    public void outd()
    
        display.setText("");
    

【问题讨论】:

你的代码看起来有点乱,但我会帮你清理一下 GridLayout 就是这样工作的…… 【参考方案1】:

可以使用 GridLayout(int rows, int cols, int hgap, int vgap) 构造函数调整 1 行与另一行之间的间隙。

https://docs.oracle.com/javase/7/docs/api/java/awt/GridLayout.html 可以在此处找到有关网格布局的更多信息。

【讨论】:

【参考方案2】:

这就是GridLayout 的工作方式,每个单元格都被赋予完全相同的空间量。相反,请尝试使用类似GridBagLayout...

GridBagLayout grid = new GridBagLayout();
setLayout(grid);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;

//...

row[0].add(scrollerD);
add(row[0], gbc);

row[1].add(scrollerM);
add(row[1], gbc);

row[2].add(button[0]);
row[2].add(button[1]);
add(row[2], gbc);

row[3].add(button[2]);
row[3].add(keyIn);
row[3].add(button[3]);
add(row[3], gbc);

import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class WindowWin extends JFrame implements ActionListener 

    JPanel[] row = new JPanel[4];
    JButton[] button = new JButton[4];
    String[] buttonString = "Copy to Clipboard", "Go", "Back", "Info";

    int[] dimW = 400, 200, 65;
    int[] dimH = 40, 100;

    Dimension keyDim = new Dimension(dimW[0], dimH[0]);
    Dimension displayDimension = new Dimension(dimW[0], dimH[1]);
    Dimension butDim = new Dimension(dimW[1], dimH[0]);
    Dimension infoDim = new Dimension(dimW[2], dimH[0]);

    JEditorPane display = new JEditorPane();
    Font font = new Font("Times new Roman", Font.PLAIN, 14);

    JTextField keyIn = new JTextField(24);
    JEditorPane msgIn = new JEditorPane();

    JScrollPane scrollerD = new JScrollPane(display, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    JScrollPane scrollerM = new JScrollPane(msgIn, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

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

                WindowWin c = new WindowWin();
            
        );
    

    WindowWin() 
        super("Test");

//  setDesign();
        //setSize(380,250);
//        setSize(460, 500);

//        setResizable(true);

        setDefaultCloseOperation(EXIT_ON_CLOSE);

//        GridLayout grid = new GridLayout(4, 3);
        GridBagLayout grid = new GridBagLayout();
        setLayout(grid);
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.fill = GridBagConstraints.HORIZONTAL;

        FlowLayout f1 = new FlowLayout(FlowLayout.CENTER);
        FlowLayout f2 = new FlowLayout(FlowLayout.CENTER, 1, 1);
        //FlowLayout South

        for (int i = 0; i < 4; i++) 
            row[i] = new JPanel();
        

        row[0].setLayout(f1);

        for (int i = 1; i < 4; i++) 
            row[i].setLayout(f2);
        

        for (int i = 0; i < 4; i++) 
            button[i] = new JButton();
            button[i].setText(buttonString[i]);
            button[i].setFont(font);
            button[i].addActionListener(this);
        

        display.setFont(font);
        display.setEditable(false);
        display.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
        display.setPreferredSize(displayDimension);

        keyIn.setFont(font);
        keyIn.setEditable(true);
        keyIn.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
        keyIn.setPreferredSize(keyDim);

        msgIn.setFont(font);
        msgIn.setEditable(true);
        msgIn.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
        msgIn.setPreferredSize(displayDimension);

        for (int i = 0; i < 2; i++) 
            button[i].setPreferredSize(butDim);
        
        for (int i = 2; i < 4; i++) 
            button[i].setPreferredSize(infoDim);
        

        row[0].add(scrollerD);
        add(row[0], gbc);

        row[1].add(scrollerM);
        add(row[1], gbc);

        row[2].add(button[0]);
        row[2].add(button[1]);
        add(row[2], gbc);

        row[3].add(button[2]);
        row[3].add(keyIn);
        row[3].add(button[3]);
        add(row[3], gbc);

        pack();
        setLocationRelativeTo(null);
        setVisible(true);

    

    /*  public final void setDesign()
     
     try
     
     UIManager.setLookAndFeel(
     "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
     
     catch(Exception e)
     
     
     
     */
    public void actionPerformed(ActionEvent ae) 

        if (ae.getSource() == button[0]) 

        

        if (ae.getSource() == button[1]) 
            display.setText("Test");
        
    

    public void clear() 
        try 
            display.setText("");
         catch (NullPointerException e) 
        
    

    public void outd() 
        display.setText("");
    

您还应该使用pack 而不是setSize,这将考虑到每种外观/平台可能具有的不同框架边框,并使用布局管理器API,它做得更好,并考虑到渲染之间的差异平台...

你可能想看看:

Laying Out Components Within a Container Initial Threads

...更多详情

【讨论】:

以上是关于JFrame 中的 JTextField 在实际文本字段之外占用了太多空间的主要内容,如果未能解决你的问题,请参考以下文章

如何为 JTextField 设置动态宽度?

Java jFrame toBack() 和可聚焦

人品计算器 JFrame 窗体软件版 JPanel JTextField JTextArea JButtton JLabel setContentPane

在设置可见之前向 JFrame 添加内容

java:限制swing中的JTextField只能输入中文,字母,数字。

单击时在 Java 中添加类似动态文本区域的对象