Проверьте, присутствует ли карта с именем в CardLayout - PullRequest
3 голосов
/ 18 мая 2011

У меня есть CardLayout, в который я добавляю карты только по мере необходимости.Поэтому, когда возникает необходимость показать конкретную карту (обозначенную ее именем), мне нужен способ проверить, присутствует ли карта с таким именем, чтобы я мог либо показать, либо создать ее соответствующим образом.

Согласно документации CardLayout

Переходит к компоненту, который был добавлен в этот макет с указанным именем, с использованием addLayoutComponent.Если такого компонента не существует, то ничего не происходит.

Так что, если я попрошу показать карту, которая еще не была добавлена, не будет выдано никакой ошибки.Я не смог найти API, который позволил бы мне проверить наличие карты.

Итак, возможно ли это сделать?Если нет, то как можно решить эту проблему?Есть решение, которое я помню вручную, какие карты я добавил, но кажется, что свинг должен быть в состоянии справиться с этим.

Ответы [ 2 ]

4 голосов
/ 18 мая 2011

Итак, когда возникает необходимость показать конкретную карту (обозначенную ее именем), мне нужен способ проверить, присутствует ли карта с таким именем, чтобы я мог либо показать, либо создать ее соответствующим образом..

  1. Получить текущий компонент, отображаемый в контейнере
  2. Попытка показать другую карту
  3. Получить компонент, отображаемый в контейнере
  4. Если два компонента одинаковы, ничего не произошло, и вам нужно создать карточку и добавить ее в контейнер.

Этот подход избавит вас от самостоятельного управления Набором карточек.

Редактировать:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class CardLayoutTest implements ActionListener
{
    JPanel cards;

    public void addComponentToPane(Container pane) {
        JPanel comboBoxPane = new JPanel();
        String comboBoxItems[] = { "Red", "Orange", "Green", "Yellow", "Blue"};
        JComboBox cb = new JComboBox(comboBoxItems);
        cb.setEditable(false);
        cb.addActionListener(this);
        comboBoxPane.add(cb);

        cards = new JPanel(new CardLayout());

        pane.add(comboBoxPane, BorderLayout.PAGE_START);
        pane.add(cards, BorderLayout.CENTER);

        JPanel red = new JPanel();
        red.setBackground(Color.RED);
        red.setPreferredSize( new Dimension(200, 50) );
        cards.add(red, "Red");

        JPanel green = new JPanel();
        green.setBackground(Color.GREEN);
        green.setPreferredSize( new Dimension(200, 50) );
        cards.add(green, "Green");

        JPanel blue = new JPanel();
        blue.setBackground(Color.BLUE);
        blue.setPreferredSize( new Dimension(200, 50) );
        cards.add(blue, "Blue");
    }

    public void actionPerformed(ActionEvent e)
    {
        Component visible = getVisibleCard();

        JComboBox comboBox = (JComboBox)e.getSource();
        String item = comboBox.getSelectedItem().toString();
        CardLayout cl = (CardLayout)(cards.getLayout());
        cl.show(cards, item);

        //  change code below to create and show your card.

        if (visible == getVisibleCard())
            JOptionPane.showMessageDialog(cards, "Card (" + item + ") not found");

    }

    private Component getVisibleCard()
    {
        for(Component c: cards.getComponents())
        {
            if (c.isVisible())
                return c;
        }

        return null;
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("CardLayoutTest");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        CardLayoutTest demo = new CardLayoutTest();
        demo.addComponentToPane(frame.getContentPane());
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
4 голосов
/ 18 мая 2011

CardLayout API не позволяет проверить, был ли компонент уже добавлен с заданным именем.

Если вы действительно хотите это сделать (но я настоятельно рекомендую ПРОТИВ сделав это), вы можете использовать отражение в CardLayout, используемом контейнером, и прочитать его поле vector, а затем проверить каждую запись (типа CardLayout$Card) на предмет заданного имени.Как вы видите, это выглядит как взлом, и он может сломаться, если CardLayout был когда-нибудь подвергнут рефакторингу (текущая реализация довольно уродлива).

Лучший способ для вас - непосредственно отслеживать именавсе добавленные потомки в поле Set<String> где-то.И это действительно не так уж и сложно.

...