Image einem bestimmten Button zuordnen



  • HI

    Ich sitze gerade auf Arbeit in einem kleinen Java-Seminar. Unsere Aufgabe ist es jetzt ein Spiel zu Programmieren.

    Hatte mir ein Memory-Spiel ausgesucht. Also das mit dem "kleine Kärtchen umdrehen und zwei gleiche finden" ^^.

    Klingt dumm ist für uns aber gar nicht so einfach.

    Unser Problem ist jetzt das wir in einem Fenster mit dem GridLayout Button erstellt und darunter auf genaue Positionen die Bilder gesetzt haben.
    Die Bilder sollen sich per Zufall ändern.

    Wir wissen nur nicht genau wie wir die Bilder einem bestimmten Button zuordnen sollen, damit das Programm am Ende weiß, welches Bild sich unter dem Button befindet den wir angeklickt haben.

    Würden uns sehr über Hilfe von euch freuen.

    😘



  • Hallo,

    das mit dem Bild sollte nicht das Problem sein. Wieso macht ihr das vorläufig nicht mit Strings 🙄 ? Ansonsten denke ich mal, dass sich die Images innerhalb der paint-Methode genauso zeichnen lassen wie z.B. wenn man die Hintergrundfarbe (wie hier) ändert. Hm, wie wäre es mit setIcon (statt setText) ?

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    
    class Karte extends JButton implements ActionListener {
    	public static Karte active = null;   //Paar
    	private String value;
    
    	public Karte(String value) {
    		super();
    		this.value = value;
    		setText(null);
    		addActionListener(this);
    	}
    
    	public String getValue() {
    		return value;
    	}
    
    	public void actionPerformed(ActionEvent ae) {
    		if(getText() != null) return;   //mehrmals nacheinander klicken
    
    		setText(value);
    		repaint();
    
    		if(active == null) {
    			active = this;
    			return;
    		}
    
    		if(active.getValue().equals(getValue())) { //auf gleichheit prüfen
    			System.out.println("richtig");
    			active.removeActionListener(active);  //kann nicht mehr angeklickt werden
    			removeActionListener(this);			  //kann nicht mehr angeklickt werden
    			active.setBackground(Color.GREEN);
    			setBackground(Color.GREEN);
    		} else {
    			System.out.println("falsch");
    			setText(null);
    			active.setText(null);
    		}
    		repaint();
    		active = null;
    	}
    
    	public void paint(Graphics g) {
    		Graphics2D g2d = (Graphics2D) g;
    		super.paint(g);
    	}
    }
    
    public class Memory extends JFrame {
    
    	public Memory(String title) {
    		super(title);
    
    		JPanel jp = (JPanel) getContentPane();
    		jp.setLayout(new GridLayout(6,4));
    
    		//initialisierung mit Werten
    		ArrayList values = new ArrayList();
    		values.add("katze");
    		values.add("hund");
    		values.add("maus");
    		values.add("vogel");
    		values.add("ziege");
    		values.add("kuh");
    		values.add("wolf");
    		values.add("hirsch");
    		values.add("löwe");
    		values.add("elefant");
    		values.add("schildkröte");
    		values.add("nemo");
    		values.add("fisch");
    		values.add("giraffe");
    		values.add("panther");
    		values.add("hase");
    		values.add("seehund");
    		values.add("braunbär");
    		values.add("eißbär");
    		values.add("tintenfisch");
    		values.add("seepferd");
    		values.add("nashorn");
    		values.add("ente");
    		values.add("schaf");
    
    		//result
    		ArrayList result = new ArrayList();
    
    		int j=0;
    		while(values.size() > 0) {
    			Random random = new Random();
    			int i = random.nextInt(values.size());   //nicht ganz ok  --> besser machen
    			System.out.println(i);
    
    			result.add(values.get(i));
    
    			if(contains(result, (String) values.get(i))) {
    				values.remove(values.get(i));
    			}
    		}
    
    		for(int i=0; i<result.size(); i++) {    //gui adden
    			Karte karte = new Karte((String) result.get(i));
    			jp.add(karte);
    		}
    	}
    
    	private boolean contains(ArrayList al, String val) {   //schon 2 vorhanden ?
    		int count = 0;
    		for(int i=0; i<al.size(); i++) {
    			String v = (String) al.get(i);
    			if(v.equals(val)) count++;
    			if(count == 2) return true;
    		}
    
    		return false;
    	}
    
    	public static void main(String[] args) {
    		Memory memory = new Memory("memory");
    
    		class WindowCloser extends WindowAdapter {
    			public void windowClosing(WindowEvent we) {
    				System.exit(0);
    			}
    		}
    
    		memory.addWindowListener(new WindowCloser());
    
    		memory.setSize(800,800);
    		memory.show();
    	}
    }
    

    lg kati



  • toll 👎

    ein kleiner Hinweis hätte auch gereicht. revoke sollte das selbst lösen.



  • oooops sorry 🕶



  • ach nit schlümm ^^

    wir dürfen eh nit mitta swing arbeiten vondaher war es doch nur n wink auf n möglich rictigen weg.

    Danke Kati 🙂



  • Also ehrlich gesagt würde ich das auch garnicht mit swing oder AWT-Standardkomponenten lösen. Eigentlich schreibe ich mir für jede Art von Spiel meine eigenen Komponenten und wenn´s einigermaßen schnell sein soll, sollte man auf Swing sowieso verzichten.



  • Pogo schrieb:

    wenn´s einigermaßen schnell sein soll, sollte man auf Swing sowieso verzichten.

    ... ich muss auch sagen, dass ich ein bisschen enttäuscht bin. Swing finde ich vom Konzept her super ( leicht erweiterbar etc., Anwendungen lassen sich schnell entwickeln), ABER: Performanz ist ziemlich heavy. Bei der Bearbeitung großer Datenmengen zeigt sich, wie lahm Java manchmal ist. Z.B. bei 600 Einträgen in einem JTreeView (und das ist eigentlich gar nicht viel!) ist es schon langsam, wenn ich schnell scrollen will. Geschweige, wenn man mit vielen Komponenten interaktiv arbeitet - also das Event Handling. Außerdem Speicherbedarf: ich habe mal versucht, das java.lang.OutOfMemoryError-Problem über expliziten gc() Aufruf zu lösen. Es hat einige Minuten gedauert, bis es aufgeräumt war. Geht es nur mir so? 😞



  • Tipp: C# 😉



  • das OutOfMemory Problem kannst du umgehen indem du dir mehr speicher beim prg-aufruf besorgst 🙂

    -Xmsn
        Specify the initial size, in bytes, of the memory allocation pool. This value must be a multiple of 1024 greater than 1MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is 2MB. Examples:
    
           -Xms6291456
           -Xms6144k
           -Xms6m
    
    -Xmxn
        Specify the maximum size, in bytes, of the memory allocation pool. This value must a multiple of 1024 greater than 2MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is 64MB. Examples:
    
           -Xmx83886080
           -Xmx81920k
           -Xmx80m
    

    (wobei es natürlich besser ist 'sparsam' zu implementieren)

    gruß
    d



  • fast schrieb:

    Tipp: C# 😉

    Ah, ein Scherzkeks hat sich verirrt; du gehörst hier her



  • djoxo schrieb:

    das OutOfMemory Problem kannst du umgehen indem du dir mehr speicher beim prg-aufruf besorgst 🙂
    (wobei es natürlich besser ist 'sparsam' zu implementieren)

    ja genau, mit der Speicherbesorgung sind die Probleme sicher nicht gelöst... Schlimm wirds, wenn es sparsamer nimmer geht.

    gruss
    kati


  • Mod

    Kati schrieb:

    ... ich muss auch sagen, dass ich ein bisschen enttäuscht bin. Swing finde ich vom Konzept her super ( leicht erweiterbar etc., Anwendungen lassen sich schnell entwickeln), ABER: Performanz ist ziemlich heavy. Bei der Bearbeitung großer Datenmengen zeigt sich, wie lahm Java manchmal ist. Z.B. bei 600 Einträgen in einem JTreeView (und das ist eigentlich gar nicht viel!) ist es schon langsam, wenn ich schnell scrollen will. Geschweige, wenn man mit vielen Komponenten interaktiv arbeitet - also das Event Handling. Außerdem Speicherbedarf: ich habe mal versucht, das java.lang.OutOfMemoryError-Problem über expliziten gc() Aufruf zu lösen. Es hat einige Minuten gedauert, bis es aufgeräumt war. Geht es nur mir so? 😞

    Ich glaube, es gibt ein paar Komponenten in Swing, die man sehr schnell so benutzen kann, wie es nicht gedacht ist. Diese Komponenten bestrafen das dann auch ganz schnell mit einer miserablen Performance. Dazu gehören sicherlich der JTree und die JTable. Ich kenne mich mit diesen Komponenten leider auch nicht aus, da ich mich noch nicht intensiver mit denen auseinandersetzen mußte. Man hört aber in verschiedenen Foren immer wieder, dass es da Performance-Probleme gibt. Die Lösung ist meistens eine andere Nutzung der Komponente. Oft werden z.B. unnötigerweise sehr viele Objekte bei der Nutzung so einer Komponente genutzt. Die Kosten natürlich Speicherplatz und bremsen das ganze Programm aus.

    Mein Tipp: Schau dir mal die Beispielanwendungen an, die es von Sun zu Swing gibt. In den Sun-Tutorials wird sicherlich auch etwas zur richtigen Nutzung dieser Komponenten drinstehen.



  • hi gregor,

    ja, du hast natürlich recht. Ich schaue mir jedoch fast immer die beispielanwendungen aus der api-doku an. Ich halte mich auch an die Prinzipen so weit nur möglich... also was das JTree-Problem angeht: ich möchte eine Datenstruktur graphisch darstellen. Diese kann aus vielen Elementen bestehen und jedes dieser Elemente kann eine konstante Anzahl der Kinder haben, die wiederum sehr viele Kinder haben können. Um diese Datenstruktur graphisch darstellen zu können, habe ich JTree verwendet, weil es sich hierbei eben um eine baumartige Datenstruktur (Objekte die auf andere Objekte verweisen) handelt. Naja, und da ich JTree eben mit vielen Daten fülle, verhält sich die Anwendung auch dementsprechend. Was für eine Komponente soll ich statt JTree verwenden (Bedingung: es muss möglich sein, die Kinder anzuklicken, da gleichzeitig DB-Zugriff erfolgt --> Event Handling; d.h. JTextArea oder ähnliches käme nicht in Frage).

    lg kati



  • Wie komplex sind die Objekte, die du als Knoten bzw. Blätter ablegst? Ein einfacher String könnte ich mir vorstellen würde weniger verbraten ...



  • hi,

    hier sind 2 screenshots:
    http://www.wu-wien.ac.at/usr/h99d/h9953043/Bilder/visual.gif
    http://www.wu-wien.ac.at/usr/h99d/h9953043/Bilder/datastr.gif

    Das erste veranschaulicht eine Vektorkarte. Jedes der Polygone kann aus mehreren Tausend Punkten bestehen. Dies kann man vor allem am zweiten Screenshot erkennen. Von Bedeutung sind hierbei vor allem die Knoten "GeoPoint X". In diesem Fall machen den ersten Datensatz 1486 Punkte aus (0-1485). Die anderen Knoten sind eigentlich harmlos (also klein: 1-4 Knotenkinder, wobei jeder dieser Knoten noch ein Blatt hat). Insgesamt ist es eine ziemlich große Menge an Knoten und Blättern 😞 . Was für eine Komponente sollte ich dafür besser verwenden? 😕

    lg
    kati



  • Die Komponente an sich ist schon korrekt gewählt nur würde ich die Organisation etwas anders machen. Von diesen Geo-X-Daten benötigst du wahrscheinlich nicht alle gleichzeitig. Zumindest könnte man den Umfang etwas eingrenzen. Was ich damit sagen will ist, dass man evtl. durch ein ausgereiftes Befüllen des Trees on-demand viel mehr rausholen kann als wie wenn man alle Daten sofort in den Speicher holt. Immer nur die Daten in den Speicher lesen, die man auch tatsächlich benötigt. Beispielsweise bei der Expandierung eines Knotens einlesen etc. Ich denke damit kommt man weiter und ist aus Sicht der Performance besser.



  • ja, das wäre eine Alternative. D.h. erst wenn der Knoten "record..." angeklickt wird, sollen die Daten per "random access" aus der Datei rausgeholt werden. Was mir aber aufgefallen ist: wenn auf der Ebene 1 (also ohne root) viele Knoten sind, ist es eigentlich wurst, ob diese noch Kinder haben, oder ? Es ist trotzdem lahm, wenn man scrollt.

    lg kati



  • Na ja die angesprochene Alternative ist nur als Speicherentlastung gedacht. Dass beim Scrollen Probleme auftreten mag tatsächlich ein Problem der Swing-API sein.


Anmelden zum Antworten