英文:
How to refresh JInternalFrame or JPanel form on button click where JPanel is a separate class and used in JInternalFrame
问题
我试图构建一个桌面应用程序,在一个单独的JFrame内部具有多个屏幕。因此,每次按钮点击事件都会将我们带到具有刷新后的屏幕组件的单独屏幕。到目前为止,这种方法对我有效,但我面临的问题是,即使在使用“.dispose(),.repaint(),.revalidate(),.invalidate()”函数之后,JInternalFrame或JPanel似乎也不会刷新其组件。
这是一个类似下面GIF的工作示例。
[选项卡样式][1]
我知道JtabbedPane存在,但对于我的方法,JtabbedPane不可行。
以下是通过复制我遇到的问题来精简的代码。
MainMenu.Java(主类文件)
```java
package test;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JInternalFrame;
public class MainMenu extends JFrame {
private JPanel contentPane;
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, 841, 522);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JPanel panel = new JPanel();
panel.setBounds(10, 10, 807, 63);
contentPane.add(panel);
panel.setLayout(new GridLayout(1, 0, 0, 0));
JButton Tab1 = new JButton("Tab1");
panel.add(Tab1);
JButton Tab2 = new JButton("Tab2");
panel.add(Tab2);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 88, 807, 387);
contentPane.add(scrollPane);
JInternalFrame internalFrame1 = new JInternalFrame();
JInternalFrame internalFrame2 = new JInternalFrame();
Tab1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Panel1 panel1 = new Panel1();
if(internalFrame1 !=null) {
internalFrame1.dispose();
panel1.invalidate();
panel1.revalidate();
panel1.repaint();
}
internalFrame1.setTitle("Panel 1");
scrollPane.setViewportView(internalFrame1);
internalFrame1.getContentPane().add(panel1);
internalFrame1.setVisible(true);
}
});
Tab2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Panel2 panel2 = new Panel2();
if(internalFrame2 !=null) {
internalFrame2.dispose();
panel2.invalidate();
panel2.revalidate();
panel2.repaint();
}
internalFrame2.setTitle("Panel 2");
scrollPane.setViewportView(internalFrame2);
internalFrame2.getContentPane().add(panel2);
internalFrame2.setVisible(true);
}
});
}
}
以及相应的JPanel类文件,其中有JInternal Frames
Panel1.java
package test;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
public class Panel1 extends JPanel {
private JTextField textField;
/**
* 创建面板。
*/
public Panel1() {
setLayout(null);
textField = new JTextField();
textField.setBounds(10, 60, 430, 19);
add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("示例按钮");
btnNewButton.setBounds(10, 156, 430, 21);
add(btnNewButton);
}
}
Panel2.java
package test;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
public class Panel2 extends JPanel {
private JTextField textField;
/**
* 创建面板。
*/
public Panel2() {
setLayout(null);
textField = new JTextField();
textField.setBounds(10, 60, 430, 19);
add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("新按钮2");
btnNewButton.setBounds(21, 157, 419, 21);
add(btnNewButton);
}
}
附:这是我第一次在Stackoverflow上提问,所以请原谅我,如果可能的话,请指导我是否漏掉了什么。
谢谢
编辑:我面临的问题是,表面上看,JPanel已经被刷新,但是组件(如JTextField)仍然隐藏了先前写入其中的文本,只有当我单击该JTextField时才会显示文本。
下面我附上另一个GIF,突出显示了我遇到的问题。我已经突出显示了我面临问题的部分。
<details>
<summary>英文:</summary>
Iam trying to build a desktop application with multiple screens inside one single JFrame.
So each button click event will take us to the separate screen with refreshed components in the screen. So far this approach is working for me but the problem I am facing is even after using ".dispose(), .repaint(), .revalidate(), .invalidate()" functions. JInternalFrame or Jpanel seems to not refresh its components.
Which works something like below gif.
[Tabbed Style][1]
I do know JtabbedPane exists but for my method JtabbedPane is not viable.
Below I am posting minified code by replicating the problem I am facing.
MainMenu.Java(file with Main Class)
package test;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JInternalFrame;
public class MainMenu extends JFrame {
private JPanel contentPane;
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, 841, 522);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JPanel panel = new JPanel();
panel.setBounds(10, 10, 807, 63);
contentPane.add(panel);
panel.setLayout(new GridLayout(1, 0, 0, 0));
JButton Tab1 = new JButton("Tab1");
panel.add(Tab1);
JButton Tab2 = new JButton("Tab2");
panel.add(Tab2);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 88, 807, 387);
contentPane.add(scrollPane);
JInternalFrame internalFrame1 = new JInternalFrame();
JInternalFrame internalFrame2 = new JInternalFrame();
Tab1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Panel1 panel1 = new Panel1();
if(internalFrame1 !=null) {
internalFrame1.dispose();
panel1.invalidate();
panel1.revalidate();
panel1.repaint();
}
internalFrame1.setTitle("Panel 1");
scrollPane.setViewportView(internalFrame1);
internalFrame1.getContentPane().add(panel1);
internalFrame1.setVisible(true);
}
});
Tab2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Panel2 panel2 = new Panel2();
if(internalFrame2 !=null) {
internalFrame2.dispose();
panel2.invalidate();
panel2.revalidate();
panel2.repaint();
}
internalFrame2.setTitle("Panel 2");
scrollPane.setViewportView(internalFrame2);
internalFrame2.getContentPane().add(panel2);
internalFrame2.setVisible(true);
}
});
}
}
and the corresponding Jpanel class files where JInternal Frames
Panel1.java
package test;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
public class Panel1 extends JPanel {
private JTextField textField;
/**
* Create the panel.
*/
public Panel1() {
setLayout(null);
textField = new JTextField();
textField.setBounds(10, 60, 430, 19);
add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("Example Button");
btnNewButton.setBounds(10, 156, 430, 21);
add(btnNewButton);
}
}
Panel2.java
package test;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
public class Panel2 extends JPanel {
private JTextField textField;
/**
* Create the panel.
*/
public Panel2() {
setLayout(null);
textField = new JTextField();
textField.setBounds(10, 60, 430, 19);
add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("New button2");
btnNewButton.setBounds(21, 157, 419, 21);
add(btnNewButton);
}
}
P.S: This is my first time asking question in Stackoverflow so forgive me and if possible guide me if i miss anything
Thank you :)
Edit:
The problem I am facing is on the surface it looks like the Jpanel has been refreshed but the components like JtextField Still hides the previously written text in it and only show the text when i click on that JTextField
Below I am Attaching another gif which show highlights the issue. I have highlighted the part where I am facing issue.
[Issue I am Facing][2]
[1]: https://i.stack.imgur.com/s7mar.gif
[2]: https://i.stack.imgur.com/JKJDZ.gif
</details>
# 答案1
**得分**: 0
你可以在JFrames中使用JPanels,然后使用[CardLayout](https://docs.oracle.com/javase/tutorial/uiswing/layout/card.html)来更改面板(这些面板可以像不同的屏幕一样操作)。
<details>
<summary>英文:</summary>
You can use the JPanels in the Jframes and then use the [CardLayout](https://docs.oracle.com/javase/tutorial/uiswing/layout/card.html) to change the panel ( which could than act like the different screens )
</details>
# 答案2
**得分**: 0
dispose()方法不会移除组件,因此在使用以下代码时,您会不断向内部框架添加组件:
```java
internalFrame1.getContentPane().add(panel1);
相反,您可以尝试类似以下的操作:
Container contentPane = internalFrame1.getContentPane();
contentPane.removeAll();
contentPane.add(panel1);
contentPane.revalidate();
contentPane.repaint();
英文:
The dispose() method does not remove components so you keep adding components to the internal frame when you use the following:
internalFrame1.getContentPane().add(panel1);
Instead you might do something like:
Container contentPane = internalFrame1.getContentPane();
contentPane.removeAll();
contentPane.add( panel1 );
contentPane.revalidate();
contentPane.repaint();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论