bin gerade dabei ein programm zu erweitern und dazu möchte ich gerne eine liste erstellen, in dieser sollen objekte angezeigt werden. jetzt allerdings nicht nur als einzeiler sondern da einige informationen zu diesen objekten gehören dachte ich da an so ein art rechteck das mehrere zeilen hat.
so etwa wie im bild nur muss es keine icons enthalten, aber buttons zum entfernen wären auch nicht schlecht.
jetzt hab ich allerdings leider kein blassen schimmer wie ich das anstellen kann
dachte da an rechtecke zeichnen lassen und diese mit text zu versehen wäre das eine möglichkeit?
oder gibt es da eine swing komponente die ich übersehen hab?
zweite idee wäre es jpanels einzufügen die dann eben zwei, drei labels enthalten und dann noch buttons.
könnte man diese jpanels in einer jlist abspeichern so das ich mich nicht um die position kümmern muss?
Wenn du Buttons in deiner Liste haben willst wird das mit dem ListCellRenderer nicht funktionieren. Am besten du schreibst dir eine Klasse die von JPanel erbt und eine View für einen deiner Listeneinträge repräsentiert. Für jeden Eintrag erstellst du jetzt eine solche Klasse und packst die in ein Vertikales Layout (z.B Box)
Damit untergräbst du das Rendering Konzept der JList und könntest eigentlich wie vorgeschlagen ein JPanel mit Box Layout o.ä. verwenden.
Sicher dass der Renderer nicht aufgerufen wird? Die Objekte sind doch zu sehen?
Problematisch - neben dem Aushebeln des Renderings - ist das Du ein Null Layout verwendest und Dich nicht um die korrekte Größe Deiner Komponente kümmerst. Ausschlaggebend für den Renderer ist meines Wissens die PreferredSize.
[QUOTE=_Michael;29169]Damit untergräbst du das Rendering Konzept der JList und könntest eigentlich wie vorgeschlagen ein JPanel mit Box Layout o.ä. verwenden.
[/QUOTE]
ja damit habe ich es auch schon versucht dann habe ich aber das problem das ich mich um die selektion kümmern muss über ein mouseadapter oder so
möchte auch die position der elemente über drag&drop verändern können (innerhalb der liste) dachte dies ginge wenn ich eine jlist nehme einfacher
[QUOTE=_Michael;29169]
Sicher dass der Renderer nicht aufgerufen wird? Die Objekte sind doch zu sehen?[/QUOTE]
ja die system.out.println in meinem renderer wurde nie auf der console ausgegeben
problem lag vermutlich daran das ich kein model verwendet habe -.-
musste für die panels, wie du gesagt hast, noch die PreferredSize festlegen und ich füge die panels nun einem defaultlistmodel hinzu.
bisher habe ich es nun so gelöst:
erstmal panel von dem daten-objekt getrennt.
Meine Klasse zum anzeigen:
/**
*
*/
private static final long serialVersionUID = 1L;
private Step mystep = null;
private final JLabel oidlbl, valuelbl, stepid;
private final Font font = new Font("Tahoma", Font.PLAIN, 14);
private final Font stepfont = new Font("Tahoma", Font.PLAIN, 30);
public StepPanel(Step step) {
this.mystep = step;
setLayout(null);
this.setBackground(Color.WHITE);
this.setSize(310, 58);
System.out.println(this.getSize());
this.setPreferredSize(this.getSize());
oidlbl = new JLabel("OID: " + mystep.getOid());
oidlbl.setFont(font);
oidlbl.setBounds(50, 10, 200, 14);
add(oidlbl);
valuelbl = new JLabel("value: " + mystep.getValue());
valuelbl.setBounds(50, 34, 200, 14);
valuelbl.setFont(font);
add(valuelbl);
stepid = new JLabel(String.valueOf(step));
stepid.setBounds(5, 9, 40, 38);
stepid.setFont(stepfont);
add(stepid);
this.setOpaque(true);
}
}```
listen aufruf:
``` list = new JList<StepPanel>();
DefaultListModel<StepPanel> listmod = new DefaultListModel<StepPanel>();
list.setModel(listmod);
list.setCellRenderer(new FWListRenderer());
scrollPane2.setViewportView(list);
list.setDragEnabled(true);
list.setDropMode(DropMode.INSERT);
listmod.addElement(new StepPanel(new Step("1.3.3.3.3.3.")));
listmod.addElement(new StepPanel(new Step("1.3.3.3.3.3.", 2)));
listmod.addElement(new StepPanel(new Step("1.3.3.3.3.3.", 3)));
listmod.addElement(new StepPanel(new Step("1.3.3.3.3.3.", 4)));
listmod.addElement(new StepPanel(new Step("1.3.3.3.3.3.", 5)));
listmod.addElement(new StepPanel(new Step("1.3.3.3.3.3.", 6)));
listmod.addElement(new StepPanel(new Step("1.3.3.3.3.3.", 7)));```
renderer habe ich nicht geändert der funktioniert jetzt wie geplant
Müssen nicht, er kann auch einfach nur ein JPanel mit den entsprechend platzierten Labels verwenden. Aber üblicherweise erben die Renderer von einer Komponente und stellen “sich selbst” zum rendern zur Verfügung.
welches Layout sollte ich dann verwenden?
im anhang ist das bild meiner JPanels, die ich anzeigen lasse. bis jetzt 3 labels pro jpanel.
ich tue mich mit den standard layouts schwer, finde die recht unbrauchbar bzw. umständlich.
für meine jframes habe ich in eclipse den windowbuilder,mit dem ich dann über das AbsoluteLayout meine komponenten in die größe und position ziehe. (ist auch nicht so toll, da bei fenster maximierung usw… die komponenten ihre größe behalten, aber wenn ich die komponenten, in dieser anordnung, mit einem standard-layout sortieren müsste würde das ja stunden dauern.)
mein neustes frame mit der liste sieht man im anhang
[japi]BorderLayout[/japi] ist für den Anfang immer eine gute Wahl. Oft muss man mehrere Panels mit verschiedenen Layouts schachteln, und das gewünschte Ergebnis zu erzielen. Wenn man Zeilen und Spalten auf einander abstimmen muss würde ich zum [JAPI]GroupLayout[/japi] greifen, aber da gibts auch schon einige externe Frameworks (zb.: JGoodies-FormLayout) die recht intuitiv anzuwenden sind.
GUI-Builder sind für mich immer bäh, weil die eben ein pixelgenaues Layout liefern, dass kaputt geht, wenn man die Fenstergröße ändert…
BorderLayout komibiniert mit GridLayout wäre eine Möglichkeit. Etwas unschön wäre dabei evtl. IDs mit unterschiedlicher Ziffernzahl. Da müsste man sich etwas überlegen. Eine bequeme Lösung:
import java.awt.Component;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
public class CustomListRendererDemo {
public static void main(String[] args) {
new CustomListRendererDemo().startDemo();
}
public void startDemo() {
DefaultListModel<CustomObject> model = new DefaultListModel<CustomObject>();
JList<CustomObject> list = new JList<CustomObject>(model);
for (int i=0; i< 101; i++) {
CustomObject obj = new CustomObject((char)(Math.random()*26 + 65)+" value", "value2");
model.addElement(obj);
}
list.setCellRenderer(new CustomRenderer());
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 300, 300);
frame.setLocationRelativeTo(null);
frame.add(new JScrollPane(list));
frame.setVisible(true);
}
class CustomRenderer extends JPanel implements ListCellRenderer<CustomObject> {
private JLabel[] label;
private final Font font = new Font("Tahoma", Font.PLAIN, 14);
private JLabel labelMaxPreferredSize = new JLabel();
public CustomRenderer() {
label = new JLabel[] {new JLabel("", JLabel.RIGHT), new JLabel(), new JLabel()};
setLayout(new BorderLayout(10, 10));
JPanel panel = new JPanel(new GridLayout(2,1 ));
panel.setOpaque(false);
panel.add(label[1]);
panel.add(label[2]);
label[0].setFont(font.deriveFont(26f));
labelMaxPreferredSize.setFont(font.deriveFont(26f));
label[1].setFont(font);
label[2].setFont(font);
add(label[0], BorderLayout.WEST);
add(panel, BorderLayout.CENTER);
}
public Component getListCellRendererComponent(JList<? extends CustomObject> list, CustomObject value, int index,
boolean isSelected, boolean cellHasFocus) {
if (isSelected)
setBackground(list.getSelectionBackground());
else
setBackground(list.getBackground());
labelMaxPreferredSize.setText(" " + (list.getModel().getSize()-1));
label[0].setText(String.valueOf(index));
label[0].setPreferredSize(labelMaxPreferredSize.getPreferredSize());
label[1].setText("OID: " + value.value1);
label[2].setText("value: " + value.value2);
return this;
}
}
class CustomObject {
//public for dummy reasons
public String value1, value2;
public CustomObject(String value1, String value2) {
this.value1 = value1;
this.value2 = value2;
}
}
}```
[QUOTE=_Michael;29333]Etwas unschön wäre dabei evtl. IDs mit unterschiedlicher Ziffernzahl. [/QUOTE]für den Anfang könnte mann ja die PrefferedSize und die MinSize des entsprechenden Labels auf einen angemessenen Wert setzen…
ok danke, verwende halt die gui-builder weils einfach und schnell geht und ich nicht viel zeit in die gui investieren wollte.
jetzt habe ich allerdings die zeit das ich das noch anpassen könnte, wäre eigentlich schon notwendig. habe die software unter xp geschrieben und unter windows 7 schneidet es bei meinen fenstern unten immer etwas ab. also doch zeit in die gui investieren :twisted: