2017-06-21 139 views
3

我正在用Swing制作一个计算器来练习,而我无法弄清楚为什么我在JButton行的边缘和父JPanel的边缘(buttonPanel)之间存在这个间隙。我翻遍了我的代码并改变了一些东西,但我仍然无法弄清楚为什么差距在那里。如果我删除了MatteBorder,将边框保留为默认值,则间隔消失,但是我会在按钮之间有两个边框。如果我将我的JTextField的列大小缩小到7,那么差距就会消失。我怎样才能解决这个问题,而不必诉诸于双重边界或缩小我的应用程序呢?如何删除JButton行边缘和父JPanel边缘之间的间隙?

calculator

(我设置面板红色的背景,以帮助确定哪些部件是造成差距。)

public class CalculatorView extends JFrame { 
    // NOTE: Not recommended to extend JFrame, recommended to use composition over inheritance 
    private JTextField display = new JTextField("0", 17); 

    // Number buttons 
    private JButton zeroButton = new JButton("0"); 
    private JButton oneButton = new JButton("1"); 
    private JButton twoButton = new JButton("2"); 
    private JButton threeButton = new JButton("3"); 
    private JButton fourButton = new JButton("4"); 
    private JButton fiveButton = new JButton("5"); 
    private JButton sixButton = new JButton("6"); 
    private JButton sevenButton = new JButton("7"); 
    private JButton eightButton = new JButton("8"); 
    private JButton nineButton = new JButton("9"); 
    private JButton periodButton = new JButton("."); 

    // Operation buttons 
    private JButton additionButton = new JButton("+"); 
    private JButton subtractionButton = new JButton("-"); 
    private JButton divisionButton = new JButton("÷"); 
    private JButton multiplicationButton = new JButton("x"); 
    private JButton signChangeButton = new JButton("+/-"); 
    private JButton percentButton = new JButton("%"); 
    private JButton clearButton = new JButton("AC"); 
    private JButton equalButton = new JButton("="); 

    CalculatorView() { 
     // Set the look and feel to the cross-platform look and feel, 
     // otherwise mac os will have quirks like gaps between jbuttons 
     try { 
      UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); 
     } catch (Exception e) { 
      System.err.println("Unsupported look and feel."); 
      e.printStackTrace(); 
     } 
     // Let the OS set location, prevent user from resizing window, and exit app on close 
     this.setLocationByPlatform(true); 
     this.setResizable(false); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setUndecorated(true); // must be undecorated for setbackground to work 

     // Create the main panel, which by default covers the entire frame 
     // NOTE: Good practice. Never put components directly onto a JFrame. 
     JPanel gui = new JPanel(); 
     // Set the main panel's layout manager to BorderLayout 
     gui.setLayout(new BorderLayout()); 

     // Create the button panel 
     JPanel buttonPanel = new JPanel(); 
     // Set button panel's layout manager to GridBagLayout 
     buttonPanel.setLayout(new GridBagLayout()); 
     // Create a GridBagConstraints object to control the layout of components 
     GridBagConstraints c = new GridBagConstraints(); 
     c.insets = new Insets(0, 0, 0, 0); 
     c.fill = GridBagConstraints.HORIZONTAL; 

     // Position buttons on the grid 
     c.gridx = 0; 
     c.gridy = 0; 
     c.ipady = 30; // adjust vertical height of buttons 
     c.weightx = 1; // needed or buttons will cluster at center w/ gap on sides 
     buttonPanel.add(clearButton, c); 
     clearButton.setBackground(Color.gray); 
     clearButton.setOpaque(true); 
     clearButton.setBorder(new MatteBorder(0, 1, 0, 1, Color.BLACK)); 
     c.gridx = 1; 
     buttonPanel.add(signChangeButton, c); 
     signChangeButton.setBackground(Color.gray); 
     signChangeButton.setOpaque(true); 
     signChangeButton.setBorder(new MatteBorder(0, 0, 0, 1, Color.BLACK)); 
     c.gridx = 2; 
     buttonPanel.add(percentButton, c); 
     percentButton.setBackground(Color.gray); 
     percentButton.setOpaque(true); 
     percentButton.setBorder(new MatteBorder(0, 0, 0, 1, Color.BLACK)); 
     c.gridx = 3; 
     buttonPanel.add(divisionButton, c); 
     divisionButton.setBackground(Color.ORANGE); 
     divisionButton.setOpaque(true); 
     divisionButton.setBorder(new MatteBorder(0, 0, 0, 1, Color.BLACK)); 
     c.gridx = 0; 
     c.gridy = 1; 
     buttonPanel.add(sevenButton, c); 
     sevenButton.setBorder(new MatteBorder(1, 1, 0, 1, Color.BLACK)); 
     c.gridx = 1; 
     buttonPanel.add(eightButton, c); 
     eightButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK)); 
     c.gridx = 2; 
     buttonPanel.add(nineButton, c); 
     nineButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK)); 
     c.gridx = 3; 
     buttonPanel.add(multiplicationButton, c); 
     multiplicationButton.setBackground(Color.ORANGE); 
     multiplicationButton.setOpaque(true); 
     multiplicationButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK)); 
     c.gridx = 0; 
     c.gridy = 2; 
     buttonPanel.add(fourButton, c); 
     fourButton.setBorder(new MatteBorder(1, 1, 0, 1, Color.BLACK)); 
     c.gridx = 1; 
     buttonPanel.add(fiveButton, c); 
     fiveButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK)); 
     c.gridx = 2; 
     buttonPanel.add(sixButton, c); 
     sixButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK)); 
     c.gridx = 3; 
     buttonPanel.add(subtractionButton, c); 
     subtractionButton.setBackground(Color.ORANGE); 
     subtractionButton.setOpaque(true); 
     subtractionButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK)); 
     c.gridx = 0; 
     c.gridy = 3; 
     buttonPanel.add(oneButton, c); 
     oneButton.setBorder(new MatteBorder(1, 1, 0, 1, Color.BLACK)); 
     c.gridx = 1; 
     buttonPanel.add(twoButton, c); 
     twoButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK)); 
     c.gridx = 2; 
     buttonPanel.add(threeButton, c); 
     threeButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK)); 
     c.gridx = 3; 
     buttonPanel.add(additionButton, c); 
     additionButton.setBackground(Color.ORANGE); 
     additionButton.setOpaque(true); 
     additionButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK)); 
     c.gridx = 0; 
     c.gridy = 4; 
     c.gridwidth = 2; // spans 2 cells 
     buttonPanel.add(zeroButton, c); 
     zeroButton.setBorder(new MatteBorder(1, 1, 1, 1, Color.BLACK)); 
     c.gridx = 2; 
     c.gridwidth = 1; 
     buttonPanel.add(periodButton, c); 
     periodButton.setBorder(new MatteBorder(1, 0, 1, 1, Color.BLACK)); 
     c.gridx = 3; 
     buttonPanel.add(equalButton, c); 
     equalButton.setBackground(Color.ORANGE); 
     equalButton.setOpaque(true); 
     equalButton.setBorder(new MatteBorder(1, 0, 1, 1, Color.BLACK)); 

     // Customize display field 
     display.setHorizontalAlignment(JTextField.RIGHT); 
     display.setFont(new Font("Arial", Font.PLAIN, 40)); 
     display.setBorder(new EmptyBorder(30, 0, 0, 0)); 
     display.setForeground(Color.WHITE); 
     // Make display translucent but leave button panel opaque 
     this.setBackground(new Color(0, 0, 0, 100)); 
     gui.setBackground(new Color(0,0,0,100)); 
     display.setBackground(new Color(0, 0, 0, 100)); 

     // I need to fix the gap between the edge of the buttonPanel and the buttons... 
     buttonPanel.setBackground(Color.red); 

     // Add display and button panel to main panel, then main panel to frame 
     gui.add(display, BorderLayout.NORTH); 
     gui.add(buttonPanel, BorderLayout.CENTER); 
     this.add(gui); 
     this.pack(); 
    } 
} 
+2

(在某些情况下)布局管理不能分割奇数,(师的结果以像素为单位),那么结果可以是/是小的边界... – mKorbel

回答

2

我不知道为什么会出现这种差距,但如果你设置以下的空边框,背景消失:

JPanel buttonPanel = new JPanel(); 
// Set button panel's layout manager to GridBagLayout 
buttonPanel.setLayout(new GridBagLayout()); 
buttonPanel.setBorder(new EmptyBorder(0, -1, 0, -1)); 
+0

谢谢,它的工作!这个差距可能是由于某个地方出现了一个奇数字,并且带有Matte Border插入符号,就像@mKorbel上面所说的那样。 – briennakh

+0

一个相关的,有趣的观察:有了这个空的边界和负插入,我可以将JTextField的大小设置为奇数,否则间隙会重新出现(我可以通过重新调整插入来修复)。 – briennakh

0

检查每一个Y轴为GridBagConstraints的分配填充声明即

c.ipady = 30; 

试图删除它们或减少它们