在外部更新现有 JFrame 的组件



这是我遇到的问题-我有一个GUI类用构造函数实现JFrame,该构造函数在3x3网格布局中用9个面板构建Frame。每个Panel都在这个构造函数中初始化,并有自己的监听器等。然而,有一个菜单选项可以加载要显示的文件,但为了使我能够保存/加载文件,我有一个专门用于保存和加载的类。我已经测试过了,问题在于当调用save/load类中的load方法时,它会创建一个GUI对象,从而重新制作GUI组件。当GUI对象用于调用GUI中名为loadedFile的方法(GUI.loadedFile)时,程序应该将每个JPanel设置为特定的RGB值背景。然而,它并没有更新我的JPanel的背景。这是构造函数的一部分,它初始化面板和加载的文件代码:

A1 = new JPanel();
        A1.addMouseListener(mouseListener);
        A1.setBackground(Color.WHITE);
        add(A1);
    A2 = new JPanel();
        A2.addMouseListener(mouseListener);
        A2.setBackground(Color.WHITE);
        add(A2);
    A3 = new JPanel();
        A3.addMouseListener(mouseListener);
        A3.setBackground(Color.WHITE);
        add(A3);
    B1 = new JPanel();
        B1.addMouseListener(mouseListener);
        B1.setBackground(Color.WHITE);
        add(B1);
    B2 = new JPanel();
        B2.addMouseListener(mouseListener);
        B2.setBackground(Color.WHITE);
        add(B2);
    B3 = new JPanel();
        B3.addMouseListener(mouseListener);
        B3.setBackground(Color.WHITE);
        add(B3);
    C1 = new JPanel();
        C1.addMouseListener(mouseListener);
        C1.setBackground(Color.WHITE);
        add(C1);
    C2 = new JPanel();
        C2.addMouseListener(mouseListener);
        C2.setBackground(Color.WHITE);
        add(C2);
    C3 = new JPanel();
        C3.addMouseListener(mouseListener);
        C3.setBackground(Color.WHITE);
        add(C3);
    System.out.println("GUI() invoked");
}

已加载文件:

public void loadedFile(int[] colors) {
    int counter = 0;
    //if in a different pain program using JPanels in an array for larger canvases,
    //use the JPanel[counter] set to colors[counter] for BG color. Also, enhanced
    //for loop could cycle through he values of panels array and set BG.
    A1.setBackground(new Color(colors[counter], colors[counter+1], colors[counter+2]));
        counter+=3;
    A2.setBackground(new Color(colors[counter], colors[counter+1], colors[counter+2]));
        counter+=3;
    A3.setBackground(new Color(colors[counter], colors[counter+1], colors[counter+2]));
        counter+=3;
    B1.setBackground(new Color(colors[counter], colors[counter+1], colors[counter+2]));
        counter+=3;
    B2.setBackground(new Color(colors[counter], colors[counter+1], colors[counter+2]));
        counter+=3;
    B3.setBackground(new Color(colors[counter], colors[counter+1], colors[counter+2]));
        counter+=3;
    C1.setBackground(new Color(colors[counter], colors[counter+1], colors[counter+2]));
        counter+=3;
    C2.setBackground(new Color(colors[counter], colors[counter+1], colors[counter+2]));
        counter+=3;
    C3.setBackground(new Color(colors[counter], colors[counter+1], colors[counter+2]));
    System.out.println("BGS SET");
}

提前感谢任何能提供帮助的人!

一些建议:

  • 是的,使用for循环可以消除90%的冗余代码,并使调试和修改(以及让其他人阅读和理解您的代码)变得更容易
  • 更重要的是我认为您需要传递引用才能工作,特别是对应该进行加载的代码的可见GUI对象的引用,因为您希望更改影响当前可见的JFrame,对吗
  • 为这个GUI类提供公共方法,允许其他对象设置其内容的背景色。这应该是一个非构造函数方法

编辑1
其他几点:

我有一个专门用于保存和加载的课程。

正如你想把它从GUI(或"视图")代码中分离出来一样好。

我已经测试过了,问题在于当调用save/load类中的load方法时,它会创建一个GUI对象,从而重新制作GUI组件。

这就是我想让你避免的。相反,为Save/Load类提供一个接受GUI作为参数的构造函数,并使用这个GUI对象(而不是新创建的对象)来完成您的owrk。

编辑2
请阅读并遵守Java命名约定。特别是,类名应该以大写字母和变量开头,方法名应该以小写字母开头。起初,这可能看起来微不足道,但如果人们习惯了几年来以这种方式查看代码,就会更容易理解别人的代码(这通常是一个困难的过程,而当前的命名方案会使这一过程变得更加困难)。

编辑3
更具体地说,我推荐这样的东西:

public class SaveLoad { // or whatever its called
  private GUI gui;  // give it a GUI variable 
  public SaveLoad(GUI gui) {
    this.gui = gui;  load in the current GUI into save load
    // ... other code ...
  }
  public void load() {
    // get the colors
    gui.loadColors(...); // method called on the visualized GUI.

然后你可能会创建这样的SaveLoad:

public void actionPerformed(ActionEvent evt) {
  // inside some event listener
  SaveLoad saveload = new SaveLoad(GUI.this);  
  // or just this if not in an inner class then just use this
  // SaveLoad saveload = new SaveLoad(this);  
  // .....
}

Zeroth,使用for循环整理代码。

首先,检查loadedFile()是否真的将背景设置为白色以外的颜色(请将其打印到控制台上)。

其次,您应该更新事件调度线程(EDT)中的GUI——从您的代码中还不清楚您是否在这样做。

一旦设置了颜色,repaint()调用可能也是一个好主意。

最新更新