Ответ 1
Вам, вероятно, нужно переопределить что-то вроде validate
(не забудьте вызвать супер). Конечно, это все еще может не сработать, если вы используете систему окон, чтобы настроить таргетинг контуров.
Когда пользователь нажимает на угол JFrame для изменения размера и перетаскивания мыши, JFrame перерисовывает на основе текущей позиции мыши при перетаскивании пользователем. Как вы можете слушать эти события?
Ниже я пытаюсь:
public final class TestFrame extends JFrame {
public TestFrame() {
this.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
// These methods do not appear to be called at all when a JFrame
// is being resized.
@Override
public void setSize(int width, int height) {
System.out.println("setSize");
}
@Override
public void setBounds(Rectangle r) {
System.out.println("setBounds A");
}
@Override
public void setBounds(int x, int y, int width, int height) {
System.out.println("setBounds B");
}
}
Как я могу определить и ограничить, как пользователь изменяет размер окна (исходя из текущего соотношения сторон окна), когда они перемещаются вокруг мыши?
Вам, вероятно, нужно переопределить что-то вроде validate
(не забудьте вызвать супер). Конечно, это все еще может не сработать, если вы используете систему окон, чтобы настроить таргетинг контуров.
Вы можете добавить прослушиватель компонентов и реализовать функцию componentResized следующим образом:
JFrame component = new JFrame("My Frame");
component.addComponentListener(new ComponentAdapter()
{
public void componentResized(ComponentEvent evt) {
Component c = (Component)evt.getSource();
//........
}
});
РЕДАКТИРОВАТЬ: По-видимому, для JFrame событие componentResized привязано к событию mouseReleased. Поэтому метод вызывается при отпускании кнопки мыши.
Один из способов добиться того, что вы хотите, - добавить JPanel, который будет охватывать всю область вашего JFrame. Затем добавьте компонентListener в JPanel (компонентResized для JPanel вызывается даже в то время, когда мышь по-прежнему перетаскивается). Когда размер рамки будет изменен, ваша панель также будет изменена.
Я знаю, это не самое элегантное решение, но оно работает!
Другим обходным решением (которое очень похоже на Alex, но немного более простым) является прослушивание событий из корневой панели JFrame
:
public final class TestFrame extends JFrame {
public TestFrame() {
this.getRootPane().addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
}
В зависимости от других деталей реализации, возможно, что корневая панель может быть изменена. Если это возможно, вы можете переопределить setRootPane()
и справиться с этим. Поскольку setRootPane()
защищен и вызывается только из конструктора, вряд ли вам это понадобится.
public class MouseDrag extends Component implements MouseListener,
MouseMotionListener {
/** The Image we are to paint */
Image curImage;
/** Kludge for showStatus */
static Label status;
/** true if we are in drag */
boolean inDrag = false;
/** starting location of a drag */
int startX = -1, startY = -1;
/** current location of a drag */
int curX = -1, curY = -1;
// "main" method
public static void main(String[] av) {
JFrame f = new JFrame("Mouse Dragger");
Container cp = f.getContentPane();
if (av.length < 1) {
System.err.println("Usage: MouseDrag imagefile");
System.exit(1);
}
Image im = Toolkit.getDefaultToolkit().getImage(av[0]);
// create a MouseDrag object
MouseDrag j = new MouseDrag(im);
cp.setLayout(new BorderLayout());
cp.add(BorderLayout.NORTH, new Label(
"Hello, and welcome to the world of Java"));
cp.add(BorderLayout.CENTER, j);
cp.add(BorderLayout.SOUTH, status = new Label());
status.setSize(f.getSize().width, status.getSize().height);
f.pack();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// "Constructor" - creates the object
public MouseDrag(Image i) {
super();
curImage = i;
setSize(300, 200);
addMouseListener(this);
addMouseMotionListener(this);
}
public void showStatus(String s) {
status.setText(s);
}
// Five methods from MouseListener:
/** Called when the mouse has been clicked on a component. */
public void mouseClicked(MouseEvent e) {
}
/** Called when the mouse enters a component. */
public void mouseEntered(MouseEvent e) {
}
/** Called when the mouse exits a component. */
public void mouseExited(MouseEvent e) {
}
// And two methods from MouseMotionListener:
public void mouseDragged(MouseEvent e) {
Point p = e.getPoint();
// System.err.println("mouse drag to " + p);
showStatus("mouse Dragged to " + p);
curX = p.x;
curY = p.y;
if (inDrag) {
repaint();
}
}
public void paint(Graphics g) {
int w = curX - startX, h = curY - startY;
Dimension d = getSize();
g.drawImage(curImage, 0, 0, d.width, d.height, this);
if (startX < 0 || startY < 0)
return;
System.err.println("paint:drawRect @[" + startX + "," + startY
+ "] size " + w + "x" + h);
g.setColor(Color.red);
g.fillRect(startX, startY, w, h);
}
}