c0d3x
c0d3x

Reputation:

How to "do something" on Swing component resizing?

I've a class which extends JPanel. I overwrote protected void paintComponent(Graphics g).

There is a variable which has to be recalculated when the panel's dimensions change. How do I do that in a proper way?

Upvotes: 31

Views: 48213

Answers (8)

jjnguy
jjnguy

Reputation: 138874

If the calculation isn't time consuming, I would just re-calculate the value each time in paintComponent().

Otherwise, you can save a value that is the size of the component and check it against the new size in paintComponent. If the size changed, then recalculate, otherwise don't.

private Dimension size;

protected void paintComponent(Graphics g){
    if (!size.equals(getSize())){
        size = getSize();
        // recalculate value
    }
}

Or, you can do the calculation on a resize event.

//in the constructor add the line
addComponentListener(resizeListener);

private ComponentListener resizeListener = new ComponentAdapter(){
    public void componentResized(ActionEvent e){
        // recalculate value
    }
};

Upvotes: 7

Szabolcs Szlávik
Szabolcs Szlávik

Reputation: 11

This simple example is drawing a red circle in the resized frame....

import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.*;
import java.awt.geom.*;

public class RedCircle extends JFrame implements ComponentListener {
     int getWidth;
     int getHeight;
     
      public RedCircle() {
        super("Red Circle");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        addComponentListener(this);             
        pack();
        setVisible(true);
    }
    
      public void componentResized(ComponentEvent e) {
            getWidth = e.getComponent().getWidth();
            getHeight = e.getComponent().getHeight();
            
            Panel pane = new Panel(getWidth,getHeight);
            
            add(pane);
      }
    
   
    public static void main(String[] args) {
        
         RedCircle rc = new RedCircle();
    }
    

 
 public void componentMoved(ComponentEvent e) {
       
    }

    
    public void componentShown(ComponentEvent e) {
     
    }

    
    public void componentHidden(ComponentEvent e) {
    
    }


}


class Panel extends JPanel {
    int panelWidth;
    int panelHeight;
    
    public Panel(Integer getWidth,Integer getHeight) {
       
    panelWidth = getWidth;
    panelHeight = getHeight;
    
    }
    
public void paintComponent(Graphics comp) {
        super.paintComponent(comp);
        Graphics2D comp2D = (Graphics2D) comp;
       
        int realWidth = panelWidth - 17;
        int realHeight = panelHeight - 40;
       
        float Height = (realHeight);
        float Width = (realWidth);
        
    // draw the Red Circle
        comp2D.setColor(Color.red);
        Ellipse2D.Float redCircle = new Ellipse2D.Float(0F, 0F, Width, Height);
        comp2D.fill(redCircle);
    }
}

Upvotes: 1

camickr
camickr

Reputation: 324118

If I understand the question correctly then you should read the section from the Swing tutorial on How to Write a Component Listener which shows you how to listen for a change in a components size.

Upvotes: 16

Jeremiah
Jeremiah

Reputation: 99

Here's what I use (where CoordinatePlane is a JPanel):

I'm not an expert

public CoordinatePlane() {
    setBackground(Color.WHITE);
    this.addComponentListener(new ComponentAdapter(){
        public void componentResized(ComponentEvent e) {
            //YOUR CODE HERE         
        }
    });
}

Upvotes: 1

Charnia
Charnia

Reputation: 625

Like Adam Paynter suggested, you can also add an inner class to your code, like this:

class ResizeListener extends ComponentAdapter {
        public void componentResized(ComponentEvent e) {
            // Recalculate the variable you mentioned
        }
}

The code you have entered between the innermost brackets will be executed everytime the component get resized.

Then you add this listener to your component with

myJPanel.addComponentListener(new ResizeListener());

You can get your component by using e.getComponent(). This way you can call any method of your component from inside the inner class like

e.getComponent().getWeight();

Upvotes: 46

Alexander
Alexander

Reputation: 81

The simplest way is to implement a ComponentListener:

myjpanel.addComponentListener(new ComponentAdapter() {
    @Override
    public void componentResized(ComponentEvent e) {
        //recalculate variable
    }
});

Here, I have used a ComponentAdapter because I only intend on overriding componentResized().

Upvotes: 4

guest
guest

Reputation: 1

It resizes automatically if it's

  1. inside a BorderLayout panel and
  2. put there as BorderLayout.CENTER component.

If it doesn't work, you probably have forgotten one of these two.

Upvotes: 0

Adam Paynter
Adam Paynter

Reputation: 46908

I suppose you could override the various setSize and resize methods and perform the calculation there. However, you may not find all the places where the size can be changed. You may want to have your class implement ComponentListener and simply listen to itself for resize events.

Warning: I am not a Swing expert.

Warning: I have not compiled this code.

public class MyJPanel extends JPanel implements ComponentListener {

    public MyJPanel() {
        this.addComponentListener(this);
    }

    public void paintComponent(Graphics g) {
        // Paint, paint, paint...
    }

    public void componentResized(ComponentEvent e) {
        // Perform calculation here
    }

    public void componentHidden(ComponentEvent e) {}

    public void componentMoved(ComponentEvent e) {}

    public void componentShown(ComponentEvent e) {}

}

Upvotes: 21

Related Questions