Java может использовать GridBagLayout для организации JPanel, используемого в CardLayout

Я новичок в макетах, и сейчас я использую CardLayout с двумя разными картами, на которых в настоящее время нарисовано фоновое изображение и кнопка. Как показано ниже, кнопка находится в верхней части экрана, и я хотел бы расположить ее где-нибудь ближе к нижней части. Насколько я понимаю, GridBagLayout будет лучшим способом сделать это. Так что мой первый вопрос, это правда? А также, возможно ли это сделать, если JPanel, на который я хочу поместить GridBagLayout, является картой в CardLayout. Я хотел бы поместить много других объектов в GridBagLayout (если это лучший способ сделать это и если это возможно), поскольку я продвигаюсь дальше в проекте, поэтому любые советы о том, в каком правильном направлении идти, будут очень признательны.

import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class Cards implements ActionListener {    
private JPanel cards;
private JButton button1;
private JButton button2;
private Image backgroundImage;

public void addComponentToPane(Container pane) throws IOException {
    try {           
        backgroundImage = ImageIO.read(getClass().getResource("resources/background.jpg"));         
    } catch (IOException ex) {
        ex.printStackTrace(System.err);
    }

    //create cards
    JPanel card1 = new JPanel()
    {
        @Override
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.drawImage(backgroundImage, 0, 0, null);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(
                    backgroundImage.getWidth(null),
                    backgroundImage.getHeight(null));
        }
    };
    JPanel card2 = new JPanel()
    {
        @Override
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.drawImage(backgroundImage, 0, 0, null);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(
                    backgroundImage.getWidth(null),
                    backgroundImage.getHeight(null));
        }
    };
    //create buttons
    button1 = new JButton("Button 1");
    button2 = new JButton("Button 2");
    button1.addActionListener(this);
    button2.addActionListener(this);
    //add buttons to cards
    card1.add(button1);        
    card2.add(button2);
    //create panel that contains cards
    cards = new JPanel(new CardLayout());
    cards.add(card1, "Card 1");
    cards.add(card2, "Card 2");
    pane.add(cards, BorderLayout.SOUTH);        
}

public void itemStateChanged(ItemEvent evt) {
    CardLayout cl = (CardLayout)(cards.getLayout());
    cl.show(cards, (String)evt.getItem());
}

public static void createAndShowGUI() throws IOException  {
    //create and setup window
    JFrame frame = new JFrame("Frame"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
    //create and setup content pane
    Cards main = new Cards();
    main.addComponentToPane(frame.getContentPane());        
    //display window
    frame.pack();       
    //frame.setResizable(false);
    frame.setVisible(true);
}

public void actionPerformed(ActionEvent ae) {
    if (ae.getSource() == button1) {
        CardLayout cl = (CardLayout) (cards.getLayout());
        cl.show(cards, "Card 2");     
    } else if (ae.getSource() == button2) {
        CardLayout cl = (CardLayout) (cards.getLayout());
        cl.show(cards, "Card 1");
    }        
}            

public static void main(String[] args) {
    //set look and feel
    try {
        UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
    } catch (UnsupportedLookAndFeelException ex) {
        ex.printStackTrace();
    } catch (IllegalAccessException ex) {
        ex.printStackTrace();
    } catch (InstantiationException ex) {
        ex.printStackTrace();
    } catch (ClassNotFoundException ex) {
        ex.printStackTrace();
    }                

    //schedule job for the event dispatch thread creating and showing GUI        
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {                   
                    try {
                        createAndShowGUI();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }                
        }
    });     
}   
}

person Jarod    schedule 16.07.2012    source источник


Ответы (2)


GridBagLayout будет делать то, что вы хотите, да. Это один из самых гибких (но и один из самых сложных) LayoutManager доступных. Является ли это «лучшим» способом сделать это, зависит от того, какие другие элементы управления вы хотите добавить на свою панель, хотите ли вы, чтобы они изменяли размер, что вы хотите, чтобы произошло, когда родительский элемент JPanel изменяется, и другие факторы.

re: вложение JPanels с разными макетами, да. Совершенно нормально иметь JPanel с GridBagLayout внутри JPanel с CardLayout внутри JPanel с BorderLayout [и т.д...]

person Dan O    schedule 16.07.2012

Проверьте BorderLayout. Он имеет 5 отдельных областей, в которые вы можете поместить другие контейнеры: слева, справа, сверху, по центру и снизу.

http://docs.oracle.com/javase/tutorial/uiswing/layout/border.html

person ioreskovic    schedule 16.07.2012