Guten tag,
ich wollte fragen, ob es eine Möglichkeit gibt, zu gucken weshalb eine property geändert wurde?
ich habe nämlich eine JSplitPane in der je nach Focus unterschiedlich große JPanels liegen.
Das heißt, das sich die Divider-Position ständig ändert. Gerne würde ich dieses property event aber nur abfangen, wenn der User den Divider ganz bewusst verschoben hat.
Gibt es da eine Möglichkeit?
Das geht AFAIK nicht so ohne weiteres. Das würde auch dem Grundgedanken von MVC widersprechen: Wenn sich etwas ändert, kriegt man eine Nachricht darüber - aber NICHT über die “Ursache” der Änderung. Es könnte in jedem Fall etwas hakelig werden, aber … kann man erkennen, ob das passiert, was (keine Benutzerinteraktion ist aber) die Änderung der Divider-Position verursacht? Also GROB (!) sinngemäß sowas wie
Ich habe eine liste mit verschiedenen Sachen. Je nachdem welche ausgewählt wird, wird eine Preview angezeigt. Diese ist unterschiedlich groß, weshalb eine Seite der Split pane die Größe ändert.
Code, der die Augen rausreist.
Beispiel
[spoiler]Java Code:
import java.awt.Dimension;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class BS {
public static void main(String[] args) {
final JFrame bs = new JFrame();
bs.setTitle("Beispiel");
bs.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
bs.setSize(300, 450);
bs.setLocationRelativeTo(null);
final Dimension[] d = new Dimension[200];
final Random r = new Random();
for (int i = 0; i < d.length; ++i)
d** = new Dimension(r.nextInt(300), r.nextInt(300));
final JList<Dimension> list = new JList<Dimension>(d);
final JSplitPane split = new JSplitPane();
split.setOrientation(JSplitPane.VERTICAL_SPLIT);
split.setResizeWeight(0.8);
split.setTopComponent(new JScrollPane(list));
split.setBottomComponent(null);
list.addListSelectionListener(new ListSelectionListener() {
@SuppressWarnings("serial")
@Override
public void valueChanged(ListSelectionEvent e) {
split.setBottomComponent(new JScrollPane(new JPanel() {
{
setPreferredSize(list.getSelectedValue());
add(new JLabel(list.getSelectedValue().toString()));
}
}));
}
});
bs.add(split);
bs.setVisible(true);
}
}
[/spoiler]
Die Previews sind sehr unterschiedlich groß aber man hat ja die Funktion [JAPI]JSplitPane#setResizeWeight(double)[/JAPI] weshalb ich dem User gern die Möglichkeit geben würde, den Divider mit der Hand zu versetzen, und die gesetzte Position danach als maximale Ausdehnung (mit setResizeWeight) zu setzen.
Hä… geht’s jetzt nur darum, dass die Größe sich nicht automatisch anpassen soll? Da gibt’s doch 1000 einfache Möglichkeiten…
import java.awt.*;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class BS {
public static void main(String[] args) {
final JFrame bs = new JFrame();
bs.setTitle("Beispiel");
bs.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
bs.setSize(300, 450);
bs.setLocationRelativeTo(null);
final Dimension[] d = new Dimension[200];
final Random r = new Random();
for (int i = 0; i < d.length; ++i)
d** = new Dimension(r.nextInt(300), r.nextInt(300));
final JList list = new JList(d);
final JSplitPane split = new JSplitPane();
split.setOrientation(JSplitPane.VERTICAL_SPLIT);
split.setResizeWeight(0.8);
split.setTopComponent(new JScrollPane(list));
final JPanel container = new JPanel(new GridLayout(1,1));
split.setBottomComponent(container);
list.addListSelectionListener(new ListSelectionListener() {
@SuppressWarnings("serial")
@Override
public void valueChanged(ListSelectionEvent e) {
JPanel p = new JPanel();
p.setPreferredSize((Dimension)list.getSelectedValue());
p.add(new JLabel(list.getSelectedValue().toString()));
container.removeAll();
container.add(p);
container.validate();
}
});
bs.add(split);
bs.setVisible(true);
}
}
Geändert von Marco13 (Gestern um 20:30 Uhr) Grund: Code Formatierung
^^ Erstmal, vielen dank.
Nein, es geht nicht darum, dass die Größe nicht angepasst wird, sondern das sie nur bis zu einem bestimmten Maximum angepasst wird. Beispiel: (1 Dimensional, nur die Höhe)Die höhe ist 100px hoch.
Das Panel darf maximal 60px hoch sein.
Es wird ein Panel mit der Höhe 20 gesetzt.
Das Panel bekommt seine Höhe von 20.
Es wird ein Panel mit der Höhe 70 gesetzt.
Das Panel bekommt eine höhe von 60.
(Bis jetzt kein Problem)
Der User möchte das Panel ganz sehen, und verschiebt per Hand den Divider auf Höhe 80.
Scheinbar ist es dem User recht, wenn 80% vom Panel eingenommen werden.
Das heißt ab jetzt darf das Panel maximal 80px hoch sein, muss es aber nicht.
Das heißt, wenn der user den Divider verschiebt und loslässt, soll dies ab da die maximal mögliche Ausdehnung des Panels sein.
Unregistered
Vielen Dank, das du hier unbekannten Leuten hilfst, ihre Probleme zu lösen.
(oder ihnen zu sagen, das sie gar keine haben sondern sich nur welche machen,
oder die die sie haben nicht die Wichtigen sind, usw…)
Bin mir nicht sicher, ob ich es verstanden habe. Bei kleineren Komponenten soll die Höhe des SplitPane Bereich auf die Höhe der Komponente gesetzt werden und bei größeren auf einen Maximalwert?
Im Beispiel unten kann der Anwender den Maximalwert über den Divider verändern, allerdings nur nach oben. Soll er wieder reduziert werden müsste man sich etwas - z.B. eine separate “reset” Möglichkeit - einfallen lassen.
Hab’ gerade nochmal geschaut… irgendwie ist das ganze dann IMHO ziemlich “hakelig” zu bedienen. Angefangen bei Usability-Killern, wie dass man einen Eintrag aus der Liste wählt, und dieser Eintrag dann (nach der Größenanpassung) ggf. nicht mehr sichtbar ist, scheinen da auch einige … “Spezifika” der SplitPane eine Rolle zu spielen: Wenn die BottomComponent größer ist, als die Component, in der die SplitPane selbst drin ist, wird die PreferredSize der BottomComponent quasi ignoriert (oder irgendein absurder Wert verwendet). Wie man das beschriebene Verhalten vernünftig mit einer bestimmten ResizeWeight kombinieren soll, wüßte ich jetzt auch nicht. Vielleicht könnte man da irgendwas dengeln, aber… ob das wirklich alles so gewünscht ist, oder nur ein Gedanke für eine “mögliche” Lösung war, ist gerade nicht ganz klar…