0

I am a student trying to figure out the basics of Java's graphics. My class creates a window where a single red button will move every time it is pressed. I set the bounds of the window to 720x720 and the button is 50 pixels wide. Everytime it is pressed, the button goes to a new x and y coordinate that is between 0 and 670. My understanding is that if the setBounds() method is called with the parameters (670,670,50,50) then my red button will occupy the bottom right corner of the window.

Unfortunately, the button seems to be going outside of the window even when the bounds are set to something like (660,660,50,50).

Problem

I have tried tracking the bounds by printing every change in coordinates but this still does not add up.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Custom extends JPanel
{
   //fields
   private int kovakx = 0, kovaky = 0; //stores x and y coordinates of the button
   private double accuracy_percent = 100; //not used yet

   private JButton kovak = new JButton();

   //Only ActionListener this program needs since theres only one button that moves around the screen.
   private class Elim implements ActionListener
   {
      public void actionPerformed(ActionEvent e)
      {
         kovakx = (int)(Math.random()*670);
         kovaky = (int)(Math.random()*670);
         kovak.setBounds(kovakx,kovaky,50,50);
         System.out.println(kovakx+","+kovaky);//prints out the new coordinates of the button
      }
   }

   //Constructor sets icon and initally puts the button in the top left corner
   public Custom()
   {
      kovak.setIcon(new ImageIcon("Target.png"));
      setLayout(null);
      kovak.setBounds(0,0,50,50);
      kovak.addActionListener(new Elim());
      add(kovak);
   }

   //Creates frame based on teacher's tutorials.
   public static void main(String args[])
   {
      Custom a = new Custom();
      JFrame f = new JFrame("Reaction and Accuracy Test");
      f.setSize(720,720);
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.add(a);
      f.setVisible(true);
   } 
}
Mithran M
  • 5
  • 3
  • You are setting the size of the frame but you are painting on the Panel - The things will always go outside of bounds - so what exactly are you trying to do? cant you be satisfied with drawing in the middle?? – gpasch Apr 12 '19 at 18:43

1 Answers1

0

You set the frame size, but are never setting the size on Custom. If you call getSize() on Custom, it returns (0,0). So what is happening I think is that the frame really is (720,720) in size, but that includes the area of the decorations (such as title bar) and frame borders. The effective area inside the frame is smaller, which is why you cannot see the entire button.

The solution is either to determine the actual area inside the frame, or to adjust the frame so that the area inside is (720,720).

To adjust the frame so the inner size is (720,720), the usual way is to set the component size and then pack the frame:

In main,

f.add(a);
a.setPreferredSize(720,720);   // set desired size of JPanel
f.pack();                      // resize frame to fit around its contents
f.setVisible(true);

It is not necessary to call frame.setSize() if you are calling pack(), because pack will set the size automatically. Note that it you call pack without calling setPreferredSize(), the frame will be a tiny zero-size frame that may be hard to see. If you run the program and don't see anything that is the likely problem.

Getting the frame size without the decorations is a little more complicated. See the part about getInsets() in JFrame: get size without borders?

Alcamtar
  • 1,478
  • 13
  • 19
  • That was it! I don't mind the Frame being hard too see. I am going to make the window unscalable anyway. – Mithran M Apr 12 '19 at 19:02