2016-04-06 7 views
2

Ich habe einen JPanel mit einem Bild als Hintergrund gemacht. Beim ersten Laden des JPanels wird der Rest der hinzugefügten Komponenten aber das Bild nicht sichtbar. Nachdem Sie die Maus über das Bild bewegt haben, werden die Schaltflächen sichtbar. Wie man die JButtons zusammen mit dem Bild als Hintergrund sichtbar macht, während das Panel geladen wird.Wie man JButtons auf einem JPanel mit einem Bild als Hintergrund sichtbar macht

enter image description here

Hier ist das Stück von meinem Code:

contentPane = new JPanel(); 
    contentPane.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null)); 
    setContentPane(contentPane); 
    contentPane.setLayout(null); 

    homePanel.setBounds(10, 11, 959, 620); 
    homePanel.setLayout(null); 

    JPanel wizardPanel = new JPanel(); 
    wizardPanel.setBounds(10, 295, 545, 336); 
    wizardPanel.setLayout(null); 
    homePanel.add(wizardPanel); 

    JLabel backgroundLabel; 
    try { 
     backgroundLabel = new JLabel(new ImageIcon(ImageIO.read(new File("images/nature.jpg")))); 
     backgroundLabel.setBounds(0, 0, 545, 336); 
     wizardPanel.add(backgroundLabel); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 


    JButton btnNewButton = new JButton("New button"); 
    btnNewButton.setBounds(309, 95, 89, 23); 
    wizardPanel.add(btnNewButton); 

    JButton btnNewButton_1 = new JButton("New button"); 
    btnNewButton_1.setBounds(309, 150, 89, 23); 
    wizardPanel.add(btnNewButton_1); 

    JButton btnNewButton_2 = new JButton("New button"); 
    btnNewButton_2.setBounds(309, 212, 89, 23); 
    wizardPanel.add(btnNewButton_2); 
+2

Versuchen Sie 'revalidate()' und 'repaint()' in Ihrem Inhaltsbereich aufzurufen, nachdem alle Ihre Komponenten hinzugefügt wurden. – Berger

+0

wenn möglich dann den ganzen Code posten. –

+1

Es wäre gut, ein [minimales, vollständiges und überprüfbares Beispiel] (http://stackoverflow.com/help/mcve) zu haben. Dies würde Ihre Frage viel einfacher beantworten. – Tiz

Antwort

0

das ist verrückt !! Ich habe es funktioniert, indem Sie den Abschnitt JButtons Initialisierung Codeblock über dem Bild Laden platzieren es funktioniert .....

 package demo; 

    import java.awt.EventQueue; 
    import java.io.File; 
    import java.io.IOException; 

    import javax.imageio.ImageIO; 
    import javax.swing.ImageIcon; 
    import javax.swing.JButton; 
    import javax.swing.JFrame; 
    import javax.swing.JLabel; 
    import javax.swing.JPanel; 
    import javax.swing.SwingUtilities; 
    import javax.swing.UIManager; 
    import javax.swing.border.EmptyBorder; 

public class demoframe extends JFrame { 

/** 
* 
*/ 
private static final long serialVersionUID = 1436190962490331120L; 

/** 
* Launch the application. 
*/ 
public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       demoframe frame = new demoframe(); 

       UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); 
       SwingUtilities.updateComponentTreeUI(frame); 

       frame.setVisible(true); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

/** 
* Create the frame. 
*/ 
public demoframe() { 

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setBounds(100, 100, 988, 678); 
    JPanel contentPane = new JPanel(); 
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
    setContentPane(contentPane); 
    contentPane.setLayout(null); 

    JPanel panel = new JPanel(); 
    panel.setBounds(10, 11, 501, 361); 
    contentPane.add(panel); 
    panel.setLayout(null); 

    JButton btnNewButton = new JButton("New button"); 
    btnNewButton.setBounds(322, 112, 89, 23); 
    panel.add(btnNewButton); 

    JButton button = new JButton("New button"); 
    button.setBounds(322, 172, 89, 23); 
    panel.add(button); 

    JButton button_1 = new JButton("New button"); 
    button_1.setBounds(322, 244, 89, 23); 
    panel.add(button_1); 

    JLabel backgroundLabel; 
    try { 
     backgroundLabel = new JLabel(new ImageIcon(ImageIO.read(new File("images/nature.jpg")))); 
     backgroundLabel.setBounds(0, 0, 501, 361); 
     panel.add(backgroundLabel); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 



    JPanel panel_1 = new JPanel(); 
    panel_1.setBounds(521, 11, 441, 361); 
    contentPane.add(panel_1); 

    JPanel panel_2 = new JPanel(); 
    panel_2.setBounds(10, 383, 952, 246); 
    contentPane.add(panel_2); 

} 
} 

Output looks like this now

+0

Es ist eine schlechte Idee, Ihre Komponenten übereinander zu platzieren. Besser ist es, Ihr Bild als Hintergrund zu malen. –

+0

@SergiyMedvynskyy ... das macht keinen Sinn, wir setzen die Komponente immer übereinander, es ist so, wie das Ganze funktioniert ... wenn du das Bild malen würdest, würdest du eine Komponente brauchen male es mit (vorzugsweise ein 'JPanel') ... aber immer noch die gleiche Art von Sache – MadProgrammer

+0

@MadProgrammer du hast Recht. Ich habe gemeint, dass es eine schlechte Idee ist, einen Button über das Label zu setzen. –

1

Eine schnelle Lösung kann direkt in das Bild JFrame Inhaltsbereich werden Einstellung und Ihre Komponenten Inhaltsbereich dieser JFrame hinzufügen. Angenommen, Ihr Code stammt aus dem Text einer Klasse JFrame. Mein Vorschlag würde mehr oder weniger wie folgt aussehen:

 JRootPane rootpane = new JRootPane(); 
     JPanel contentPane = new JPanel(); 
     contentPane.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null)); 
     rootpane.setContentPane(contentPane); 
     contentPane.setLayout(null); 

     JPanel homePanel = new JPanel(); 
     homePanel.setBounds(10, 11, 959, 620); 
     homePanel.setLayout(null); 

     JRootPane wizardPanel = new JRootPane(); 
     wizardPanel.setBounds(10, 295, 545, 336); 
     wizardPanel.setLayout(null); 

     JLabel backgroundLabel; 
     try { 
      File f = new File("D:\\work\\eclipse\\workspace_eclipse_4.4.1\\trialExamples\\src\\main\\images\\nature.jpg"); 
      backgroundLabel = new JLabel(new ImageIcon(ImageIO.read(f))); 
      backgroundLabel.setBounds(0, 0, 545, 336); 
      wizardPanel.setContentPane(backgroundLabel); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     JButton btnNewButton = new JButton("New button"); 
     btnNewButton.setBounds(309, 95, 89, 23); 
     wizardPanel.getContentPane().add(btnNewButton); 

     JButton btnNewButton_1 = new JButton("New button"); 
     btnNewButton_1.setBounds(309, 150, 89, 23); 
     wizardPanel.getContentPane().add(btnNewButton_1); 

     JButton btnNewButton_2 = new JButton("New button"); 
     btnNewButton_2.setBounds(309, 212, 89, 23); 
     wizardPanel.getContentPane().add(btnNewButton_2); 

     homePanel.add(wizardPanel.getContentPane()); 

     add(homePanel); 
+0

Aber dazu verwende ich zwei weitere Panels auf der linken Seite! Ich möchte nur, dass das Bild im ersten Panel angezeigt wird. – Lingaraj

+1

@Lingaraj Ich habe es bearbeitet, um einen JRootPane innerhalb eines JPanels zu verwenden. Obwohl das korrekt ist und es funktioniert, ist es kein schöner Weg dies zu tun. Sie sollten ein erweitertes JPanel verwenden, in dem die paintComponent-Methode überschrieben wird. Es ist auch eine gute Praxis, [Layoutmanager] (https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html) zu verwenden. –

+2

Eine bessere Lösung wäre, sich nicht auf "Null" -Layouts zu verlassen: P – MadProgrammer

2

Es ist eine schlechte Idee Taste auf Etikett zu platzieren. Besser ist es, das Bild als Hintergrund zu malen oder JLayer zu verwenden. Hier ein Beispiel für die erste Lösung:

import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.LayoutManager; 
import java.util.Objects; 

import javax.imageio.ImageIO; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.WindowConstants; 

public class JImagePanel extends JPanel { 

    private final Image image; 

    private boolean scale; 

    public JImagePanel(Image anImage) { 
     image = Objects.requireNonNull(anImage); 
    } 

    public JImagePanel(Image anImage, LayoutManager aLayout) { 
     super(aLayout); 
     image = Objects.requireNonNull(anImage); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     final Image toDraw = scale? image.getScaledInstance(getWidth(), getHeight(), Image.SCALE_SMOOTH) : image; 
     g.drawImage(toDraw, 0, 0, this); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } else { 
      return new Dimension(image.getWidth(this), image.getHeight(this)); 
     } 
    } 

    public boolean isScale() { 
     return scale; 
    } 

    public void setScale(boolean scale) { 
     this.scale = scale; 
    } 


    public static void main(String[] args) throws Exception { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        final JImagePanel p = 
          new JImagePanel(ImageIO.read(JImagePanel.class.getResource("myImage.png")), new FlowLayout()); 
        p.setScale(true); 
        p.add(new JButton("Button")); 
        final JFrame frm = new JFrame("Image test"); 
        frm.add(p); 
        frm.pack(); 
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
        frm.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

} 
+0

* "Es ist eine schlechte Idee, die Schaltfläche über das Label zu setzen" * - Warum? Es ist nicht meine bevorzugte Methode für mindestens einen bestimmten Grund, aber wenn Sie die Behauptung machen wollen, wäre es für das OP nützlich zu wissen, warum – MadProgrammer

+2

'image.getWidth (null)' 'Image sein sollte. getWidth (this) 'und dasselbe für' getHeight' und 'g.drawImage (toDraw, 0, 0, null)' sollte 'g.drawImage (toDraw, 0, 0, this)' und [The Perils of Image sein .getScaledInstance()] (https://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html) aus Gründen, warum ich 'getScaledInstance' nicht verwenden würde: P – MadProgrammer

+2

Sie sollten Ihre Benutzeroberfläche auch aus dem Kontext des EDT laden, um einige der anderen möglichen Probleme zu lösen, werfen Sie einen Blick auf [Anfängliche Themen] (http://docs.oracle.com/javase/tutorial/uiswing) /concurrency/initial.html) für weitere Details – MadProgrammer

Verwandte Themen