Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Größe eines JFrame-Fensters nur nach einer Seite ändern

165 views
Skip to first unread message

Manfred Denzer

unread,
Apr 23, 2008, 5:01:39 AM4/23/08
to
Hallo zusammen,

ich versuche grade ein JFrame so einzustellen, dass man nur die Höhe
des Fenstern ändern kann. Die Breite soll immer gleich sein. Zwei
Versuche sind bisher gescheitert:

1. Versuch:
myFrame.setResizable(false);
-> Man kann die Fenstergröße nach beiden Seite nicht mehr ändern

2. Versuch:
myFrame.addComponentListener(new ComponentListener() {
public void componentResized(ComponentEvent e) {
myFrame.setSize(/*konstante Breite*/, /*neue Hoehe*/);
}
public void componentHidden(ComponentEvent e) {}
public void componentMoved(ComponentEvent e) {}
public void componentShown(ComponentEvent e) {}
});
-> Der Component-Listener wird erst ausgelöst, nachdem der Anwender
schon versucht hat, die Breite zu ändern. Das sieht gar nicht gut aus.
Ideal wäre es, wenn man die Breite gar nicht ändern könnte, so ähnlich
wie bei setResizable(false). Man darf also mit der Maus erst gar nicht
den Rand des Fenstern "fassen".

Wie kann ich das machen?
Bin für jeden Tipp dankbar :-)

Viele Grüße
Manfred

Jan Thomä

unread,
Apr 23, 2008, 5:21:06 AM4/23/08
to
On Wed, 23 Apr 2008 02:01:39 -0700 (PDT) Manfred Denzer wrote:
> ich versuche grade ein JFrame so einzustellen, dass man nur die Höhe
> des Fenstern ändern kann. Die Breite soll immer gleich sein. Zwei

Vielleicht kannst Du ja die Methode getMaximumSize und getMinimumSize
überladen so daß diese immer eine konstante Breite übergeben. Warum genau
willst Du eigentlich den Resize verhindern, sowas ist normalerweise prima
dazu geeignet seine Nutzer in den Wahnsinn zu treiben...

Jan

Manfred Denzer

unread,
Apr 23, 2008, 6:30:18 AM4/23/08
to
On 23 Apr., 11:21, Jan Thomä <k...@insomnia-hq.de> wrote:
> Vielleicht kannst Du ja die Methode getMaximumSize und getMinimumSize
> überladen so daß diese immer eine konstante Breite übergeben.

Danke für Deine Antwort! Ich habs versucht, aber die Methoden
getMaximumSize und getMinimumSize werden leider beim Verändern der
Größe nicht aufgerufen.

> Warum genau willst Du eigentlich den Resize verhindern, sowas ist normalerweise prima
> dazu geeignet seine Nutzer in den Wahnsinn zu treiben...

In dem Dialog ist eine Grafik mit konstanter Größe und daneben ein
Feld mit vertikalen Scrollbars. Wenn man die Breite ändern würde,
sieht der Dialog nicht gut aus. Wenn man aber die Höhe ändert, wird
das Feld mit den vertikalen Scrollbars größer und somit
übersichtlicher für den Anwender.

Frank Meyer

unread,
Apr 23, 2008, 10:34:58 AM4/23/08
to
Manfred Denzer schrieb:

> Danke für Deine Antwort! Ich habs versucht, aber die Methoden
> getMaximumSize und getMinimumSize werden leider beim Verändern der
> Größe nicht aufgerufen.

Wie du schon gemerkt hast, nützen diese beiden get-Methoden deiner Anforderung
nicht.

So sollte es gehen:

final JFrame frame = ...;
final int frameMinWidth = 500;
frame.addComponentListener(
new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
Dimension current = frame.getSize();
if (current.width < frameMinWidth) {
frame.setSize(frameMinWidth, current.height);
}
}
}
);
}
}
);

Manfred Denzer

unread,
Apr 24, 2008, 4:12:02 AM4/24/08
to
On 23 Apr., 16:34, Frank Meyer <f.me...@mediacare.de> wrote:
> So sollte es gehen:
>
> final JFrame frame = ...;
> final int frameMinWidth = 500;
> frame.addComponentListener(
> new ComponentAdapter() {
> public void componentResized(ComponentEvent e) {
> SwingUtilities.invokeLater(
> new Runnable() {
> public void run() {
> Dimension current = frame.getSize();
> if (current.width < frameMinWidth) {
> frame.setSize(frameMinWidth, current.height);
> }
> }
> }
> );
> }
> }
> );

Hallo Frank!
Vielen Dank für Deine Antwort. Leider ist diese Lösung auch nicht so
ganz ideal. Der Benutzer kann mit der Maus das Frame am Rand "greifen"
und aufziehen. Erst nachdem er die Maus wieder loslässt, springt das
Frame auf die richtige Breite zurück. Mir wäre es aber lieber, der
Benutzer könnte das Frame gar nicht erst aufziehen. Wenn ich zum
Beispiel setResizable(false) verwende, kann man die Größe des Frames
nach beiden Seiten nicht mehr ändern, die Seiten des Frames sind
sozusagen "gesperrt" und lassen sich mit der Maus nicht mehr
"greifen". So etwas bräuchte ich für eine Seite: die Breite soll nicht
verändert werden können, nur die Höhe.

Frank Meyer

unread,
Apr 24, 2008, 12:05:11 PM4/24/08
to
Manfred Denzer schrieb:

> Vielen Dank für Deine Antwort. Leider ist diese Lösung auch nicht so
> ganz ideal. Der Benutzer kann mit der Maus das Frame am Rand "greifen"
> und aufziehen. Erst nachdem er die Maus wieder loslässt, springt das
> Frame auf die richtige Breite zurück.

Das Event wird tatsächlich kommt tatsächlich erst nach einem MouseRelease.
Das kannst du damit beschleunigen:
Toolkit.getDefaultToolkit().setDynamicLayout(true);

> Mir wäre es aber lieber, der
> Benutzer könnte das Frame gar nicht erst aufziehen. Wenn ich zum
> Beispiel setResizable(false) verwende, kann man die Größe des Frames
> nach beiden Seiten nicht mehr ändern, die Seiten des Frames sind
> sozusagen "gesperrt" und lassen sich mit der Maus nicht mehr
> "greifen". So etwas bräuchte ich für eine Seite: die Breite soll nicht
> verändert werden können, nur die Höhe.

Ok, dann mach doch einfach setResizable(false) und bau an die Seite(n), die du
veränderbar haben willst, eine eigene Komponente ein (s.u.).

Gruß
Frank

import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

/**
* FrameBorderDragger
*
* @author FRMEYER
* @version 24.04.2008 17:18:42
*/
public class FrameBorderDragger extends JComponent implements MouseListener,
MouseMotionListener {

public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);

JLabel label = new JLabel();
label.setBackground(Color.blue);
label.setOpaque(true);
label.setPreferredSize(new Dimension(400,400));

Container pane = frame.getContentPane();
pane.add(label, BorderLayout.CENTER);
FrameBorderDragger.install(frame, TYPE_NORTH);
FrameBorderDragger.install(frame, TYPE_EAST);
FrameBorderDragger.install(frame, TYPE_SOUTH);
FrameBorderDragger.install(frame, TYPE_WEST);

frame.pack();
frame.setMinimumSize(frame.getSize());

frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

private JFrame frame;

public static final int TYPE_NORTH = 0;
public static final int TYPE_EAST = 1;
public static final int TYPE_SOUTH = 2;
public static final int TYPE_WEST = 3;

private int type;
private Point pointPressed;
private Point pointReleased;

public static FrameBorderDragger install(JFrame frame, int type) {
FrameBorderDragger dragger = new FrameBorderDragger(frame, type);

Container pane = frame.getContentPane();
if (type == TYPE_NORTH) {
pane.add(dragger, BorderLayout.NORTH);
} else if (type == TYPE_EAST) {
pane.add(dragger, BorderLayout.EAST);
} else if (type == TYPE_SOUTH) {
pane.add(dragger, BorderLayout.SOUTH);
} else if (type == TYPE_WEST) {
pane.add(dragger, BorderLayout.WEST);
}

return dragger;
}

public FrameBorderDragger(JFrame frame, int type) {
this.frame = frame;
this.type = type;

setBackground(Color.red);
setOpaque(true);
setUI(new ComponentUI() {});

setPreferredSize(new Dimension(5,5));

addMouseListener(this);
addMouseMotionListener(this);

}

public void mousePressed(MouseEvent e) {
pointPressed = e.getLocationOnScreen();
updateCursor(true);
}

private void updateCursor(boolean on) {
if (on) {
if (type == TYPE_NORTH) {
setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
} else if (type == TYPE_EAST) {
setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
} else if (type == TYPE_SOUTH) {
setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
} else if (type == TYPE_WEST) {
setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
}
} else {
setCursor(null);
}
}

public void mouseReleased(MouseEvent e) {
pointReleased = e.getLocationOnScreen();

int deltaX = pointReleased.x - pointPressed.x;
int deltaY = pointReleased.y - pointPressed.y;

Point location = frame.getLocation();
Dimension size = frame.getSize();

if (type == TYPE_NORTH) {
size.height -= deltaY;
location.y += deltaY;
} else if (type == TYPE_EAST) {
size.width += deltaX;
} else if (type == TYPE_SOUTH) {
size.height += deltaY;
} else if (type == TYPE_WEST) {
size.width -= deltaX;
location.x += deltaX;
}

Dimension minSize = frame.getMinimumSize();
if (minSize != null) {
if (size.width < minSize.width) {
size.width = minSize.width;
}
if (size.height < minSize.height) {
size.height = minSize.height;
}
}

frame.setBounds(location.x, location.y, size.width, size.height);

Rectangle r = new Rectangle(getLocationOnScreen(), getSize());
updateCursor(r.contains(pointReleased));

pointPressed = null;
pointReleased = null;
}

public void mouseDragged(MouseEvent e) {
mouseReleased(e);
pointPressed = e.getLocationOnScreen();
}

public void mouseMoved(MouseEvent e) {}

public void mouseEntered(MouseEvent e) {
updateCursor(true);
}

public void mouseClicked(MouseEvent e) {}

public void mouseExited(MouseEvent e) {}

}

Manfred Denzer

unread,
Apr 28, 2008, 4:19:02 AM4/28/08
to


Hallo Frank!
Ich danke Dir vielmals für den Beispiel-Code!
Vielen Dank und viele Grüße
Manfred

0 new messages