访问其他类的 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 组件的主要内容,如果未能解决你的问题,请参考以下文章