如何在初始化后将组件添加到 JFrame?
How to add components to a JFrame after initialization?
我有一个 JFrame。当它首次启动时,它不会加载按钮(有意),因为它取决于一个布尔值 sessionExists,默认情况下为 false。当用户单击“添加”以启动 JDialog 并在该 JDialog 中单击“确定”时,它将 JFrame 的 sessionExists 值设置为 true。
我希望代码做什么:
单击确定后,我希望 JFrame 自行更新并显示带有文本“新按钮”的按钮,因为 sessionExists 现在为真。
当前行为:
目前,用户点击“确定”,JDialog退出,但父JFrame保持不变,按钮不出现。
我试过的解决方案:
我尝试在 JFrame 中使用 .validate 和 .repaint() 来刷新它以便显示按钮,但它似乎不起作用。
我应该如何实现预期的行为?我应该使用 CardLayout 吗?
我使用下面的代码重现了这个问题。我的实际程序依赖于文件是否存在而不是布尔变量。
JFrame
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import javax.swing.JDialog;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class MainMenu extends JFrame {
private JPanel contentPane;
MainMenu thisFrame = this;
boolean sessionExists = false;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainMenu frame = new MainMenu();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MainMenu() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
if (sessionExists == true) {
JButton btnNewButton = new JButton("New button");
contentPane.add(btnNewButton, BorderLayout.CENTER);
}
JButton btnNewButton_1 = new JButton("Add Button");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Add newTask = new Add(thisFrame);
newTask.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
newTask.setTitle("Add Task");
newTask.setVisible(true);
}
});
contentPane.add(btnNewButton_1, BorderLayout.SOUTH);
}
public void refresh() {
this.validate();
this.repaint();
}
}
“添加”JDialog
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Add extends JDialog {
private final JPanel contentPanel = new JPanel();
public Add(MainMenu parentJFrame) {
setBounds(100, 100, 450, 300);
getContentPane().setLayout(new BorderLayout());
contentPanel.setLayout(new FlowLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
{
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPane, BorderLayout.SOUTH);
{
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
parentJFrame.sessionExists = true;
parentJFrame.refresh();
dispose();
}
});
okButton.setActionCommand("OK");
buttonPane.add(okButton);
getRootPane().setDefaultButton(okButton);
}
{
JButton cancelButton = new JButton("Cancel");
cancelButton.setActionCommand("Cancel");
buttonPane.add(cancelButton);
}
}
}
}
当您尝试添加它时,您没有调用 if(session == true)。取而代之的是创建像 adding() 这样的新函数,并从 Add JDialog class 中调用它,它将起作用。(你会注意到你不必使用 session == true 因为你可以调用直接以这种方式运行。但为了您的理解,我没有改变它。)
示例代码:
主菜单:
public class MainMenu extends JFrame {
private JPanel contentPane;
MainMenu thisFrame = this;
boolean sessionExists = false;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainMenu frame = new MainMenu();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MainMenu() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JButton btnNewButton_1 = new JButton("Add Button");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Add newTask = new Add(thisFrame);
newTask.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
newTask.setTitle("Add Task");
newTask.setVisible(true);
}
});
contentPane.add(btnNewButton_1, BorderLayout.SOUTH);
}
public void adding() {
if (sessionExists == true) {
JButton btnNewButton = new JButton("New button");
contentPane.add(btnNewButton, BorderLayout.CENTER);
}
}
public void refresh() {
this.validate();
this.repaint();
}
}
添加:
public class Add extends JDialog {
private final JPanel contentPanel = new JPanel();
public Add(MainMenu parentJFrame) {
setBounds(100, 100, 450, 300);
getContentPane().setLayout(new BorderLayout());
contentPanel.setLayout(new FlowLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
{
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPane, BorderLayout.SOUTH);
{
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
parentJFrame.sessionExists = true;
parentJFrame.adding();
parentJFrame.refresh();
dispose();
}
});
okButton.setActionCommand("OK");
buttonPane.add(okButton);
getRootPane().setDefaultButton(okButton);
}
{
JButton cancelButton = new JButton("Cancel");
cancelButton.setActionCommand("Cancel");
buttonPane.add(cancelButton);
}
}
}
}
我有一个 JFrame。当它首次启动时,它不会加载按钮(有意),因为它取决于一个布尔值 sessionExists,默认情况下为 false。当用户单击“添加”以启动 JDialog 并在该 JDialog 中单击“确定”时,它将 JFrame 的 sessionExists 值设置为 true。
我希望代码做什么:
单击确定后,我希望 JFrame 自行更新并显示带有文本“新按钮”的按钮,因为 sessionExists 现在为真。
当前行为:
目前,用户点击“确定”,JDialog退出,但父JFrame保持不变,按钮不出现。
我试过的解决方案:
我尝试在 JFrame 中使用 .validate 和 .repaint() 来刷新它以便显示按钮,但它似乎不起作用。
我应该如何实现预期的行为?我应该使用 CardLayout 吗?
我使用下面的代码重现了这个问题。我的实际程序依赖于文件是否存在而不是布尔变量。
JFrame
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import javax.swing.JDialog;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class MainMenu extends JFrame {
private JPanel contentPane;
MainMenu thisFrame = this;
boolean sessionExists = false;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainMenu frame = new MainMenu();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MainMenu() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
if (sessionExists == true) {
JButton btnNewButton = new JButton("New button");
contentPane.add(btnNewButton, BorderLayout.CENTER);
}
JButton btnNewButton_1 = new JButton("Add Button");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Add newTask = new Add(thisFrame);
newTask.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
newTask.setTitle("Add Task");
newTask.setVisible(true);
}
});
contentPane.add(btnNewButton_1, BorderLayout.SOUTH);
}
public void refresh() {
this.validate();
this.repaint();
}
}
“添加”JDialog
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Add extends JDialog {
private final JPanel contentPanel = new JPanel();
public Add(MainMenu parentJFrame) {
setBounds(100, 100, 450, 300);
getContentPane().setLayout(new BorderLayout());
contentPanel.setLayout(new FlowLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
{
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPane, BorderLayout.SOUTH);
{
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
parentJFrame.sessionExists = true;
parentJFrame.refresh();
dispose();
}
});
okButton.setActionCommand("OK");
buttonPane.add(okButton);
getRootPane().setDefaultButton(okButton);
}
{
JButton cancelButton = new JButton("Cancel");
cancelButton.setActionCommand("Cancel");
buttonPane.add(cancelButton);
}
}
}
}
当您尝试添加它时,您没有调用 if(session == true)。取而代之的是创建像 adding() 这样的新函数,并从 Add JDialog class 中调用它,它将起作用。(你会注意到你不必使用 session == true 因为你可以调用直接以这种方式运行。但为了您的理解,我没有改变它。) 示例代码:
主菜单:
public class MainMenu extends JFrame {
private JPanel contentPane;
MainMenu thisFrame = this;
boolean sessionExists = false;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainMenu frame = new MainMenu();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MainMenu() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JButton btnNewButton_1 = new JButton("Add Button");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Add newTask = new Add(thisFrame);
newTask.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
newTask.setTitle("Add Task");
newTask.setVisible(true);
}
});
contentPane.add(btnNewButton_1, BorderLayout.SOUTH);
}
public void adding() {
if (sessionExists == true) {
JButton btnNewButton = new JButton("New button");
contentPane.add(btnNewButton, BorderLayout.CENTER);
}
}
public void refresh() {
this.validate();
this.repaint();
}
}
添加:
public class Add extends JDialog {
private final JPanel contentPanel = new JPanel();
public Add(MainMenu parentJFrame) {
setBounds(100, 100, 450, 300);
getContentPane().setLayout(new BorderLayout());
contentPanel.setLayout(new FlowLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
{
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPane, BorderLayout.SOUTH);
{
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
parentJFrame.sessionExists = true;
parentJFrame.adding();
parentJFrame.refresh();
dispose();
}
});
okButton.setActionCommand("OK");
buttonPane.add(okButton);
getRootPane().setDefaultButton(okButton);
}
{
JButton cancelButton = new JButton("Cancel");
cancelButton.setActionCommand("Cancel");
buttonPane.add(cancelButton);
}
}
}
}