Tony
Tony

Reputation: 78

Why i need to click twice to let my JButton work?

I'm building a program that draws random (User input) rectangles on a JPanel.

Problem 1:

Whenever I type a number in my JTextfield,I need to click twice on the JBUtton for Rectangles to show up.

Problem 2:

When i type a new number in the JTextField the number of that don't show the rectangle but it shows the rectangles I typed in previous.

CODE:

private void init() {

    final int FRAME_WIDHT = 800;
    final int FRAME_HEIGHT = 1000;
    int input = 3;

    JFrame frame = new JFrame();
    frame.setSize(FRAME_WIDHT, FRAME_HEIGHT);
    frame.setTitle("Frame");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    west = new JPanel();
    west.setSize(500, 500);
    west.setBorder(BorderFactory.createLineBorder(Color.black));

    east = new JPanel();
    east.setSize(300, 1000);

    button = new JButton("Add squares");
    field = new JTextField(10);
    button.setSize(100, 50);
    east.add(button);
    east.add(field);
    east.setBorder(BorderFactory.createLineBorder(Color.black));

    button.addActionListener(new java.awt.event.ActionListener() {

        @Override
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            JButton1ActionPerformed(evt);
        }

        public void JButton1ActionPerformed(ActionEvent evt) {

            int aantalRect = Integer.parseInt(field.getText());

            MyDrawing draw = new MyDrawing(aantalRect);

            west.add(draw);
            draw.revalidate();
            draw.repaint();

        }
    });

    frame.add(west, BorderLayout.CENTER);
    frame.add(east, BorderLayout.EAST);

    frame.setResizable(true);
    frame.setVisible(true);

}

public static void main(String[] a) {

    P1027 form = new P1027();

}

}

class MyDrawing extends JPanel {

int input = 0;

public MyDrawing(int i) {

    this.input = i;

}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Random r = new Random();

    setPreferredSize(new Dimension(500, 1000));

    for (int i = 0; i < input; i++) {

        int x = r.nextInt(460);
        int y = r.nextInt(960);

        g.drawRect(x, y, 40, 40);

    }

}

Can any one tell me how to fix that?

Upvotes: 0

Views: 1058

Answers (1)

MasterBlaster
MasterBlaster

Reputation: 968

Problem 1: You're not be seeing the squares being drawn on your MyDrawing JPanel the first time because you are calling the setPreferredSize(...) method, when you really should be overriding the getPreferredSize() method as explained by this answer. It is also possible that they are being drawn off-screen. You set the preferred height of MyDrawing to 1000, which doesn't fit on my laptop's screen (The green line is the border of a MyDrawing).

To fix Problem 1, override the method and lower the preferred height if necessary:

class MyDrawing extends JPanel {

    ... //Constructor

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(500, 500); //Changed from 1000 to 500
    }

    ... //paintComponent(...) 
        //If you change 1000 to 500, don't forget to change 960 to 460 too
} 

Problem 2: You're seeing the amount of rectangles you typed into the JTextField previously because:

  • You are forgetting to remove the previously added MyDrawing from west before adding the new one.
  • You are calling revalidate() and repaint() on draw when you should be calling it on its parent component, west.

To fix problem 2, remove the old MyDrawing from west, add the new one, then call revalidate() and repaint():

...
public void JButton1ActionPerformed(ActionEvent evt) {
    west.removeAll(); //If the old MyDrawing is the only thing 
                      //that has been added to west. Otherwise use
                      //remove(int index) or remove(Component comp)
    west.add(draw);
    west.revalidate();
    west.repaint();
}
...

Other things:

  • You switched the T and H around in FRAME_WIDTH.
  • You could put the code in JButton1ActionPerformed(...) into the actual actionPerformed method.
  • Your JFrame looks exactly the same with and without the calls to setSize(...) on west, east, and button and that answer I mentioned earlier suggests not using those methods, so consider removing them.

Upvotes: 1

Related Questions