简体   繁体   中英

JButton does not appear on the GUI

when I compile and run my code everything seems to work fine except the JButton does not appear. I'm adding it to a JPanel that is on the frame. I'm new so I might not know what to lookout for here. Thanks!

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

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;

public class TemperatureConverter extends JFrame{

    //declarations
    private JLabel celJLabel, farJLabel;

    private JTextField celJTextField, farJTextField;

    private JSlider sliderJSlider;

    private JButton closeButton;

    private TitledBorder border;

    private JPanel topPanel, bottomPanel;

    double celsiusDegrees, farenheitDegrees, sliderValue;

    DecimalFormat decimalFormat = new DecimalFormat("#.0");

    public TemperatureConverter()
    {
        createUserInterface();
    }

    public void createUserInterface()
    {
        //create the JFrame
        Container frame = getContentPane();
        frame.setBackground(Color.white);
        frame.setLayout(null);

        border = new TitledBorder("Convert between C & F");
        border.setTitleColor(Color.black);
        border.setTitleFont(new Font("Default", Font.ITALIC, 12));
        border.setTitleJustification(TitledBorder.LEFT);
        border.setTitlePosition(TitledBorder.TOP);

        topPanel = new JPanel();
        topPanel.setBounds(20,10,360,300);
        topPanel.setForeground(Color.black);
        topPanel.setBackground(Color.white);
        topPanel.setLayout(null);
        topPanel.setBorder(border);
        frame.add(topPanel);

        bottomPanel = new JPanel();
        bottomPanel.setBounds(20,310,360,50);
        bottomPanel.setForeground(Color.black);
        bottomPanel.setBackground(Color.white);
        bottomPanel.setLayout(null);
        frame.add(bottomPanel);

        celJLabel = new JLabel();
        celJLabel.setBounds(120, 200, 60, 20);
        celJLabel.setBackground(Color.white);
        celJLabel.setFont(new Font("Default", Font.PLAIN, 12));
        celJLabel.setText("Celcius");
        celJLabel.setHorizontalAlignment(JLabel.LEFT);
        topPanel.add(celJLabel);

        farJLabel = new JLabel();
        farJLabel.setBounds(120, 220, 60, 20);
        farJLabel.setBackground(Color.white);
        farJLabel.setFont(new Font("Default", Font.PLAIN, 12));
        farJLabel.setText("Faranheit");
        farJLabel.setHorizontalAlignment(JLabel.LEFT);
        topPanel.add(farJLabel);

        celJTextField = new JTextField();
        celJTextField.setBounds(195,200, 50, 15);
        celJTextField.setFont(new Font("Default", Font.PLAIN, 12));
        celJTextField.setHorizontalAlignment(JTextField.CENTER);
        celJTextField.setForeground(Color.black);
        celJTextField.setBackground(Color.white);
        topPanel.add(celJTextField);

        farJTextField = new JTextField();
        farJTextField.setBounds(195,225, 50, 15);
        farJTextField.setFont(new Font("Default", Font.PLAIN, 12));
        farJTextField.setHorizontalAlignment(JTextField.CENTER);
        farJTextField.setForeground(Color.black);
        farJTextField.setBackground(Color.white);
        topPanel.add(farJTextField);

        sliderJSlider = new JSlider(JSlider.HORIZONTAL, 0,100,0);
        sliderJSlider.setBounds(20, 20, 310, 120);
        sliderJSlider.setMajorTickSpacing(10);
        sliderJSlider.setMinorTickSpacing(5);
        sliderJSlider.setPaintTicks(true);
        sliderJSlider.setPaintLabels(true);
        sliderJSlider.setForeground(Color.black);
        sliderJSlider.setBackground(Color.white);
        topPanel.add(sliderJSlider);
        sliderJSlider.addChangeListener( 
                new ChangeListener()
                {
                    public void stateChanged(ChangeEvent event)
                    {
                        sliderStateChanged(event);
                    }       
                }

                );

        closeButton = new JButton();
        closeButton.setBounds(140, 250, 75, 20);
        closeButton.setFont(new Font("Default", Font.PLAIN,12));
        closeButton.setText("Close");
        closeButton.setForeground(Color.black);
        closeButton.setBackground(Color.white);
        bottomPanel.add(closeButton);
        closeButton.addActionListener(

            new ActionListener()
            {
                public void actionPerformed(ActionEvent event)
                {
                    closeActionPerformed(event);
                }
            }
            );

        setTitle("Temperature Converter");
        setSize(400,400);
        setVisible(true);

    }   
    public static void main(String[] args)
    {
        TemperatureConverter application = new TemperatureConverter();
        application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void sliderStateChanged(ChangeEvent event)
    {
        farenheitDegrees = sliderJSlider.getValue();
        calculateCelsiusTemperature();

    }
    public void calculateCelsiusTemperature()
    {
        celsiusDegrees = (farenheitDegrees - 32)*5.0/9.0;
        outputTemps();
    }
    public void outputTemps()
    {
        celJTextField.setText(decimalFormat.format(celsiusDegrees));
        farJTextField.setText(decimalFormat.format(farenheitDegrees));
    }
    public void closeActionPerformed(ActionEvent event)
    {
        TemperatureConverter.this.dispose();
    }

    }

I'd follow the advice from the comments, use a proper layout manager .

The actual fault, is the placement of the close button within the bottom panel.

closeButton.setBounds(140, 250, 75, 20);

This might be a typo or a misunderstanding of the coordinate system, each new panel has its own private system where (0,0) is the top left of at component. The button is at (140, 250), however bottomPanel is only 360 x 50, so it is outside the visible bounds..

Try changing to

closeButton.setBounds(0, 0, 75, 20);

Your first and major mistake is this: topPanel.setLayout(null); . While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.

The solution is simple: learn about and how to use the layout managers, and then use them. You can find links to the Swing tutorials including those for the layout managers and other Swing resources here: Swing Info


eg,

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.*;

public class TempConverter extends JPanel {
   private static final int PREF_W = 400;
   private static final int GAP = 5;
   private JTextField celJTextField = new JTextField(10);
   private JTextField farJTextField = new JTextField(10);
   private JSlider sliderJSlider = new JSlider(0, 100, 0);
   private JButton closeButton = new JButton("Close");

   public TempConverter() {
      sliderJSlider.setMajorTickSpacing(10);
      sliderJSlider.setMinorTickSpacing(5);
      sliderJSlider.setPaintTicks(true);
      sliderJSlider.setPaintLabels(true);

      JPanel textFieldPanel = new JPanel(new GridBagLayout());
      textFieldPanel.add(new JLabel("Celcius:"), createGbc(0, 0));
      textFieldPanel.add(celJTextField, createGbc(1, 0));
      textFieldPanel.add(new JLabel("Faranheit:"), createGbc(0, 1));
      textFieldPanel.add(farJTextField, createGbc(1, 1));
      JPanel textFieldWrapperPanel = new JPanel(new GridBagLayout());
      textFieldWrapperPanel.add(textFieldPanel);

      JPanel conversionPanel = new JPanel(new BorderLayout());
      conversionPanel.setBorder(BorderFactory.createTitledBorder("Foo"));
      conversionPanel.setLayout(new BorderLayout());
      conversionPanel.add(sliderJSlider, BorderLayout.PAGE_START);
      conversionPanel.add(textFieldWrapperPanel, BorderLayout.CENTER);

      JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
      bottomPanel.add(closeButton);

      setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
      setLayout(new BorderLayout());
      add(conversionPanel, BorderLayout.CENTER);
      add(bottomPanel, BorderLayout.PAGE_END);
   }

   private GridBagConstraints createGbc(int x, int y) {
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = x;
      gbc.gridy = y;
      gbc.gridheight = 1;
      gbc.gridwidth = 1;
      gbc.weightx = 1.0;
      gbc.weighty = 1.0;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      gbc.insets = new Insets(GAP, GAP, GAP, GAP);

      return gbc;
   }

   @Override
   public Dimension getPreferredSize() {
      Dimension superSize = super.getPreferredSize();
      ;
      if (isPreferredSizeSet()) {
         super.getPreferredSize();
      }
      int prefW = Math.max(PREF_W, superSize.width);
      return new Dimension(prefW, superSize.height);
   }

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

      JFrame frame = new JFrame("TempConverter");
      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 you might say that this looks more complicated, and perhaps it is, but what happens when you want to add another JTextField and JLabel to represent the Kelvin temperature scale? For your GUI, you'll need to resize the GUI and recalculate the position of any component that may be effected by adding the new components. For my GUI, you just need to add a few new lines, and the chance of the changes causing a bug in my code is much smaller than that of your changes. eg please note the changes below just require 3 lines of code. Everything else remains the same:

public class TempConverter extends JPanel {
   private static final int PREF_W = 400;
   private static final int GAP = 5;
   private JTextField celJTextField = new JTextField(10);
   private JTextField farJTextField = new JTextField(10);
   private JTextField KelvinJTextField = new JTextField(10); // !!! Added
   private JSlider sliderJSlider = new JSlider(0, 100, 0);
   private JButton closeButton = new JButton("Close");

   public TempConverter() {
      sliderJSlider.setMajorTickSpacing(10);
      sliderJSlider.setMinorTickSpacing(5);
      sliderJSlider.setPaintTicks(true);
      sliderJSlider.setPaintLabels(true);

      JPanel textFieldPanel = new JPanel(new GridBagLayout());
      textFieldPanel.add(new JLabel("Celcius:"), createGbc(0, 0));
      textFieldPanel.add(celJTextField, createGbc(1, 0));
      textFieldPanel.add(new JLabel("Faranheit:"), createGbc(0, 1));
      textFieldPanel.add(farJTextField, createGbc(1, 1));

      // !!! added
      textFieldPanel.add(new JLabel("Kelvin:"), createGbc(0, 2));
      textFieldPanel.add(KelvinJTextField, createGbc(1, 2));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM