使用JPanel在GUI中相互覆盖图层 [英] Layers overriding each other in GUI using JPanel

查看:140
本文介绍了使用JPanel在GUI中相互覆盖图层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法制作简单计算器的布局。发生的事情是,除了我的减去按钮保留为背景之外,一切看起来都很好,我必须猜测我的其他按钮能够点击它们的位置。当我点击它们时,我能够看到它们,直到我取消它们。有没有什么办法解决这一问题?我不会发布这个问题所不需要的数学算法。

I am having trouble making the layout of a simple Calculator. What is happening is that everything appears fine except that my subtract button stays as the background and I have to guess where my other buttons are to be able to click them. When I click them I am able to see them until I unclick them. is there anyway to fix this? I'm not posting the math algorithm a it is not needed for this question.

import javax.swing.*;

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

public class GUIcalc extends JFrame implements ActionListener {

    private JPanel panel;
    private JPanel buttonpanel;
    private JPanel text;
    private JLabel sumfield;
    private BorderLayout layout;
    private GridLayout grid;
    private Container container;
    private boolean toggle=true;
    private float sum;
    private int num1;
    private int num2;
    JButton one = new JButton("1");
    JButton two = new JButton("2");
    JButton three = new JButton("3");
    JButton four = new JButton("4");
    JButton five = new JButton("5");
    JButton six = new JButton("6");
    JButton seven = new JButton("7");
    JButton eight = new JButton("8");
    JButton nine = new JButton("9");
    JButton zero = new JButton("0");
    JButton multi = new JButton("*");
    JButton divide = new JButton("/");
    JButton equal = new JButton("=");
    JButton add = new JButton("+");
    JButton subtract = new JButton("-");
    JButton deci = new JButton("."); 
    private final Font number= new Font("monspaced", Font.ITALIC, 20);
    JFrame guiFrame;
    private int counter;

    /**
     * @param args
     */
    public GUIcalc() {

        super("Calculator");    
        sumfield = new JLabel(""+sum);
        sumfield.setLocation(0, 0);
        sumfield.setSize(245, 45);
         add(sumfield);
        seven=new JButton("7");
        seven.setLocation(0,50);
        seven.setSize(50, 50);
        seven.addActionListener(this);
        add(seven);
        eight=new JButton("8");
        eight.setLocation(55,50);
        eight.setSize(50, 50);
        eight.addActionListener(this);
        add(eight);
        nine=new JButton("9");
        nine.setLocation(110,50);
        nine.setSize(50, 50);
        nine.addActionListener(this);
        add(nine);
        divide=new JButton("/");
        divide.setLocation(165,50);
        divide.setSize(50, 50);
        divide.addActionListener(this);
        add(divide);
        six=new JButton("6");
        six.setLocation(0,105);
        six.setSize(50, 50);
        six.addActionListener(this);
        add(six);
        five=new JButton("5");
        five.setLocation(55,105);
        five.setSize(50, 50);
        five.addActionListener(this);
        add(five);  
        four=new JButton("4");
        four.setLocation(110,105);
        four.setSize(50, 50);
        four.addActionListener(this);
        add(four);
        multi=new JButton("*");
        multi.setLocation(165,105);
        multi.setSize(50, 50);
        multi.addActionListener(this);
        add(multi);
        three=new JButton("3");
        three.setLocation(0,165);
        three.setSize(50, 50);
        three.addActionListener(this);
        add(three);
        two=new JButton("2");
        two.setLocation(55,165);
        two.setSize(50, 50);
        two.addActionListener(this);
        add(two);
        one=new JButton("1");
        one.setLocation(110,165);
        one.setSize(50, 50);
        one.addActionListener(this);
        add(one);
        add=new JButton("+");
        add.setLocation(165,165);
        add.setSize(50, 50);
        add.addActionListener(this);
        add(add);
        zero=new JButton("0");
        zero.setLocation(0,220);
        zero.setSize(50, 50);
        zero.addActionListener(this);
        add(zero);      
        deci=new JButton(".");
        deci.setLocation(55,220);
        deci.setSize(50, 50);
        deci.addActionListener(this);
        add(deci);
        equal=new JButton("=");
        equal.setLocation(110,220);
        equal.setSize(50, 50);
        equal.addActionListener(this);
        add(equal);
        subtract=new JButton("-");
        subtract.setLocation(165,220);
        subtract.setSize(50, 50);
        subtract.addActionListener(this);
        add(subtract);
   }


推荐答案

你的问题是那个您正尝试在使用BorderLayout(JFrame的contentPane)的容器中设置组件的绝对位置和大小。快速简便的解决方案是通过 setLayout(null)使JFrame contentPane的布局为空

You're problem is that you're trying to set the absolute location and size of components in a container that uses BorderLayout (the JFrame's contentPane). The quick and easy solution is to make the JFrame contentPane's layout null via setLayout(null)

虽然这很快它很容易,它也有效,它也是错误的,因为它迫使你创建在一个平台上以某种屏幕分辨率看起来很好的刚性GUI,在其他分辨率或其他平台上看起来很糟糕,几乎不可能根据需要进行修改。更好的解决方案是使用布局管理器。请等一下这个例子....

While this is quick and easy, and it works, it's also wrong because it forces you to create rigid GUI's that might look good on one platform at a certain screen resolution, it looks terrible at other resolutions or on other platforms and is near impossible to modify as needed. A better solution is to use the layout managers to your advantage. Hold on for an example of this....

编辑

例如,如果...

Edit
For example what if...


  • 您的主GUI使用BorderLayout

  • 您添加了您的JTextField将数字显示到主GUI BorderLayout.NORTH,也称为BorderLayout.PAGE_START

  • 为按钮创建一个JPanel,比如称为btnPanel,并将其添加到主GUI BorderLayout。 CENTER。

  • 给btnPanel一个GridLayout大小以接受所有按钮。

  • 在创建它们时将JButtons添加到btnPanel。

  • 不是设置JButton的大小,而是为什么不设置更大的字体,让按钮和GUI大小本身以容纳更大的字体。

  • Your main GUI used a BorderLayout
  • You added your JTextField that displays the numbers to the main GUI BorderLayout.NORTH also known as BorderLayout.PAGE_START
  • Create a JPanel for the buttons, say called btnPanel, and add it to the main GUI BorderLayout.CENTER.
  • Give the btnPanel a GridLayout sized to accept all the buttons.
  • Add the JButtons to the btnPanel as you create them.
  • Rather than setting the sizes of the JButtons, why not instead set the font larger, and let the buttons and the GUI size themselves to accommodate the larger fonts.

例如,以这种方式完成的代码如下所示:

For example, code done this way would look like:

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;

import javax.swing.*;

public class GUIcalc2 extends JPanel {
   private static final String[][] BTN_TEXTS = { 
      { "7", "8", "9", "/" },
      { "6", "5", "4", "*" }, 
      { "3", "2", "1", "+" }, 
      { "0", ".", "=", "-" } };
   private static final int GAP = 3;
   private static final float TF_SIZE = 18f;
   private static final float BTN_SIZE = 24f;
   private JButton[][] buttons = new JButton[BTN_TEXTS.length][BTN_TEXTS[0].length];
   private JTextField textField = new JTextField(10);

   public GUIcalc2() {
      textField.setFont(textField.getFont().deriveFont(TF_SIZE));
      JPanel btnPanel = new JPanel(new GridLayout(BTN_TEXTS.length, 
            BTN_TEXTS[0].length, GAP, GAP));
      for (int row = 0; row < BTN_TEXTS.length; row++) {
         for (int col = 0; col < BTN_TEXTS[0].length; col++) {
            JButton btn = new JButton(BTN_TEXTS[row][col]);
            // add ActionLIstener here
            btn.setFont(btn.getFont().deriveFont(Font.BOLD, BTN_SIZE));
            btnPanel.add(btn);

            buttons[row][col] = btn;
         }
      }

      setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
      setLayout(new BorderLayout(GAP, GAP));
      add(textField, BorderLayout.PAGE_START);
      add(btnPanel, BorderLayout.CENTER);
   }

   private static void createAndShowGui() {
      GUIcalc2 mainPanel = new GUIcalc2();

      JFrame frame = new JFrame("Calc");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

现在为了使用布局管理器的代码之美,假设您现在想要在顶部添加一行按钮来执行内存功能,例如内存清除,内存替换,内存添加,...所有您需要做的事情(从GUI视图的角度来看)是添加另一行字符串常量:

Now for the beauty of code that uses layout managers, say you now want to add a row of buttons at the top that does memory functions such as memory clear, memory replace, memory add to,... all you need to do (from the GUI view standpoint) is to add another row of String constants:

private static final String[][] BTN_TEXTS = { 
   {"MC", "MR", "MS", "M+"},  // new line !
   { "7", "8", "9", "/" },
   { "6", "5", "4", "*" }, 
   { "3", "2", "1", "+" }, 
   { "0", ".", "=", "-" } };

这样做和GUI机会:

并注意到所有按钮调整大小以允许包含在顶行中的较大文本字符串,并且他们执行此操作而无需编写任何其他代码来执行此操作。

And notice that all the buttons resize to allow for the larger text Strings contained in the top row, and they do this without having to write any additional code to do this.

尝试执行与您的代码类似的东西,并注意您必须更改所添加组件的右侧或右侧的所有组件的位置,以及错误和错误的风险成倍增加。

Try to do something similar with your code, and notice that you'll have to change the positions of all components that are under or to the right of the added components, and the risks of errors and bugs multiply.

当然你还需要添加逻辑代码,但这是另一个讨论的主题。

Of course you still need to add the logic code, but that's the subject of another discussion.

这篇关于使用JPanel在GUI中相互覆盖图层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆