我的布局键盘上的空格按钮大小不会调整大小

Posted

技术标签:

【中文标题】我的布局键盘上的空格按钮大小不会调整大小【英文标题】:Space button size on my layout keyboard won't resize 【发布时间】:2014-04-19 03:28:37 【问题描述】:

我正在开发一个包含键盘的打字应用程序,但我发现调整空格按钮的大小以使其比其他按钮更宽有点困难。这就是我显示和组织布局的方式..

我可以调整整个按钮的大小,但这不是我想要的.. 重点是调整空格键的大小.. :)

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Arrays;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class example extends JFrame 
  
    //Individual keyboard rows  
    String firstRow[] = "~","1","2","3","4","5","6","7","8","9","0","-","+","BackSpace";
    String secondRow[] = "Tab","Q","W","E","R","T","Y","U","I","O","P","[","]","\\";
    String thirdRow[] = "Caps","A","S","D","F","G","H","J","K","L",":","\"","Enter";
    String fourthRow[] = "Shift","Z","X","C","V","B","N","M",",",".","?","   ^" ;
    String fifthRow[]="               " ,"<" ,"v",">" ;
    String strText = "";
    //all keys without shift key press
    String noShift="`1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./";
    //special characters on keyboard that has to be addressed during key press
    String specialChars ="~-+[]\\;',.?";

    //Jbuttons corresponding to each individual rows 
    JButton first[];
    JButton second[];
    JButton third[];
    JButton fourth[];
    JButton fifth[];


    //Driver main method to start the application 
    public static void main(String[] args) 
        //launch typing tutor
        new example().setVisible(true);
    

    // No argument constructor to create frame
    public example()
    
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //set size of the content pane ie frame
        this.getContentPane().setPreferredSize(new Dimension(1200,275));

        initWidgets();
    


    // Method to initialize frame component 
    private void initWidgets()
    

        //set the layout and place component in place and pack it 
        setLayout(new BorderLayout());
        //Various panel for the layout 
        JPanel jpNorth = new JPanel();
        JPanel jpCenter = new JPanel();
        JPanel jpKeyboard = new JPanel();
        JPanel jpNote = new JPanel();
        add( jpNorth, BorderLayout.NORTH);
        add( jpNote);
        add( jpCenter, BorderLayout.CENTER);
        add(jpKeyboard, BorderLayout.SOUTH);

        //layout for keyboard 
        jpKeyboard.setLayout(new GridLayout(5,1));
        //pack the components
        pack();

        //paint first keyboard row  and add it to the keyboard
        first = new JButton[firstRow.length];
        //get the panel for the  row
        JPanel p = new JPanel(new GridLayout(1, firstRow.length));
        for(int i = 0; i < firstRow.length; ++i) 
        
            JButton b= new JButton(firstRow[i]);
            b.setPreferredSize(new Dimension(100,50));
            first[i] = b;
            p.add(first[i]);
        
        jpKeyboard.add(p);

        //paint second keyboard row  and add it to the keyboard
        second = new JButton[secondRow.length];
        //get the panel for the  row
        p = new JPanel(new GridLayout(1, secondRow.length));
        for(int i = 0; i < secondRow.length; ++i) 
        
            second[i] = new JButton(secondRow[i]);
            p.add(second[i]);

        
        jpKeyboard.add(p);

        //paint third keyboard row  and add it to the keyboard
        third = new JButton[thirdRow.length];
        //get the panel for the  row
        p = new JPanel(new GridLayout(1, thirdRow.length));
        for(int i = 0; i < thirdRow.length; ++i)
        
            third[i] = new JButton(thirdRow[i]);
            p.add(third[i]);
        
        jpKeyboard.add(p);

        //paint fourth keyboard row  and add it to the keyboard
        fourth = new JButton[fourthRow.length];
        //get the panel for the  row
        p = new JPanel(new GridLayout(1, fourthRow.length));
        for(int i = 0; i < fourthRow.length; ++i)
        
            fourth[i] = new JButton(fourthRow[i]);
            p.add(fourth[i]);
            if(i==fourthRow.length-2)
                p.add(new JPanel());

        
        p.add(new JPanel());
        jpKeyboard.add(p);

        //paint the fifth row
        fifth = new JButton[fifthRow.length];
        //get the panel for the  row
        p = new JPanel(new GridLayout(1, fifthRow.length));
        //put empty panel for layout adjustments 
        for(int i = 0; i < 1; ++i)
        
            JPanel  spacePanel = new JPanel();
            p.add(spacePanel);
        
        //draw the buttons 
        for(int i = 0; i < fifthRow.length; ++i)
        
            if(i==1) //space bar panel
            
                JButton b = new JButton(fifthRow[i]);
                b.setPreferredSize(new Dimension(400,10));
                b.setBounds(10, 10, 600, 100);
                fifth[i]=b;
                //add empty panels for layout 
                p.add(new JPanel());p.add(new JPanel());p.add(new JPanel());p.add(new JPanel());p.add(new JPanel());p.add(new JPanel());p.add(new JPanel());p.add(new JPanel());
            
            else
            
                fifth[i]=new JButton(fifthRow[i]);
            
            if(i==0) //first black panel
            
                   //place a black panel at first
                   JPanel  spacePanel = new JPanel();
                   p.add(spacePanel);
            
            p.add(fifth[i]);

        
        jpKeyboard.add(p);

         //end of initWidgets   

//end of class

好吧,如果你们中的任何人可以指导我,我将非常感激,如果你们需要任何澄清或更多信息,请告诉我.. :)

【问题讨论】:

您应该在添加所有组件后打包框架 有一个可运行的示例来演示该问题,因为需要翻阅大量非上下文代码:P @MadProgrammer 你的意思是发布整个程序? 不,我建议创建一个可运行的示例来演示您的问题,我们不需要它背后的任何功能 @MadProgrammer 刚刚添加了可运行的示例.. :) 【参考方案1】:

有两个问题,一是您在真正完成构建内容之前调用packpack 使用内容首选大小来计算窗口的大小,这会导致您出现问题,因为内容的(潜在)大小与您想要的不同。它的工作原理取决于您之前调用的setPreferredSize 的使用,您应该避免这样做。

第二个问题是布局管理器的选择。 GridLayout 将根据父容器的可用空间水平和垂直地为容器内的每个组件分配相等的空间。

例如,更好的解决方案可能是使用GridBagLayout

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Example extends JFrame 

    //Individual keyboard rows  
    String firstRow[] = "~", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "+", "fill", "BackSpace";
    String secondRow[] = "Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\";
    String thirdRow[] = "Caps", "A", "S", "D", "F", "G", "H", "J", "K", "L", ":", "\"", "fill", "fill", "Enter";
    String fourthRow[] = "Shift", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "?", "blank", "^";
    String fifthRow[] = "blank", "blank", "fill", "fill", "fill", "fill", "fill", "fill", "fill", "fill", "", "<", "v", ">";

    //Jbuttons corresponding to each individual rows 
    JButton first[];
    JButton second[];
    JButton third[];
    JButton fourth[];
    JButton fifth[];

    //Driver main method to start the application 
    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) 
                

                new Example().setVisible(true);
            
        );
    

    // No argument constructor to create frame
    public Example() 
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        initWidgets();
    

    // Method to initialize frame component 
    private void initWidgets() 

        //set the layout and place component in place and pack it 
        setLayout(new BorderLayout());
        //Various panel for the layout 
        JPanel jpNorth = new JPanel();
        JPanel jpCenter = new JPanel();
        JPanel jpKeyboard = new JPanel(new GridBagLayout());
        JPanel jpNote = new JPanel();
        add(jpNorth, BorderLayout.NORTH);
        add(jpNote);
        add(jpCenter, BorderLayout.CENTER);
        add(jpKeyboard, BorderLayout.SOUTH);

        first = new JButton[firstRow.length];
        second = new JButton[secondRow.length];
        third = new JButton[thirdRow.length];
        fourth = new JButton[fourthRow.length];
        fifth = new JButton[fifthRow.length];

        addKeys(jpKeyboard, 0, firstRow, first);
        addKeys(jpKeyboard, 1, secondRow, second);
        addKeys(jpKeyboard, 2, thirdRow, third);
        addKeys(jpKeyboard, 3, fourthRow, fourth);
        addKeys(jpKeyboard, 4, fifthRow, fifth);

        pack();

     //end of initWidgets   

    protected void addKeys(JPanel parent, int row, String[] keys, JButton[] buttons) 

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridy = row;
        gbc.gridx = 0;
        gbc.fill = GridBagConstraints.BOTH;

        int gap = 0;
        for (int index = 0; index < keys.length; index++) 
            String key = keys[index];
            if ("blank".equalsIgnoreCase(key)) 
                gbc.gridx++;
             else if ("fill".equalsIgnoreCase(key)) 
                gbc.gridwidth++;
                gap++;
             else 
                System.out.println("Add " + key);
                JButton btn = new JButton(key);
                buttons[index] = btn;
                parent.add(btn, gbc);
                gbc.gridx += gap + 1;
                gbc.gridwidth = 1;
                gap = 0;
            
        

    

//end of class

如果您发现答案有用,如果您能将@peeskillet 的答案标记为正确,我将不胜感激,因为他首先回答并发现了一些我没有发现的问题......不过,点赞会很好;)

【讨论】:

您将使用哪个函数来更改键盘示例中按钮的高度和宽度? 我不会。宽度和高度由按钮文本和GridBagConstraints 的要求得出,例如fillgridwidth。如果您“真的”想要更改按钮的大小,请考虑更改边距 谢谢,非常感谢您的帮助。我似乎无法让我的 KeyListener 正常工作。我正在尝试编辑输入的字符串并为其设置背景颜色。不知道你是否愿意帮我解决这个问题?? KeyListener 有焦点问题。它注册到的组件必须是可聚焦的并具有焦点,然后才能响应关键事件。 发布了一个问题,其中包含有关我的问题的更多信息.. 与此帖子无关.. 如果您有兴趣查看它.. 这是链接.. ***.com/questions/22417890/… 【参考方案2】:

pack() 所做的是使用组件的首选尺寸打包框架。您正在做的是pack()ing before 添加组件并设置它们的首选大小,因此pack() 对调用后添加的组件无关紧要(就首选大小而言。所以@987654326 @框架你添加所有组件并设置它们的首选尺寸。

您需要考虑的另一件事是GridLayout 不会尊重组件的首选大小。它实际上会使它们的大小都相同。

请参阅 here 以了解哪些布局管理器尊重首选尺寸。并相应地重组你的代码。正如 MadProgrammer 建议的那样,我会查看GridBagLayout,这样您就可以只使用一个布局管理器。如果你没有这方面的经验,这有点棘手。另一种选择是坚持使用JPanel 的默认FlowLayout 并像您所做的那样嵌套面板。

另请参阅Laying out Components Within a Container 以了解可用的布局管理器以及它们的工作热度。

【讨论】:

嘿,感谢您的帮助,不确定您是否愿意继续提供帮助,我的程序遇到了另一个问题..它关于 KeyListener,我试图更改字符串背景颜色以及何时设置发布回到白色..

以上是关于我的布局键盘上的空格按钮大小不会调整大小的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 自动布局调整大小问题

在 Qt 表单的不同布局中调整按钮大小

在 jQuery Layout Plugin 上调整大小时,放置在调整大小上的按钮会消失

Swift - 大屏幕上的自动布局调整大小按钮

避免 android 软键盘调整布局大小。或回调隐藏视图

Kivi,在布局文件中调整按钮大小