Layers overriding each other in GUI using JPanel

大城市里の小女人 提交于 2019-12-10 00:16:35

问题


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

回答1:


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)

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...

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

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", ".", "=", "-" } };

Do this and the GUI chances to:

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.



来源:https://stackoverflow.com/questions/25945061/layers-overriding-each-other-in-gui-using-jpanel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!