【问题标题】:updating change to another class将更改更新到另一个类
【发布时间】:2016-03-08 20:04:07
【问题描述】:

我是java新手,我被困在这里......我想要做的是将一个java文件中的arraylist的更改更新为另一个文件中的JPanel。我正在对数组列表进行排序,因此无法手动完成。有没有办法让我“告诉”JPanel 疼痛发生了什么?

我有 BubbleSort.java 进行排序(工作),Animation.java 包含 JPanel 和 JFrame 类(用于显示未排序的直方图)。

这是家庭作业,所以我不想在这里发布我的代码。但是如果我的描述不起作用,我会发布它。

谢谢!

更新:嗯,作业需要冒泡排序,所以我必须这样做。 https://www.youtube.com/watch?v=wB7ovstyH4E 这就是它的假设。我只有前几秒内未排序的黄色直方图和有效的排序方法。

【问题讨论】:

  • 不要使用冒泡排序,java有免费的timsort...
  • @P Zhu 你能描述一下你的unsorted histograms 的样子吗。
  • @P Zhu 下面看看我的解决方案。

标签: java swing


【解决方案1】:

有没有一种方法可以“告诉”JPanel 排序过程中发生了什么?

有很多方法可以做到这一点。最直接的方法是保留当前未排序列表的引用并在面板类中执行排序。每次从列表中交换 2 个元素时,调用 repaint() 重新绘制列表中元素的当前位置。


然而,更优雅的方式是使用观察者模式,方法是在DrawingPanel 和执行排序的类之间建立契约。

DrawingPanel 可以实现 Observer 接口,而 SortAlgorightm 类实现 Observable 接口。

您可以让DrawingPanel 每次在sorting class 中交换两个元素时得到通知。


在您的观察者模式中,您将拥有以下接口:

public interface Observer
{
    public void update(ArrayList<Integer> list);    
}

public interface Observable
{
    public void register(Observer o);
    public void unregister(Observer o);
    public void notifyObservers();
}

在 GUI 和排序算法之间建立合约

class DrawingPanel extends JPanel implements Observer{
    //Other attributes and initializations not shown
    @Override
    public void update(ArrayList<Integer> list){
        this.list = list;   //You can choose to receive element 
                            //indexs which got swapped instead (this is up to you)
        repaint();          //Repaint your current display when list is updated
    }

    //Register myself with the sorting algorithm class
    public void registerWith(Observable ob){
        if(ob != null)
            ob.register(this);
    }
}

在您的 SortingAlgorithm 类中,使其能够向已在该类中注册的所有观察者发送更新:

class SortingAlgorithm implements Observable{
    private ArrayList<Observer> observers;  //keep a list of observers for notifying
    //Other attributes and initializations not shown

    @Override
    public void register(Observer o){
        observers.add(o);       
    }

    @Override
    public void unregister(Observer o){
        observers.remove(o);
    }

    @Override
    public void notifyObservers(){
        for(Observer o : observers)
            o.update(list);  //Update all observers with your latest list updates
    }

    public void bubbleSort(){
        //Your sorting happens here..
        for(int i=0; i < n; i++){
            for(int j=1; j < (n-i); j++){
                if(intArray[j-1] > intArray[j]){
                    //swap the elements!
                    temp = intArray[j-1];
                    intArray[j-1] = intArray[j];
                    intArray[j] = temp;

                    //Notify GUI to update screen
                    notifyObservers();
                }    
            }
        }
    } 
}

有了以上内容,GUI 将在您需要时随时更新。在这种情况下,由于我们将notifyObservers(observers); 放在了bubbleSort() 中,尤其是在交换元素时,因此只有在列表更改时才会更新GUI。

即使您不是在 JPanel 上而是在其他 contentPanes 上显示您的 GUI,也可以应用相同的逻辑。只需让类处理UI实现Observer并将其注册到SortingClass即可。

如果您只有 1 个observer,您甚至不需要保留Observers 的列表。您可以随时调整我示例中的小细节。


如果您不希望在交换 2 个元素时更新 GUI,您可以随时将 notifyObservers(); 移动到另一个您想要更新的位置。

【讨论】:

  • 非常感谢!我正在尝试,但有一些问题。是导入了 Observable 模式,还是我应该创建自己的? notifyObservers() 方法也有参数吗?我在排序循环中看到它将观察者作为参数传递,但在方法签名中没有。
  • 我完全赞成使用观察者模式,但是如果我要设置这样的自定义观察者,我会更倾向于为事件提供更好的命名(例如@987654337 @),当只有一个可能的事件时,它可能不会有太大的不同,但是如果你想添加更多的事件,它可以让生活变得更轻松(恕我直言)。我也很想从EventListener 扩展,这样你就可以使用EventListenerList 在Swing 组件中具有protected 访问权限来管理它,只需少处理一件事情;) - 仍然+ 1 推荐 :)
  • @PZhu 观察者模式不要必须被导入,你唯一需要做的就是在你的项目中再创建2个接口. (Observer 和 Observable 接口就像我在示例中显示的那样)。尽管 Java 也有 Observer 接口,但我建议您实现自己的接口。这样,您可以自定义所需的抽象方法。notifyObservers() 没有参数。我已经修改了它。 (我凌晨 4 点写这篇文章时太困了)。
  • @PZhu 如果我的解决方案对您有所帮助,您可以通过单击我的答案旁边的空心勾号来接受我的解决方案。 :)
  • @MadProgrammer 也许您可以向我们展示EventListenerList 的实现?我会毫不犹豫地投票。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-05
  • 1970-01-01
  • 2014-06-13
  • 2021-04-25
  • 1970-01-01
  • 2013-10-01
  • 2015-04-29
相关资源
最近更新 更多