【发布时间】:2014-07-22 11:28:29
【问题描述】:
我正在尝试这样做:在我的 GUI 中,我有一个带有自定义模型的 JTable,而在 GUI 的其他部分,我有一个面板,我可以在其中绘制一些箭头。我想“同步这两个视图。假设我们的 JTable 中有 5 行,我将在箭头面板中绘制 5 个箭头。如果我对行数进行修改,我必须有相同的行数排。 所以我正在尝试使用设计模式观察者。
为了简单起见,我尝试在一个文件中提供一个可计算的示例: 我在我的第一个面板 (ButtonPanel) 中创建了 n 个按钮,并在第二个面板 (LabelButton) 中创建了 n 个标签。
问题是:如何用DP Observer同步标签个数和标签个数
import java.awt.Color;
import java.awt.GridLayout;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
interface Observer {
public void update(Subject subject, int number);
}
interface Subject {
public void addObserver(Observer observer);
public void delObserver(Observer observer);
public void notifyObservers();
}
class SynchronizeNumber implements Subject {
private ArrayList<Observer> observers;
private int numberSync;
public SynchronizeNumber() {
super();
observers = new ArrayList<Observer>();
}
public SynchronizeNumber(int numberSync) {
super();
this.numberSync = numberSync;
observers = new ArrayList<Observer>();
}
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}
@Override
public void delObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer o : observers) {
o.update(this, this.numberSync);
}
}
/**
* @return the number
*/
public int getNumberSync() {
return numberSync;
}
/**
* @param number
* the number to set
*/
public void setNumberSync(int numberSync) {
this.numberSync = numberSync;
notifyObservers();
}
}
class ButtonPanel extends JPanel implements Observer {
private int numberButton;
public ButtonPanel() {
super();
}
public ButtonPanel(int numberButton) {
this.numberButton = numberButton;
for (int i = 1; i <= numberButton; i++)
this.add(new JButton("" + i));
}
/**
* @return the numberLabel
*/
public int getNumberButton() {
return numberButton;
}
/**
* @param numberLabel
* the numberLabel to set
*/
public void setNumberButton(int numberButton) {
this.numberButton = numberButton;
}
@Override
public void update(Subject subject, int number) {
if (subject instanceof SynchronizeNumber) {
SynchronizeNumber synchronizeNumber = (SynchronizeNumber) subject;
numberButton = synchronizeNumber.getNumberSync();
System.out.println("ButtonPanel, numberButton: " + numberButton);
}
}
}
class LabelPanel extends JPanel implements Observer {
private int numberLabel;
public LabelPanel() {
super();
}
public LabelPanel(int numberLabel) {
super();
this.numberLabel = numberLabel;
for (int i = 1; i <= numberLabel; i++)
this.add(new JLabel("label numbe: " + i));
this.setBorder(new LineBorder(Color.blue));
}
@Override
public void update(Subject subject, int number) {
if (subject instanceof SynchronizeNumber) {
SynchronizeNumber synchronizeNumber = (SynchronizeNumber) subject;
numberLabel = synchronizeNumber.getNumberSync();
System.out.println("LabelPanel, numberLabel: " + numberLabel);
}
}
/**
* @return the numberLabel
*/
public int getNumberLabel() {
return numberLabel;
}
/**
* @param numberLabel
* the numberLabel to set
*/
public void setNumberLabel(int numberLabel) {
this.numberLabel = numberLabel;
}
}
public class Test {
public static void main(String[] args) {
JFrame f = new JFrame();
f.setLayout(new GridLayout(2, 1));
// create an subject synchronizeNumber
SynchronizeNumber synchronizeNumber = new SynchronizeNumber();
// set number to 1
synchronizeNumber.setNumberSync(1);
//create observers buttonPanel and labelPanel
ButtonPanel buttonPanel = new ButtonPanel(synchronizeNumber.getNumberSync());
LabelPanel labelPanel = new LabelPanel(synchronizeNumber.getNumberSync());
// add buttonPanel and labelPanel as observers
synchronizeNumber.addObserver(buttonPanel);
synchronizeNumber.addObserver(labelPanel);
// make a change manually
synchronizeNumber.setNumberSync(4);
f.add(buttonPanel);
f.add(labelPanel);
f.setSize(400, 400);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
编辑:我使用自己的 DP Observer 而不是来自 API,因为无法进行多次扩展
【问题讨论】:
-
“假设我们的 JTable 中有 5 行,我将在箭头面板中绘制 5 个箭头。” 绝对有必要使用观察者模式吗?这是任务还是要求?如果没有,那么每次从表模型中插入/删除一行时,实现TableModelListener 来更新面板会更容易。
-
我使用观察者模式是因为我认为它是最好的解决方案。我有两个类,我希望这两个类之间有一个最小的依赖关系。
-
@dic19 不是监听者模式吗?
标签: java swing user-interface design-patterns observer-pattern