Java 如何从其父JFrame外部重新绘制JPanel?
当填充面板的方法被其父JFrame事件调用时,我可以在Java 如何从其父JFrame外部重新绘制JPanel?,java,swing,Java,Swing,当填充面板的方法被其父JFrame事件调用时,我可以在面板中添加/删除元素,并重新绘制它,但我不能通过其他类的事件重新绘制它,即使它们的源已经添加到面板中,或者这就是我现在理解问题的方式 我想知道这里发生了什么,谢谢 主类 public class Principal extends JFrame implements ActionListener{ private static Principal instPrincipal = null; private SubClass subCl
面板中添加/删除元素,并重新绘制它,但我不能通过其他类的事件重新绘制它,即使它们的源已经添加到面板中,或者这就是我现在理解问题的方式
我想知道这里发生了什么,谢谢
主类
public class Principal extends JFrame implements ActionListener{
private static Principal instPrincipal = null;
private SubClass subClassInst =new SubClass();
public JPanel panelPrincipal;
public static Principal getInstance() {
if (instPrincipal != null)
return instPrincipal ;
else {
instPrincipal = new Principal ();
return instPrincipal ;
}
}
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
try {
if(source == btnSub)
{
subClassInst.fillPanelPrincipal();
}
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
子类示例
public class SubClass implements ActionListener {
private JPanel tempPanel;
private JButton btnSave;
private Principal instPrincipal;
public void fillPanelPrincipal() {
instPrincipal = Principal.getInstance();
instPrincipal.panelPrincipal.removeAll();
//Start adding elements..
tempPanel = new JPanel();
instPrincipal.panelPrincipal.add(tempPanel);
btnSave = new JButton("Save");
btnSave.addActionListener(this);
tempPanel.add(btnSave);
//End.
instPrincipal.panelPrincipal.repaint();
}
public void actionPerformed(ActionEvent event) {
instPrincipal = Principal.getInstance();
Object source = event.getSource();
if (source == btnSave) {
// modify local data, Database .. ; //work but need to be repainted on panelPrincipal
instPrincipal.panelPrincipal.repaint();//does not work
}
}
}
更新
public class SubClass implements ActionListener {
private JPanel tempPanel;
private JButton btnSave;
private Principal instPrincipal;
public void fillPanelPrincipal() {
instPrincipal = Principal.getInstance();
instPrincipal.panelPrincipal.removeAll();
//Start adding elements..
tempPanel = new JPanel();
instPrincipal.panelPrincipal.add(tempPanel);
btnSave = new JButton("Save");
btnSave.addActionListener(this);
tempPanel.add(btnSave);
//End.
instPrincipal.panelPrincipal.repaint();
}
public void actionPerformed(ActionEvent event) {
instPrincipal = Principal.getInstance();
Object source = event.getSource();
if (source == btnSave) {
// modify local data, Database .. ; //work but need to be repainted on panelPrincipal
instPrincipal.panelPrincipal.repaint();//does not work
}
}
}
为了进一步澄清这个问题,我在一个JFrame
上有一个JPanel
,有不同的类来填充它的多个功能,我在主框架上使用JMenuItems
调用它们的方法,这些类实现ActionListener
,通过面板不起作用,还有我在这里尝试的方法。
我曾考虑将设计更改为使用CardLayout
,但这非常困难。您将主体作为静态引用调用,那么它如何知道要重新绘制的帧?您应该通过子类的构造函数传递JFrame的实例。像这样:
private SubClass subClassInst = new SubClass(this);
然后像这样创建构造函数
private JFrame parent;
public SubClass(JFrame parent) { this.parent = parent; }
你可以这样使用它
this.parent.repaint();
您不应该将您的JPanel声明为static
@user3437460 static在这里不是问题,它只是对类的所有对象都意味着相同,对于您,我做了一个没有它的测试,但没有任何更改。谢谢。这是公共静态JPanel panelPrincipal代码>非常危险。实际上,您无法控制其他类如何更改此值,无法保证您引用的值实际上就是屏幕上的值。以这种方式使用是一个很好的迹象表明一个糟糕的设计。此外,基于使用设置边界
,这表明您没有使用布局管理器,这意味着重新验证
是毫无意义的,这可能是另一个潜在问题的指示器,考虑提供一个能证明您的问题的布局管理器。这不是一个代码转储,而是您正在做的一个示例,它突出了您所遇到的问题。这将减少混乱,提高效率responses@TiyebBellal我并不是说制作你的JPanel会神奇地让一切都运转起来,而且永远不会。我说过你不应该让你的面板是静态的,因为你不必这样做,而且你会遇到很多不希望出现的问题。我已经按照你的建议通过了JFrame参数,但这不是问题所在,谢谢。