Eigenes List Model für Icon + String -> Speicherhungrig?

Status
Nicht offen für weitere Antworten.

liz

Mitglied
Hi,

ich wollte für mein Programm ein Statusfenster erstellen, in dem Nachrichten eingeblendet werden + einem dazugehörigen Icon, also "INFOICON Programm erfolgreich gestartet" etc. Ihr wisst vermutlich was ich meine.

Ich hab mir dafür ein eigenes ListenModel (implementiert das Interface ListModel) erstellt sowie einen eigenen ListenRenderer (implementiert das Interface ListCellRenderer). Folgend sind die beiden Klassen mal aufgelistet:

Model:
Java:
class MyStatusListModel implements ListModel {
	private Vector<Map<String, String>> maps = new Vector<Map<String, String>>();
	private Vector<ListDataListener> listeners = new Vector<ListDataListener>();

	public void addObject(Map<String, String> img) {
		int index = maps.size();
		maps.add(img);

		ListDataEvent e = new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index);

		for (int i = 0, n = listeners.size(); i < n; i++) {
			((ListDataListener) listeners.get(i)).contentsChanged(e);
		}
	}

	public void clear() {
		maps.clear();
	}

	@Override
	public void addListDataListener(ListDataListener arg0) {
		listeners.add(arg0);
	}

	@Override
	public Object getElementAt(int arg0) {
		Map<String, String> map = (Map<String, String>) maps.get(arg0);
		return map;
	}

	@Override
	public int getSize() {
		return maps.size();
	}

	@Override
	public void removeListDataListener(ListDataListener arg0) {
		listeners.remove(arg0);
	}
}

ListRenderer:
Java:
class IconListRenderer implements ListCellRenderer {
	private Map<String, Icon> icons = null;
	private JLabel label = new JLabel();
	private Map<String, String> val;

	public IconListRenderer(Map<String, Icon> icons) {
		this.icons = icons;
	}

	@Override
	public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
		// Get icon to use for the list item value
		val = (Map<String, String>) value;

		Icon icon = null;
		if (val.containsKey("added")) {
			icon = icons.get("added");
			label.setText(val.get("added").toString());
		} else if (val.containsKey("info")) {
			icon = icons.get("info");
			label.setText(val.get("info").toString());
		} else if (val.containsKey("error")) {
			icon = icons.get("error");
			label.setText(val.get("error").toString());
		} else if (val.containsKey("alert")) {
			icon = icons.get("alert");
			label.setText(val.get("alert").toString());
		} else if (val.containsKey("folder")) {
			icon = icons.get("folder");
			label.setText(val.get("folder").toString());
		}

		// Set icon to display for value
		label.setIcon(icon);
		val = null;
		icon = null;
		return label;
	}
}

Dem Model werden Werte dann wie folgt hinzugefügt:
Java:
Map<String, String> icons = new HashMap<String, String>(1);
				icons.put("info", "Programm erfolgreich gestartet...");
				statusListModel.addObject(icons);
Wenn ich dem Model jetzt aber z.b. 60 Werte übergebe, verbraucht die JVM ca 77MB. Wenn ich nichts hinzufüge, beansprucht die irgendwas mit 38MB.
Die wird vermutlich so viel verbrauchen weil ich jedesmal ein HashMap-Objekt übergebe. Eine Stauszeile wird immer hinzugefügt wenn ein Event ausgelöst wird.
Gibt es für mein Vorhaben also eine elegenatere Lösung?
 

hdi

Top Contributor
Also ich steig nich komplett durch was du da eig. machst, aber das sieht irgendwie zu aufgebläht aus wenn dieser Code wirklich nur für diese Liste zuständig ist. zB dieser Vector von Maps usw.

Also dein Model braucht eig. nur eine einfache List<String>.
Und ich würd den Messages einfach n Token geben die den Message-Typ angibt, und damit implizit das Icon. zB:

"!Programm-Fehler blabla"
"#Programm gestartet"

dann haste einfach ne Liste von Strings, und die Icons kriegste über:
(in der getRendererComponent, angenommen deine Klasse ist n JLabel:)

Java:
char typecode = value.toString().charAt(0);
Icon icon = null;
switch(typecode){
   case '!': icon = ICON_WARNING;
   break;
   case '#':icon = ICON_INFO;
}
setIcon(icon);

setText(value.toString().substring(1);

Fertig. Und wenn du neue nachrichten addest wie gesagt einfach nur deiner einfachen Liste nen neuen String adden und die passende fire-Methode Aufrufen, damit sich das gleich repaintet.
 

liz

Mitglied
Warum einfach, wenn es auch kompliziert geht? ;)
Danke, deine Lösung ist jedenfalls wesentlich praktikabler :)

Allerdings löst die mein problem nicht, was mich wundert.

Ich füge die Textzeilen wie folgt hinzu, die beiden gui.-Methoden fügen die Statuszeile bzw das Bild einfach der jeweiligen Liste hinzu. Nur warum verbraucht die Statuszeile sooo viel Speicher?!

Java:
public void update(Observable arg0, Object arg1) {
		ImageListChangeEvent obj = (ImageListChangeEvent) arg1;
		int index = obj.getIndex();

		if (obj.getType() == ImageListChangeEvent.ADDED) {
			EigenImageThumb img = crawler.getImageThumbModelList().imageThumbZurueckgeben(index);
			gui.statusHinzufuegen("+Bild " + img.getImageURL() + " hinzugefügt."); // wenn auskommentiert verbraucht die JVM nur ~ 38MB; wenn aktiv ~ 78MB
			gui.imageHinzufuegen(img);
			img = null;
		}
		obj = null;
	}
 

hdi

Top Contributor
Erstellst du dauernd neue Bilder? Das ist noch immer viel zu viel Code ;) Der Renderer für deine JList holt sich das Bild aus einem statischen Pool:

Java:
switch(typecode){
   case '!': icon = IconPool.getIcon("error.png");
   break;
   case '#':icon = IconPool.getIcon("message.png");
}
setIcon(icon);

Java:
public class IconPool {

	private static Map<String, Icon> pics;

	static {
		pics = new HashMap<String, Icon>();
		pics.put("error.png", new ImageIcon(ImageIO.read(IconPool.class
				.getResourceAsStream("/icons/error.png"))));
		pics.put("message.png", new ImageIcon(ImageIO.read(IconPool.class
				.getResourceAsStream("/icons/message.png"))));
	}
	
	public Icon getIcon(String name){
		return pics.get(name);
	}
}

Nur als Beispiel. Die Bilder werden nur einmal geladen und der Renderer klatscht je nach Message-Typ einfach eines der beiden rein. Aber es gibt im kompletten Programm nur jedes Bild 1 mal, es wird nur öfters gemalt.
 

liz

Mitglied
Ja, ich erzeuge ständig neue Bilder, aber nicht die Icons. Das Programm das ich gerade erstelle lädt Bilder von einer Homepage und ich möchte jedes mal wenn eines fertig geladen wurde, die Statuszeile ändern.

Mein CellRenderer für die Status jList sieht wie folgt aus:
Java:
class IconListRenderer implements ListCellRenderer {
	private JLabel label = new JLabel();
	private String val;

	private Icon icon_added = new ImageIcon(getClass().getResource("icon_accept.gif"));
	private Icon icon_info = new ImageIcon(getClass().getResource("icon_info.gif"));
	private Icon icon_folder = new ImageIcon(getClass().getResource("folder.gif"));
	private Icon icon_error = new ImageIcon(getClass().getResource("action_stop.gif"));
	private Icon icon_alert = new ImageIcon(getClass().getResource("icon_alert.gif"));

	public IconListRenderer() {

	}

	@Override
	public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
		// Get icon to use for the list item value
		val = value.toString();

		char typecode = val.charAt(0);
		Icon icon = null;
		switch (typecode) {
		case '!':
			icon = icon_error;
			label.setText(val.substring(1));
			break;
		case '+':
			icon = icon_added;
			label.setText(val.substring(1));
			break;
		case '#':
			icon = icon_info;
			label.setText(val.substring(1));
		}

		// Set icon to display for value
		label.setIcon(icon);
		val = null;
		icon = null;
		return label;
	}
}
 

hdi

Top Contributor
Zum Renderer:

1) label.setText(val.substring(1)); kannste aus dem switch rausziehen, dass passiert ja immer, egal welcher case

2) dass du val & icon am ende auf null setzt ist ist unnötig, das bringt nix.

3) du kannst dir "val" eig. gleich sparen, wozu denn erst den Text in einen String speichern, wenn du ihn ein paar Zeilen später eh im Label als Text setzt?

Aber das nur nebenbei, der Renderer hier kann nicht für das Problem verantwortlich sein. Ist es noch immer so dass es einen Unterschied der Memory gibt, ob du ihn verwendest oder nicht? ...wie viele solcher Nachrichten für diese Liste erzeugst du eigentlich?
 

liz

Mitglied
Hab mal deine Verbesserungen eingebaut.

Ja, es macht immernoch einen Unterschied ob ich die eine Zeile auskommentiere oder nicht.
Es werden 64 Listeneinträge für die Statusleiste erzeugt.

Wenn die Zeile aktiv ist:
Idle: 33 Mb Nach dem Durchlauf: 77 Mb

Wenn die Zeile inaktiv ist:
Idle: 33 Mb Nach dem Durchlauf: 37 Mb

Ich versteh es einfach nicht.
 

hdi

Top Contributor
Welche Zeile meinst du eig. gerade? also versteh ich das richtig: Ohne Bilder verbraucht die JVM bei 70 Nachrichten 38MB, und mit den Bildchen in der Liste sind es 77 MB?
 

liz

Mitglied
Es geht um die Zeile mit dem Kommentar:
Java:
public void update(Observable arg0, Object arg1) {
		ImageListChangeEvent obj = (ImageListChangeEvent) arg1;
		int index = obj.getIndex();

		if (obj.getType() == ImageListChangeEvent.ADDED) {
			EigenImageThumb img = crawler.getImageThumbModelList().imageThumbZurueckgeben(index);
			gui.statusHinzufuegen("+Bild " + img.getImageURL() + " hinzugefügt."); // wenn auskommentiert verbraucht die JVM nur ~ 38MB; wenn aktiv ~ 78MB
			gui.imageHinzufuegen(img);
			img = null;
		}
		obj = null;
	}

Ohne die Statusnachrichten braucht die JVM 38MB, wenn die Statusnachrichten hinzugefügt werden 77Mb.
Es macht dabei keinen Unterschied ob in den Statusnachrichten die Icons angezeigt werden oder nicht, sobald ich Statusnachrichten hinzufüge wächst der Speicherverbrauch.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Mein erstes eigenes Projekt - Aufbau und Strukturierung Java Basics - Anfänger-Themen 6
R Eigenes Protokoll zur Übermittlung von Daten zum Webserver? Java Basics - Anfänger-Themen 4
8 Eigenes Bild in email einfügen Java Basics - Anfänger-Themen 1
G eigenes package Java Basics - Anfänger-Themen 3
Anfänger2011 Eigenes Betriebssystem Java Basics - Anfänger-Themen 6
P Eigenes Fenster erstellen Java Basics - Anfänger-Themen 5
F eigenes Listener Pattern mit Interface Java Basics - Anfänger-Themen 1
P eigenes Equal mit IndexOf() Java Basics - Anfänger-Themen 5
L eigenes Steuerelement Zeitstrahl Java Basics - Anfänger-Themen 3
F Eigenes Package - Variable exportieren Java Basics - Anfänger-Themen 11
GianaSisters Methoden eigenes TableModel -> removeRow möglich machen Java Basics - Anfänger-Themen 30
D Eigenes Event beim TimeOut Java Basics - Anfänger-Themen 2
C Eigenes Konsolenfenster Java Basics - Anfänger-Themen 3
D Packages verwenden und in eigenes Projekt integrieren Java Basics - Anfänger-Themen 3
B Eigenes Package Java Basics - Anfänger-Themen 6
S Eigenes Objekt temporär verändern? (Clone)? Java Basics - Anfänger-Themen 12
M Eigenes Programm Flaechenrechner Java Basics - Anfänger-Themen 8
X Eigenes Kontosystem vervollständigen Java Basics - Anfänger-Themen 11
Developer_X eigenes ImageIcon schreiben Java Basics - Anfänger-Themen 11
Q Eigenes Event feuern Java Basics - Anfänger-Themen 5
S Eigenes Kontextmenü Java Basics - Anfänger-Themen 3
I jar in eigenes Programm unwandeln (OSX und Win) Java Basics - Anfänger-Themen 4
R Eigenes Pair Object Java Basics - Anfänger-Themen 2
C eigenes TableModel Java Basics - Anfänger-Themen 2
data89 In Java ein eigenes Lexikon erstellen? Doch wie? Java Basics - Anfänger-Themen 5
GilbertGrape Eigenes Event? Java Basics - Anfänger-Themen 2
K javadoc eigenes doclet in console starten Java Basics - Anfänger-Themen 3
B Eigenes Event schreiben Java Basics - Anfänger-Themen 7
M Eigenes Ellipse2D-Objekt Java Basics - Anfänger-Themen 5
G Eigenes Fenster Java Basics - Anfänger-Themen 51
N Eigenes Icon in InputDialog geht nicht! Java Basics - Anfänger-Themen 7
J Eigenes Symbol für Java Programm Java Basics - Anfänger-Themen 3
M Eigenes Seitenformat definieren Java Basics - Anfänger-Themen 2
Q Eigenes TableModel - NullPointerException Java Basics - Anfänger-Themen 6
F eigenes Package Java Basics - Anfänger-Themen 2
B Package/Klasse in ein eigenes Projekt einbinden? aber wie? Java Basics - Anfänger-Themen 6
D Array List mit Objekten sortieren Java Basics - Anfänger-Themen 2
J Array.list vergleichen Java Basics - Anfänger-Themen 1
B Vektor vs List Java Basics - Anfänger-Themen 4
volcanos Addition -> List<Integer> mit Arrays.asList() versus List<Integer>ArrayList<>() Java Basics - Anfänger-Themen 14
H Interface Wieso "List<String> list = new ArrayList<>[…]" Java Basics - Anfänger-Themen 4
T Linked List set-Methode Java Basics - Anfänger-Themen 2
volcanos List & ArrayList nach Familiennamen abfragen Java Basics - Anfänger-Themen 57
berserkerdq2 Ich gebe eine ArrayList als List zurück per MEthode, wie kann ich nun aber die ArrayList speichern? Java Basics - Anfänger-Themen 46
L Datentypen Array List Java Basics - Anfänger-Themen 9
J Java List, Bitte um Hilfe Java Basics - Anfänger-Themen 15
J Java List, bitte um Hilfe Java Basics - Anfänger-Themen 3
F GSON file mit einer List erstellen Java Basics - Anfänger-Themen 2
B Interface List - Objekt übergeben? Einzelnes Objekt geht, aber Liste nicht? Java Basics - Anfänger-Themen 4
O Collections.sort und List.sort mit Lambda Verwirrung Java Basics - Anfänger-Themen 5
J String Array zu Map<Character, List<Character>> mit Streams Java Basics - Anfänger-Themen 1
G Linked list, Methode zum Vertauschen von Elementen Java Basics - Anfänger-Themen 14
I csv auslesen, mittels List Java Basics - Anfänger-Themen 18
C Collections List über Interface zugreifen Java Basics - Anfänger-Themen 32
I Methoden List.contains() beim 2. Element = true Java Basics - Anfänger-Themen 1
N HashMap in List good practice? Java Basics - Anfänger-Themen 2
B SWAP List; Liste neu anordnen Java Basics - Anfänger-Themen 4
W Stream Array List - Frage Java Basics - Anfänger-Themen 5
E Interface List nicht als Collection an erkannt. Java Basics - Anfänger-Themen 14
X Array List geordnet ausgeben. (JSF und JAVA) Java Basics - Anfänger-Themen 1
D new arraylist (List) dynamisch erstellen Java Basics - Anfänger-Themen 1
Yjuq Generic Methode - Wie muss die List Definition aussehen? Java Basics - Anfänger-Themen 3
M List<String> auswählen Java Basics - Anfänger-Themen 42
F In List Rekursiv suchen Java Basics - Anfänger-Themen 12
B Unterschied zwischen (List<T> a) und (T[] a) Java Basics - Anfänger-Themen 7
T HashSet in List-Object Java Basics - Anfänger-Themen 5
B ENUM to List<String> konvertieren Java Basics - Anfänger-Themen 2
E Array-list mit einer bestimmten Länge Java Basics - Anfänger-Themen 17
B Sorting List und Remove Java Basics - Anfänger-Themen 2
B String: suche nach Wörter und in List<String> speichern Java Basics - Anfänger-Themen 3
M Methode überladen - Array List Java Basics - Anfänger-Themen 5
L LIST.ADD Java Basics - Anfänger-Themen 2
M XWPF - Bullet Point list erstellen Java Basics - Anfänger-Themen 1
I <List> sortieren Java Basics - Anfänger-Themen 2
N Klassen List-Art Java Basics - Anfänger-Themen 5
S List<T<X,Y> sortieren Java Basics - Anfänger-Themen 5
Salo Datentypen "Doppelt" List(e) ("gesucht") Java Basics - Anfänger-Themen 6
F .csv Export aus einer list Java Basics - Anfänger-Themen 25
T KlausurÜbung- Förderband-Linked List Java Basics - Anfänger-Themen 53
D Komischer Fehler nach <Integer> List Java Basics - Anfänger-Themen 2
B in einem abstrakten Set ,Elemente einer einfache verkettete List epeichern Java Basics - Anfänger-Themen 13
T List und ArrayList Java Basics - Anfänger-Themen 3
UnityFriday method getPrevious in class List<ContentType> cannot be applied to given types Java Basics - Anfänger-Themen 29
hooked Verkettete Liste / linked list Java Basics - Anfänger-Themen 2
T Datentypen InputStream to list of Int (or similar) Java Basics - Anfänger-Themen 4
D Input/Output CSV Parser list unvollständig Java Basics - Anfänger-Themen 25
V Erste Schritte Dateinamen aus einer FIle[] in eine List Java Basics - Anfänger-Themen 11
S Methoden Linked List Methoden können nicht aufgerufen werden Java Basics - Anfänger-Themen 1
U JAXB - List wird nicht ausgefüllt Java Basics - Anfänger-Themen 1
L Linked List - Array List Java Basics - Anfänger-Themen 2
J Einfach verkettet List: Ausgabe ohne null Java Basics - Anfänger-Themen 11
D Bestimmten Wert aus Array List ausgeben Java Basics - Anfänger-Themen 7
V Personenverwaltung mit List<>, falsche Ausgaben Java Basics - Anfänger-Themen 5
M List befüllen Java Basics - Anfänger-Themen 3
S Datentypen List.toString wirft NullPointerException Java Basics - Anfänger-Themen 5
P Anlegen und Abfragen von Array List Java Basics - Anfänger-Themen 4
S Element von List<E> in String umwandeln Java Basics - Anfänger-Themen 3
A Wie nutze ich List<List<String>> Java Basics - Anfänger-Themen 4
M Endlos schleife in List Java Basics - Anfänger-Themen 5
P Zufallszahlen ohne zahlen einer List Java Basics - Anfänger-Themen 21

Ähnliche Java Themen

Neue Themen


Oben