访问其他类的 Swing 组件

Posted

技术标签:

【中文标题】访问其他类的 Swing 组件【英文标题】:accessing swing component of other class 【发布时间】:2013-01-02 22:04:27 【问题描述】:

我有两个类 mainpanel.java 和 subpanel.java。 subpanel.class 包含一个复选框和一些标签。当我单击 mainpanel.java 中的一些按钮时,我想更改这些组件的 setSelected() 和 setText() 。

我在 subpanel.java 中创建了一个方法,我从 mainpanel.java 调用它并传递布尔值。

public void schedulerchange(boolean check)
        System.out.println("checked"+check);
        scheduleenabler.setEnabled(check);
        scheduleenabler.setSelected(check);
        scheduleinfo.setText("Scheduler in On");
        //subpanel21.updateUI();
    

当我从 mainpanel.java 调用此函数时,该函数被调用但值不会改变,除非我将 jcheckbox 和 jlabel 设为静态。但据我所知,除非非常必要,否则我们不应该使用静态组件。 有没有其他方法可以改变组件?

【问题讨论】:

我猜在设置启用后调用 scheduleenabler.revalidate() 会成功的。 “我有两个类 mainpanel.java 和 subpanel.java” 不要扩展任何一个。只需保留参考。还保留对文本组件的引用,问题就解决了。还请了解类、方法和属性名称的常见 Java naming conventions(特别是用于名称的大小写)并始终如一地使用它。 @che revalidate() 不工作。如果我使用静态,它仍在更新复选框 【参考方案1】:

如果我理解了您的问题,那么我认为您想编写一个单独的 ActionListener 类并在那里执行将启用或禁用 UI 类中的 JCheckBox 的操作。下面的代码显示了这一点。将您的复选框引用传递给 PerformAction 类,并通过单击按钮使其启用或禁用。

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class MainClass 

 MainClass() 
    JFrame jfrm = new JFrame("JTable Demo");
    jfrm.setLayout(new FlowLayout());
    jfrm.setSize(460, 180);
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JCheckBox check = null;
    // Get the Panel from the subclass;
    JPanel panel = new CheckBox().getCheckBoxPanel();

    // From the compoenents present in the panel get the CheckBox compoenent.
    for(int i = 0; i < panel.getComponentCount(); i++) 
       if(panel.getComponent(i) instanceof JCheckBox) 
        check = (JCheckBox) panel.getComponent(i);
        
    

    JButton button = new JButton("Click");

    // Pass the CheckBox Compoenent to the ActionListener.
button.addActionListener(new PerformAction(check));

    jfrm.add(button);
    jfrm.add(panel);
    jfrm.setVisible(true);
 

  public static void main(String args[]) 
  EventQueue.invokeLater(new Runnable() 

      @Override
      public void run() 
          new MainClass();
      
  );
 


class PerformAction implements ActionListener 

JCheckBox check = null;
public PerformAction(JCheckBox checkBox) 
    check = checkBox;

@Override
public void actionPerformed(ActionEvent e) 
    boolean checkStatus = check.isSelected();
    if(checkStatus == true) 
        check.setEnabled(false);
        check.setSelected(false);
     else 
        check.setEnabled(true);
        check.setSelected(true);
      



 class CheckBox 
public JPanel getCheckBoxPanel() 
    JPanel checkPanel = new JPanel();
    JCheckBox check = new JCheckBox();
    checkPanel.add(new JLabel("CheckBox"));
    checkPanel.add(check);

    return checkPanel;


【讨论】:

我正在使用两个不同的类。子面板类将面板返回给主面板类。此面板包含一个复选框和标签,当我单击主面板类中的按钮时,我试图更改其属性。 看看我的更新代码。这将获取面板并从面板中获取组件,然后将其传递给 ActionPerformed 类。希望这会有所帮助.. ;-) @RohanKandwal:不要忽视对您认为有帮助的答案进行投票。【参考方案2】:

这不适合使用 updateUI(),它“将 UI 属性重置为当前外观的值”。正如评论中所建议的那样,使用revalidate() 只有在将组件添加到封闭的Container 或从中删除组件时才会有帮助。相反,直接在子面板实例上调用repaint()。为了获得更大的灵活性,请使用建议的观察者 pettern here。

附录:本例使用Action 封装按钮的行为。因为复选框的选中状态是一个绑定属性,组件会自动重绘,但如果需要,您可以显式调用repaint()

附录:更新以将引用作为参数传递。

附录:在此变体中,参数是对导出的Action 的引用。

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

/** @see https://***.com/a/14412516/230513 */
public class Example 

    private void display() 
        JFrame f = new JFrame("Example");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new GridLayout(0, 1));
        JPanel panel = new JPanel();
        final JCheckBox check = new JCheckBox("Check");
        Action checkAction = new AbstractAction("Update") 

            @Override
            public void actionPerformed(ActionEvent e) 
                check.setSelected(!check.isSelected());
            
        ;
        panel.add(check);
        f.add(panel);
        f.add(new SubPanel(checkAction));
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    

    private static class SubPanel extends JPanel 

        public SubPanel(final Action action) 
            this.add(new JButton(action));
        
    

    public static void main(String[] args) 
        EventQueue.invokeLater(new Runnable() 

            @Override
            public void run() 
                new Example().display();
            
        );
    

【讨论】:

我几乎是个菜鸟,所以我不太了解深度编码。一个有两个类的简单例子会很好 感谢您的示例,但您的示例使用的是一个在 actionPerformed 上进行更新的类。当我执行其他类的操作时,我想选择/取消选择复选框。 您可以将目标组件的引用作为参数传递给您的子面板类。 你能详细说明一下吗?您是否建议使用 object_of_subpanel_class.checkbox.setEnabled(true) ?如果你是,那么我已经在使用它,但只有当我将复选框设置为静态时,该值才会更新。 另一种常见的做法是将Action与组件关联,如上图所示。如需更多指导,请编辑您的问题以包含一个sscce,以显示您当前的方法。

以上是关于访问其他类的 Swing 组件的主要内容,如果未能解决你的问题,请参考以下文章

swing类的类名都以大写字母啥开头

swing学习

从另一个类访问 Swing 组件

Java swing 添加来自另一个类的组件

Swing 顶层容器

架构:放置不依赖于任何其他服务或存储库组件的服务类的位置