2012-06-07 1 views
2

저는 Java에서 JFrames로 작업하고 있습니다. 특히 겹칠 필요가있는 절대적으로 배치 된 요소가 있습니다. 구성 요소를 오버레이하려면 JPanel (setOpacity(false);)을 만들고 setBounds(x,y,x2,y2); 또는 setPosition(x,y) & setSize(x,y) 중 하나를 배치해야합니다. 불행히도 패널은 CSS의 inline-divs처럼 작동합니다. 그들은 필요한만큼만 방을 차지하고 쌓지 않습니다. setLayout (null) 및 배경 이미지를 사용하여 JPanel을 다른 JPanel 위에 절대적으로 배치하는 방법은 무엇입니까?

내가 지금까지 가지고있는 코드이지만, 나는 그것을 것이라고 상상하는 것처럼 행동하지 않는 것 :

class Login extends JFrame { 
    private JPanel   backgroundpanel; 
    private JPanel   panel; 
    private JPanel   panel2; 
    private JTextField  usernameBox; 
    private JPasswordField passwordBox; 
    private JButton  button; 
    private int   height = 319; 
    private int   width = 452; 
    private ImageIcon  ii  = new ImageIcon("special-window-BG.png"); 
    private JLabel   image; 

    public Login() { 
     setLayout(null); 
     setTitle("Login"); 
     setSize(width,height); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setLayout(null); 

     buildPanel(); 

     add(backgroundpanel); 
     setVisible(true); 
    } 

    private void buildPanel() { 
     usernameBox = new JTextField(20); 
     passwordBox = new JPasswordField(20); 
     button = new JButton("Login"); 
     image = new JLabel(ii); 

     backgroundpanel = new JPanel(); 
     panel = new JPanel(); 
     panel2 = new JPanel(); 

     backgroundpanel.add(panel); 
     backgroundpanel.add(panel2); 
     backgroundpanel.add(image); 

     panel.setBackground(Color.red); 
     panel.setBounds(0, 0, 10, 10); 
     panel.setOpaque(false); 

     panel2.setBackground(Color.blue); 
     panel2.setBounds(0, 0, 10, 10); 
     panel2.setOpaque(false); 

     panel.add(passwordBox); 
     panel2.add(button); 

     backgroundpanel.setOpaque(false); 
     backgroundpanel.isOptimizedDrawingEnabled(); 
     backgroundpanel.setBounds(0, 0, width, height); 

... cot'd 그러나 불필요한.

기본적으로 배경 이미지가있는 JPanel 위에 JPanels (또는 JComponents가 더 간단하다면)를 배치하는 방법을 알고 싶습니다.

이 질문을 검토해 주셔서 감사 드리며,이 방법에 너무 많은 시간을 투자했습니다. 주석 처리 된 코드는 내가 올린 내용을 거의 500 줄 넘어서 확장 할 수있는 곳이 없습니다. 아래 이미지는 내가 성취하고자하는 것을 보여주는 조잡한 그림을 보여 주지만, 실제로 JComponents가 마치 배경 이미지 뒤에있는 것처럼 보이기 때문에 JComponents가 사라지는 것 같아서 내 눈앞에서 가장 가능성있는 간단한 솔루션을 찾고 싶습니다. 당신은하지만 (레이아웃 FlowLayout로 설정 기본값)은 "backgroundpanel"에 당신의 JFramesetLayout(null)을 설정하는

http://i.stack.imgur.com/revz8.jpg

+2

왜 이미지의 결과를 달성하기 위해 절대 레이아웃을 필요? – Robin

+0

구성 요소를 정확히 x/y 픽셀에 배치 할 수있는 다른 레이아웃 방법이 없으면 배경 이미지에 텍스트 필드의 특정 테두리가 있습니다. – ExacTM

답변

3

.

프레임이으로 설정되어 있지 않아야합니다. 기본 설정은 BorderLayout이므로 괜찮습니다 (부모와 일치하도록 "배경 패널"을 늘려야 함). JPanel에있는 setLayout(null) - "배경 패널"- 임의로 배치 된 패널을 추가합니다.

3

나는 내 눈앞에서 가장 가능성있는 간단한 해결책을 찾고 싶습니다.

이와 비슷한?

LoginPanel

import java.awt.*; 
import java.awt.image.BufferedImage; 
import java.net.URL; 

import javax.imageio.ImageIO; 
import javax.swing.*; 
import javax.swing.border.EmptyBorder; 

public class LoginPanel extends JPanel { 

    private static final long serialVersionUID = 1L; 

    BufferedImage image; 

    LoginPanel(BufferedImage image) { 
     super(new GridBagLayout()); 

     this.image = image; 

     JPanel controls = new JPanel(new BorderLayout(15,35)); 
     controls.setOpaque(false); 
     controls.setBorder(new EmptyBorder(110,0,0,0)); 

     JPanel fields = new JPanel(new GridLayout(0,1,30,30)); 
     fields.setOpaque(false); 
     controls.add(fields, BorderLayout.CENTER); 
     fields.add(new JTextField(20)); 
     fields.add(new JPasswordField(20)); 

     JPanel button = new JPanel(new GridBagLayout()); 
     button.setOpaque(false); 
     controls.add(button, BorderLayout.PAGE_END); 
     button.add(new JButton("Log In")); 

     Dimension prefSize = new Dimension(image.getWidth(),image.getHeight()); 
     setPreferredSize(prefSize); 

     add(controls); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawImage(image, 0, 0, getWidth(), getHeight(), this); 
    } 

    public static void main(String[] args) throws Exception { 
     URL url = new URL("http://i.stack.imgur.com/revz8.jpg"); 
     final BufferedImage image = ImageIO.read(url); 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       LoginPanel p = new LoginPanel(image); 
       JOptionPane.showMessageDialog(null, p); 
      } 
     }); 
    } 
} 
관련 문제