Java Spielfeld mit Bildern füllen

cl0udt

Lt. Junior Grade
Registriert
Sep. 2008
Beiträge
508
Hallo zusammen,

würde gerne ein Spielfeld (Schiffe versenken) basteln.
Ich hab mich jetzt länger mit JTable rumgeplagt, aber ich glaube, dass ist nicht so das wahre dafür.
Ich muss halt an bestimme x/y-positionen bilder setzen und löschen können.
Und das krieg ich mit JTable einfach nicht hin...

Was is da der einfachste weg? Gibts da irgendwas, was einfach maßgeschneidert dafür ist?

Danke schonmal für Tipps
 
wie wärs mit JComponent?
ne eigene klasse damit schreiben, welche ein bild malen und löschen kann. sollte funktionieren

EDIT: zum beispiel so:
Code:
class picture extends JComponont {

    int x,y;
    Image picture;

    public picture(int x, int y, Image picture) {
        this.x = x;
        this.y = y;
        this.picture = picture;
    }

    public drawImage() {
        Graphics g = getGraphics();
        g.drawImage(0,0,picture,this);
    }

    public deleteImage() {
        Graphics g = getGraphics();
        g.setColor(Color.white);
        g.clearRect(0,0,picture.getWidth(),picture.getHeight());
    }
}
 
Zuletzt bearbeitet:
Mhh, da sich deine Spielfeldgroeße nachtraeglich nicht aendert, kann man da evtl was mit GridBagLayout machen und an den entsprechenen Positionen nur die Labels aendern.


MfG SaxnPaule

EDIT: Zu langsam ;)
 
Ja, also wie gesagt, am schönsten wäre es ein raster zu haben. Wo ich dann z.b. sagen kann, ersetze das heile schiff an koordinate 0/3 durch ein kaputtes schiff oder so ähnlich halt.

@1668mib und SaxnPaule
Wie krieg ich das mit dem Grid-Layout hin? Gibts da vll ne vorlage an der ich mich bissl orientieren kann?

@F.b
hmm, damit hätte ich aber das problem mit der positionierung noch nicht gelöst, wenn ich das richtig verstehe, oder? Also festes raster hab ich damit ja nicht.
 
cl0udt schrieb:
@1668mib und SaxnPaule
Wie krieg ich das mit dem Grid-Layout hin? Gibts da vll ne vorlage an der ich mich bissl orientieren kann?

Jupp, solltest du zu genuege bei Google finden. Such mal nach "GridBag Layout Example".

Ich orientier mich auch immer an alten Beispielen oder vorhandenem Code. Alles ausm Aermel schuetteln dauert zu lange ;)
 
kk, danke. Habe ein ganz nettes, aber langes tutorial gefunden. Hoffe mal ich kann das echt damit machen und verschwende keine zeit :D ich vertrau dir mal :D
 
Bevor du es mit Bildern machst, kannst du ja erstmal nur die Farbe der einzelnen Labels veraendern. Sollte ja fuer den Anfang genuegen um erkenntlich zu machen, wo ein Schiff steht und wo nicht.


MfG SaxnPaule
 
Andere und meiner Meinung nach performantere Lösung ist ein BufferedImage über das dazugehörige Graphics2D Objekt zu verändern. Das Spielfeld ändert sich ja nicht hochfrequent. Zu viele Komponenten können manchmal schon langsam werden...
 
Ja, wenns gar nicht klappt, dann werd ichs damit ausprobieren. Aber hab jetzt schon viel Arbeit reigesteckt in mein Panel mit GridBagLayout.

Für die Leute, die sich auskennen mit GridBagLayout:

Wie kann ich denn die Zwischenräume zwischen den einzelnen Zeilen minimieren?
Habe da jetzt halt unschöne abstände zwischen den einzelnen bildern, die vom grid produziert werden...
 
Also das GridBagLayout ist zwar so ziemlich das flexibelste, aber für den Einsteig auch das komplizierteste. Ich würde das ganz normale GridLayout (ohne "bag") nehmen, das dürfte für ein simples Schiffe-versenken völlig ausreichend sein.
 
Ja, hab auch schon überlegt einfach zu switchen, aber funktioniert grad alles echt super. Denke, ich hätte beim gridlayout das gleiche problem, wird am ende auch die gleiche lösung sein nur ich weiß net wie :(

ich meine, irgendwo muss man doch einstellen können, wie breit die gitternetzlinien da sind, die das grid legt...gibts doch gar net ...
 
GridBagConstraints.insets();

http://download.oracle.com/javase/1.4.2/docs/api/java/awt/GridBagConstraints.html#insets

EDIT:
Ich habe grad mal in Quellcode von mir geschaut. Ich nutze immer eine Methode zum Hinzufuegen der Komponenten ins ContentPane, damit ich nicht jedes Mal extra Constraints definieren muss.

static void addComponent(Container cont, GridBagLayout gbl, Component c, int x, int y, int width, int height, double weightx, double weighty, int fill) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.fill = fill;
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = width;
gbc.gridheight = height;
gbc.weightx = weightx;
gbc.weighty = weighty;
gbl.setConstraints(c, gbc);
cont.add(c);
}

Hinzufuegen der Komponenten erfolgt dann ganz uebersichtlich in einem Block
contentpane.setLayout(gbl);

// Add components
addComponent(contentpane, gbl, add, 5, 0, 1, 1, 1.0, 1.0, 1);
addComponent(contentpane, gbl, remove, 5, 1, 1, 1, 1.0, 1.0, 1);
addComponent(contentpane, gbl, search, 5, 6, 1, 1, 1.0, 1.0, 1);
...
...

MfG SaxnPaule
 
Zuletzt bearbeitet:
Danke, von der Beschreibung her passts. Nur müsste es jetzt noch klappen...

Code:
        JLabel testLabel = new JLabel(imageIcon);
        GridBagConstraints listConstraints = new GridBagConstraints();
        listConstraints.gridx = x;
        listConstraints.gridy = y;
        Insets insetTest = new Insets(4, 4, 4, 4);
        listConstraints.insets(insetTest);

Eclipse unterstreicht mir hier das "insets" und sagt: The Method insets(Insets) is undefined for the Type GridBagConstraints.

Es steht auch dabei, dass die Default-Werte = 0,0,0,0 wären. Das hieße ja theoretisch dürften eh keine zwischenräume zwischen meinen bildern sein...

EDIT: OK, is schrott was ich oben geschrieben hab. Naja, zumindest bis auf den teil, das selbst beim setzen auf 0,0,0,0 noch zwischenräume vorhanden sind...
 
Zuletzt bearbeitet:
Korrekt, prinzipiell duerften keine Zwischenraeume sein. Bei mir unterkringelt Eclipse nix bei gbc.insets = new Insets(5, 5, 5, 5);

Du musst auch jedes Element zusammen mit entsprechenden GridBagConstraints ins Layout einfuegen. Waere bei meinem Code gbl.setConstraints(c, gbc);

Um nicht fuer jedes Element wieder etliche Zeilen Code zu haben empfiehlt es sich wirklich eine Methode dafuer zu definieren.

Hast du schon sehr viel Quellcode? Wenn nicht, kann ich ja mal einen Blick drauf werfen, wenn du moechtest.
Ergänzung ()

Ich habe mal schnell eine Beispiel GUI geschrieben, welche sich direkt ausfuehren laesst. Wenn die Insets geaendert werden, veraendern sich auch die Abstaende der Labels zueinander.

Code:
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class TestGui extends JFrame {
	private static final long serialVersionUID = 1L;

	private JLabel label1 = new JLabel("O");
	private JLabel label2 = new JLabel("O");
	private JLabel label3 = new JLabel("O");
	private JLabel label4 = new JLabel("O");
	
	final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

	public static void main(String args[]) {
		TestGui gui = new TestGui();
		gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		gui.setVisible(true);
	}

	private TestGui() {
		
		// Size and Position
		int width = screenSize.width;
		int height = screenSize.height;
		
		label1.setOpaque(true);
		label2.setOpaque(true);
		label3.setOpaque(true);
		label4.setOpaque(true);
		label1.setBackground(Color.RED);
		label2.setBackground(Color.GREEN);
		label3.setBackground(Color.BLUE);
		label4.setBackground(Color.GRAY);
		
		Container contentpane = getContentPane();
		GridBagLayout gbl = new GridBagLayout();
		this.setSize(80, 180);
		this.setLocation(width / 2 - 300, height / 2 - 325);
		int[] rowheights = { 20, 20};
		int[] colwidths = { 20, 20};
		gbl.columnWidths = colwidths;
		gbl.rowHeights = rowheights;

		contentpane.setLayout(gbl);

		// Add components		
		addComponent(contentpane, gbl, label1, 	0, 0, 1, 1, 1.0, 1.0, 1);
		addComponent(contentpane, gbl, label2, 	0, 1, 1, 1, 1.0, 1.0, 1);
		addComponent(contentpane, gbl, label3, 	1, 0, 1, 1, 1.0, 1.0, 1);
		addComponent(contentpane, gbl, label4, 	1, 1, 1, 1, 1.0, 1.0, 1);
		
	}

	private void addComponent(Container cont, GridBagLayout gbl, Component c, int x, int y, int width, int height,
			double weightx, double weighty, int fill) {
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.insets = new Insets(0, 0, 0, 0);
		gbc.fill = fill;
		gbc.gridx = x;
		gbc.gridy = y;
		gbc.gridwidth = width;
		gbc.gridheight = height;
		gbc.weightx = weightx;
		gbc.weighty = weighty;
		gbl.setConstraints(c, gbc);
		cont.add(c);
	}
}
 
Zuletzt bearbeitet:
Wenn das gridbaglayout keine abstände macht, dann haben halt die eingefügten komponenten jeweils abstände... Rück mal bisserl mehr code raus
 
Ok das mit den Abstand is nebensache. Das klappt am end schon irgendwie, außerdem so siehts jetzt auch schon ganz gut aus. Hab grad ein viel größeres Problem - das GridBagLayout legt alle Bilder untereinander. Das heiß neue bilder, die ich einfach drüberschreibe, werden gar net angezeigt. Auf einzelne koordinaten zugreifen und deren inhalt löschen, klappt auch nicht...

Das ist der Anfang meiner Klasse: Hab den Code eigentlich nur kopriert von der Seite:

http://www.java-forum.org/bilder-gui-damit-zusammenhaengt/64702-gridbaglayout.html

Also durch das " setLayout( new OverlayLayout( this ) );" sollte das doch eigentlich gehandhabt werden...aber selbst wenn es so funtkionieren würde, würd ich lieber Zellen löschen können, als nur überschreiben..

Code:
    private JPanel content;
    private JComponent glass;
    private GridBagLayout layout;
    private String skinPath;
    
    public Demo(String skinPath){
    	this.skinPath = skinPath;
        setLayout( new OverlayLayout( this ) );
 
 
        layout = new GridBagLayout();
        content = new JPanel( layout );
        content.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
 
Schreibe doch in jede Koordinate einfach nur ein Label. Einem Label kannst du dann problemlos ein Bild zuweisen oder einfch nur die Farbe aendern, wie in meinem Beispiel.
 
Zuletzt bearbeitet:
Mache ich auch:

Code:
        JLabel testLabel = new JLabel(correctItem); //correcItem ist vom Typ ImageIcon
        GridBagConstraints listConstraints = new GridBagConstraints();
        listConstraints.gridx = x;
        listConstraints.gridy = y;
        listConstraints.insets = new Insets(0, 0, 0, 0);
        
        content.add(testLabel, listConstraints); //content ist ein JPanel

Weiß trotzdem net, wie ich an der Koordinate wieder das Bild wegbekomme...
 
Zurück
Oben