Доступ к родительскому классу с помощью ActionListener - PullRequest
2 голосов
/ 02 января 2012

Я получил это как домашнее упражнение, но понятия не имею, как его решить ... (Просто часть доступа довольно сложно понять)

Итак, у меня есть два класса: «Top» и «Main». Класс Top выглядит следующим образом: (Краткое объяснение: переменная "панель" класса Top будет использоваться в классе Main в качестве верхней панели, Main расширяет JFrame и имеет BorderLayout)

public class Top extends JPanel implements ActionListener {

//public JPanel pane;
public JButton red, green, blue, white, black;

public Top() {
    //pane = new JPanel(); //Useless, as Top is already a JPanel
    this.setLayout(new FlowLayout(FlowLayout.CENTER));
    this.setBackground(new Color(0xc9c9c9)); //A gray background

    red = new JButton("Red");
    red.setBackground(Color.red);
    red.addActionListener(this);
    this.add(red);

    green = new JButton("Green");
    green.setBackground(Color.green);
    green.addActionListener(this);
    this.add(green);

    blue = new JButton("Blue");
    blue.setBackground(Color.blue);
    blue.addActionListener(this);
    this.add(green);

    white = new JButton("White");
    white.setBackground(Color.white);
    white.addActionListener(this);
    this.add(white);

    black = new JButton("Black");
    black.setForeground(Color.white);
    black.setBackground(Color.black);
    black.addActionListener(this);
    this.add(black);
    }

public void actionPerformed(ActionEvent e) {
    Main main = (Main)e.getSource();
    if (e.getSource() == this.red)
        main.setCENTER(1);
    if(e.getSource() == this.green)
        main.setCENTER(2);
    if(e.getSource() == this.blue)
        main.setCENTER(3);
    if(e.getSource() == this.white)
        main.setCENTER(4);
    if(e.getSource() == this.black)
        main.setCENTER(5);
    }
}

Класс Top используется в Main, и каждый раз, когда нажимается каждая из кнопок, меняется фон области CENTER в классе Main. Поэтому я запрограммировал небольшую функцию setCENTER, которая меняет фон. код для него выглядит следующим образом (код в классе Main):

    public void setCENTER(int var){
    switch(var){
        case 1: pane.setBackground(Color.red);
        break;
        case 2: pane.setBackground(Color.green);
        break;
        case 3: pane.setBackground(Color.blue);
        break;
        case 4: pane.setBackground(Color.white);
        break;
        case 5: pane.setBackground(Color.black);
        break;
    }
}

Пока что содержимое отображается правильно (верхняя панель в главном окне и само главное окно), но каждый раз, когда я пытаюсь изменить фон, нажимая на одну из 5 кнопок на верхней панели, я получаю ошибки и первая ошибка указывает на эту строку метода actionPerformed в классе Top:

        Main main = (Main)e.getSource();

Я попытался заменить его на "Main main = new Main ();". Это сработало, фон изменился, но каждый раз, когда я нажимал на него, открывалось новое окно (что явно не так, как оно должно вести себя).

РЕДАКТИРОВАТЬ: я забыл, что Top уже является JPanel, поэтому использование другого JPanel внутри класса довольно бессмысленно. (Отредактированный источник)

Ответы [ 3 ]

2 голосов
/ 02 января 2012

Источником события является кнопка.Чтобы найти панель, которой принадлежит кнопка, вы можете получить родительский элемент для кнопки:

JButton button = (JButton)e.getSource();
JPanel parent = button.getParent();

Чтобы получить основную панель, вам может потребоваться также вызвать getParent () на родительской панели.

1 голос
/ 02 января 2012

Источником действия является JButton, а не Main, поэтому вы получаете исключение при попытке его разыграть.

Вы можете рассмотреть возможность передачи своего Main экземпляра классу Top

0 голосов
/ 02 января 2012

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

   public static <T extends Container> T findParent(Component comp, Class<T> clazz)  {
      if (comp == null)
         return null;
      if (clazz.isInstance(comp))
         return (clazz.cast(comp));
      else
         return findParent(comp.getParent(), clazz);     
   }

Итак, если вы хотите найти FooPanel, которая является предком Баттона, который запустил событие, вы бы сказали

FooPanel fooPanel = findParent((Component)event.getSource(), FooPanel.class);
fooPanel.doSomething...
...