问题
I need to be able to change the size of an JPanel in a event function and then get the size again. It seems that the JPanel is not updated untill the function call has been finished. How can I get the real size? This is an SSCCE:
import java.awt.*;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.*;
public class Test extends JFrame implements MouseWheelListener{
JPanel p;
Test(){
setLayout(new FlowLayout());
setPreferredSize(new Dimension(1000,1000));
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
p = new JPanel();
p.setPreferredSize(new Dimension(200,200));
p.setBackground(Color.red);
add(p);
addMouseWheelListener(this);
pack();
}
public static void main(String args[]){
new Test();
}
public void mouseWheelMoved(MouseWheelEvent e) {
System.out.println(p.getSize());
p.setPreferredSize(new Dimension(100,100));
p.revalidate();
System.out.println(p.getSize());
}
}
The code works fine, but it prints the following in the console if I scroll the mouse one step:
java.awt.Dimension[width=200,height=200]
java.awt.Dimension[width=200,height=200]
I want it to print:
java.awt.Dimension[width=200,height=200]
java.awt.Dimension[width=100,height=100]
回答1:
your code works for me, but working only on mouse wheel event, you have to scroll with mouse wheel
modified example
import java.awt.*;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.*;
public class Test extends JFrame implements MouseWheelListener {
private static final long serialVersionUID = 1L;
private JPanel p;
public Test() {
setLayout(new FlowLayout());
setPreferredSize(new Dimension(1000, 1000));
setDefaultCloseOperation(EXIT_ON_CLOSE);
p = new JPanel();
p.setPreferredSize(new Dimension(200, 200));
p.setBackground(Color.red);
add(p);
addMouseWheelListener(this);
pack();
setVisible(true);
}
public void mouseWheelMoved(MouseWheelEvent e) {
Dimension dim100 = new Dimension(100, 100);
Dimension dim200 = new Dimension(200, 200);
System.out.println(p.getSize());
if (p.getPreferredSize().equals(dim100)) {
p.setPreferredSize(dim200);
p.revalidate();
System.out.println(p.getSize());
} else if (p.getPreferredSize().equals(dim200)) {
p.setPreferredSize(dim100);
p.revalidate();
System.out.println(p.getSize());
}
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Test();
}
});
}
}
EDIT:
have to delay System.out.println(p.getSize());
, invokeLater() is best of all in this case, becase container returned changed Dimension after all events are done in the EDT
example
import java.awt.*;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.*;
public class Test extends JFrame implements MouseWheelListener {
private static final long serialVersionUID = 1L;
private JPanel p;
public Test() {
setLayout(new FlowLayout());
setPreferredSize(new Dimension(1000, 1000));
setDefaultCloseOperation(EXIT_ON_CLOSE);
p = new JPanel();
p.setPreferredSize(new Dimension(900, 900));
p.setBackground(Color.red);
add(p);
addMouseWheelListener(this);
pack();
setVisible(true);
}
public void mouseWheelMoved(MouseWheelEvent e) {
Dimension dim100 = p.getSize();
System.out.println("before "+ p.getSize());
p.setPreferredSize(new Dimension(dim100.height - 5, dim100.width - 5));
p.revalidate();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("after "+ p.getSize());
}
});
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Test();
}
});
}
}
generated
before java.awt.Dimension[width=900,height=900]
after java.awt.Dimension[width=895,height=895]
before java.awt.Dimension[width=895,height=895]
after java.awt.Dimension[width=890,height=890]
before java.awt.Dimension[width=890,height=890]
after java.awt.Dimension[width=885,height=885]
before java.awt.Dimension[width=885,height=885]
after java.awt.Dimension[width=880,height=880]
before java.awt.Dimension[width=880,height=880]
after java.awt.Dimension[width=875,height=875]
before java.awt.Dimension[width=875,height=875]
after java.awt.Dimension[width=870,height=870]
before java.awt.Dimension[width=870,height=870]
after java.awt.Dimension[width=865,height=865]
before java.awt.Dimension[width=865,height=865]
after java.awt.Dimension[width=860,height=860]
回答2:
Don't you need to call paint() too, to the size change?
来源:https://stackoverflow.com/questions/11470530/getsize-isnt-updated