英文:
How to add components to a JFrame after initialization?
问题
我有一个JFrame。当它首次启动时,它不会加载一个按钮(故意如此),因为它取决于一个默认为false的布尔值sessionExists。当用户点击“添加”以启动一个JDialog,并在该JDialog中点击“确定”时,它将把JFrame的sessionExists值设置为true。
我希望代码实现的功能是:
在点击“确定”后,我希望JFrame更新自身,并显示文本为“new button”的按钮,因为此时sessionExists为true。
当前行为:
目前,用户点击“确定”,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();
}
}
"Add" 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);
}
}
}
}
英文:
I have a JFrame. When it first launches it won't load a button (on purpose) because it depends on a boolean value, sessionExists, that is false by default. When the user clicks add to launch a JDialog and clicks Ok in that JDialog, it will set the JFrame's sessionExists value to true.
What I want the code to do:
After Ok is clicked, I want the JFrame to update itself and display that button with the text "new button" since sessionExists is now true.
Current behavior:
Currently, the user clicks "ok", the JDialog will exit, but the parent JFrame will remain the same and the button doesn't appear.
Solution I tried:
I tried using .validate and .repaint() in the JFrame to refresh it so the button will be shown, but it doesn't seem to work.
How should I achieve the intended behavior? Should I be using CardLayout?
I reproduced the problem using the code below. My actual program relies on whether a file exists rather than a boolean variable.
The 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();
}
}
The "Add" 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);
}
}
}
}
答案1
得分: 1
你尝试添加时未调用 if(session == true),而是应创建一个名为 adding() 的新函数,在 Add JDialog 类中调用它,它将会起作用。(你会注意到你不必使用 session == true,因为可以直接通过这种方式调用函数。但为了你的理解,我没有改变它。)
示例代码:
MainMenu:
public class MainMenu extends JFrame {
// ...(其他代码)
public void adding() {
if (sessionExists == true) {
JButton btnNewButton = new JButton("New button");
contentPane.add(btnNewButton, BorderLayout.CENTER);
}
}
// ...(其他代码)
}
Add:
public class Add extends JDialog {
// ...(其他代码)
public Add(MainMenu parentJFrame) {
// ...(其他代码)
{
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);
}
// ...(其他代码)
}
// ...(其他代码)
}
英文:
You are not calling if(session == true) when you trying to add it. Instead of this, make new function like adding(), and call it from the Add JDialog class and it will be work.(You will notice you don't have to use session == true because you can call the function by this way directly. But for your understanding I didn't change it.)
Example Code:
MainMenu:
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();
}
}
Add:
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);
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论