Hintergrundgrafik + JPanel

  • Themenstarter Themenstarter Random
  • Beginndatum Beginndatum
R

Random

Gast
Hi,

ich habe ein Problem beim positionieren eines JPanels, während ich eine Hintergrunggrafik geladen habe. Dieses JPanel besitzt ebenfalls ein Bild. Hier die Quelltexte:

EditorForm.java
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * EditorForm.java
 *
 * Created on 13.06.2011, 15:17:50
 */

package H_Game;

/**
 *
 * @author Carl Hamann
 */
public class EditorForm extends javax.swing.JFrame
{
    /** Creates new form EditorForm */
    public EditorForm()
    {
        initComponents();
        setContentPane(new BackgroundPic("bg.jpg"));
        ForegroundPic fp = new ForegroundPic(0, 0, "fp.jpg", this);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        MenuBar = new javax.swing.JMenuBar();
        jMenuFile = new javax.swing.JMenu();
        jMenuItemLoadImg = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("H_Editor");
        setAlwaysOnTop(true);
        getContentPane().setLayout(null);

        jMenuFile.setText("Datei");

        jMenuItemLoadImg.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemLoadImg.setText("Bild laden");
        jMenuFile.add(jMenuItemLoadImg);

        MenuBar.add(jMenuFile);

        setJMenuBar(MenuBar);

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-748)/2, (screenSize.height-396)/2, 748, 396);
    }// </editor-fold>

    /**
    * @param args the command line arguments
    */
    public static void main(String args[])
    {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new EditorForm().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JMenuBar MenuBar;
    private javax.swing.JMenu jMenuFile;
    private javax.swing.JMenuItem jMenuItemLoadImg;
    // End of variables declaration

}

Wrapper.java
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package H_Game;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import javax.swing.JPanel;

/**
 *
 * @author Carl Hamann
 */
public class BackgroundPic extends JPanel
{
    private Image img = null;

    BackgroundPic (String path)
    {
        if (path != null)
        {
            MediaTracker mt = new MediaTracker(this);
            img = Toolkit.getDefaultToolkit().getImage(path);
            mt.addImage(img, 0);

            try
            {
                mt.waitForAll();
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
    
    @Override protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
    }
}

ForegroundPic.java
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package H_Game;

import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.net.URL;
import javax.swing.JPanel;

/**
 *
 * @author Carl Hamann
 */
public class ForegroundPic extends JPanel
{
    private Image img = null;
    private Wrapper wrapper = null;
    private int x, y;

    ForegroundPic (int x, int y, String path, EditorForm eForm)
    {
        this.x = x;
        this.y = y;

        Toolkit toolkit = Toolkit.getDefaultToolkit();
        MediaTracker mediatracker = new MediaTracker(this);
        img = toolkit.getImage(path);

        wrapper = new Wrapper(img, x, y);

        mediatracker.addImage(img, 0);

        try
        {
            mediatracker.waitForID(0);
        }
        catch (InterruptedException e)
        {
            img = null;
        }

        wrapper.repaint();
        eForm.add(wrapper);
    }

    ForegroundPic (int x, int y, URL path, EditorForm eForm)
    {
        this.x = x;
        this.y = y;

        Toolkit toolkit = Toolkit.getDefaultToolkit();
        MediaTracker mediatracker = new MediaTracker(this);
        img = toolkit.createImage(path);

        wrapper = new Wrapper(img, x, y);

        mediatracker.addImage(img, 0);

        try
        {
            mediatracker.waitForID(0);
        }
        catch (InterruptedException e)
        {
            img = null;
        }
        
        wrapper.repaint();
        eForm.add(wrapper);
    }

    public Wrapper getWrapper ()
    {
        return wrapper;
    }
}

Das Ergebnis:
infozh.jpg


Mein eigentliches Ziel ist es die Vordergrundgrafik (Java Logo) absolut mit den Koordinaten (x, y von ForegroundPic und Wrapper) auf dem Frame zu positionieren. Die Vordergrundgrafik wird jedoch immer mittig positioniert. Ich habe schon verdammt viel ausprobiert z.B. Layout ändern. Falls es interessiert: Ich nutze Netbeans.
 
Du änderst das Layout nur am JFrame, und nicht am Background. Außerdem setzt du im geposteten Code nirgends eine Position.
Und warum verwendest du keine JLabel und setzt einfach das Bild mit setIcon? ???:L
 
Danke. Welches Layout sollte ich denn nehmen um absolut positionieren zu können?
Außerdem: Stimmt - ich habe noch keine Positionsänderung vorgenommen. Habe ich jetzt ergänzt (einfach ein setLocation im ForegroundPic-Konstruktor):
[JAVA=72]wrapper.setLocation(x, y);[/code]
 
Fürs JFrame BorderLayout oder CardLayout. Diese strecken den Komponenten über die zu Verfügung stehende Fläche. Für die absolute Positionierung Null-Layout am Background. Das ist auch der Fehler, da der Background standartgemäß das FlowLayout hat, was den Komponenten oben in der Mitte anordnet. Du musst übrigens auch die Größe mit setSize oder beides zusammen mit setBounds setzen.
 
Okay habs verbessert:

EditorForm.java
Java:
public class EditorForm extends javax.swing.JFrame
{
    /** Creates new form EditorForm */
    public EditorForm()
    {
        initComponents();
        getContentPane().setLayout(new BorderLayout());
        BackgroundPic bp = new BackgroundPic("bg.jpg");
        bp.setLayout(null);
        setContentPane(bp);
        ForegroundPic fp = new ForegroundPic(10, 10, "fp.png", this);
        //ForegroundPic fp2 = new ForegroundPic(10, 10, new URL("http://www.tutsi.de/wp-content/uploads/firefox-trojaner.jpg"), this);
    }

// ...
}

Ich sehe das Java Logo aber nicht mehr.

Du musst übrigens auch die Größe mit setSize oder beides zusammen mit setBounds setzen.
Welche Größe meinst du?
 
Ach so, sorry. Ich habe übersehen, dass du den Background als Contentpane hinzufügst. Damit musst du den JFrame kein Layout setzen, da das standartgemäß sowieso auf das alte ContentPane "umgeleitet" wird, welches ersetzt wird. Die Möglichkeit ist mir erst später eingefallen, wollte ich im nächsten Post posten.

LayoutManager setzen von allen Komponenten die Position und Größe. Wenn du das Null-Layout verwendet, muss man das natürlich selbst machen. Beides ist standartgemäß 0, die Position muss deshalb nicht umbedingt gesetzt werden. Wenn du die Größe aber 0 lässt, wird es auch nur 0x0 Pixel groß dargestellt und dadurch natürlich unsichtbar. Deshalb musst du mit setSize die richtige Größe setzen.

Wenn du Labels und setIcon verwenden würdest, hättest du die angenehme Eigenschaft, dass das Label als Preferred Size die Größe des Bildes hätte. Damit würde fp.setSize(fp.getPreferredSize()); reichen.


Übrigens sind BackgroundPic und ForegroundPic keine optimalen Klassennamen. Die weißen eher darauf hin, dass es sich dabei um ein Image handelt, BackgroundPicPanel würde da wohl deutlich besser passen. Aber das nur nebenbei.
 
Vielen Dank! Ich hätte gleich auf dich hören sollen - ein JLabel mit ImageIcon ist echt besser.
 

Zurück
Oben