Java Swing GUI를 만들고, 단추가 들어있는 다른 패널을 포함하는 패널이 포함 된 프레임이 있다고 가정 해 보겠습니다. (패널은 재사용 가정하고, 그래서 각각의 클래스로 그들을했습니다.)하위 GUI 구성 요소는 부모 (MVC 사용)에 어떻게 액세스해야합니까?
Frame → FirstPanel → SecondPanel → Button
현실에서, 아이들의 라인이 더 복잡 할 수 있지만, 난 그냥 간단한 예제를 유지하려는.
단추가 상위 구성 요소 중 하나 (예 : 프레임 크기 조정)를 제어하도록하려면 두 GUI 클래스 사이에 반드시 기능을 구현하는 가장 좋은 방법은 무엇입니까?
getParent()
메서드를 함께 묶거나 Frame
의 인스턴스를 자식을 통해 전달하여 SecondPanel
에서 액세스 할 수있는 아이디어가 마음에 들지 않습니다. 기본적으로 데이지 체인 방식으로 수업을 함께하고 싶지 않습니다.
버튼이 부모 구성 요소가 아닌 모델을 직접 업데이트해야하는 인스턴스입니까? 그런 다음 부모에게 모델의 변경 사항이 통보되고 그에 따라 업데이트됩니다.
내 문제를 설명하기 위해 컴파일하고 실행해야하는 약간의 예를 정리했습니다. JFrame의 다른 JPanel에있는 JPanel의 두 JButton입니다. 단추는 JFrame의 크기를 제어합니다. 내가 좋아하지 않는 무엇
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MVCExample
{
public static void main(String[] args)
{
Model model = new Model();
Controller ctrl = new Controller();
ctrl.registerModel(model);
View view = new View(ctrl);
view.setVisible(true);
model.init();
}
/**
* Model class
*/
static class Model
{
private ArrayList<PropertyChangeListener> listeners =
new ArrayList<PropertyChangeListener>();
private Dimension windowSize;
public Dimension getWindowSize(){ return windowSize; }
public void setWindowSize(Dimension windowSize)
{
if(!windowSize.equals(getWindowSize()))
{
firePropertyChangeEvent(getWindowSize(), windowSize);
this.windowSize = windowSize;
}
}
public void init()
{
setWindowSize(new Dimension(400, 400));
}
public void addListener(PropertyChangeListener listener)
{
listeners.add(listener);
}
public void firePropertyChangeEvent(Object oldValue, Object newValue)
{
for(PropertyChangeListener listener : listeners)
{
listener.propertyChange(new PropertyChangeEvent(
this, null, oldValue, newValue));
}
}
}
/**
* Controller class
*/
static class Controller implements PropertyChangeListener
{
private Model model;
private View view;
public void registerModel(Model model)
{
this.model = model;
model.addListener(this);
}
public void registerView(View view)
{
this.view = view;
}
// Called from view
public void updateWindowSize(Dimension windowSize)
{
model.setWindowSize(windowSize);
}
// Called from model
public void propertyChange(PropertyChangeEvent pce)
{
view.processEvent(pce);
}
}
/**
* View classes
*/
static class View extends JFrame
{
public View(Controller ctrl)
{
super("JFrame");
ctrl.registerView(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().add(new FirstPanel(ctrl));
pack();
}
public void processEvent(PropertyChangeEvent pce)
{
setPreferredSize((Dimension)pce.getNewValue());
pack();
}
}
static class FirstPanel extends JPanel
{
public FirstPanel(Controller ctrl)
{
setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(
Color.RED, 2), "First Panel"));
add(new SecondPanel(ctrl));
}
}
static class SecondPanel extends JPanel
{
private Controller controller;
private JButton smallButton = new JButton("400x400");
private JButton largeButton = new JButton("800x800");
public SecondPanel(Controller ctrl)
{
this.controller = ctrl;
setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(
Color.BLUE, 2), "Second Panel"));
add(smallButton);
add(largeButton);
smallButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
controller.updateWindowSize(new Dimension(400, 400));
}
});
largeButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
controller.updateWindowSize(new Dimension(800, 800));
}
});
}
}
}
는 컨트롤러가 프레임이 이벤트를 수신하기 위해 자신을 등록 할 수 있도록 JFrame의 존재해야한다는 것입니다. 그런 다음 컨트롤러는 패널이 모델과 통신 할 수 있도록 SecondPanel (줄 112, 131 및 143)까지 모두 통과해야합니다.
여기에 비효율적 인 무언가가있는 것처럼 느껴집니다 (클래스가 너무 단단히 결합 됨). 내 문제가 명확하지 않은 경우 알려주십시오.
이 방법은 흥미로운 방법입니다. 내 특별한 경우를 더주의 깊게 고려해야 할 것입니다. – Knave