您好,我是Java新手,我遇到以下问题:
我创建了一个JFrame,我希望在单击JButton时更改JPanel。这几乎可以工作。唯一的问题是程序创建一个新窗口,然后有两个窗口。一个是第一个JPanel,一个是第二个JPanel。 这是我目前的代码:
第一堂课:
public class Program {
public static void main (String [] args) {
new window(new panel1());
}
}
第二课:
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Window extends JFrame {
private static final long serialVersionUID = 1L;
Window(JPanel panel) {
setLocation((int) Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 200,
(int) Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - 100);
setSize(400, 200);
setTitle("test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setContentPane(panel);
setVisible(true);
}
}
第三课:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Panel1 extends JPanel {
private final long serialVersionUID = 1L;
Panel1() {
JButton nextPanelButton = new JButton("click here");
add(nextPanelButton);
ActionListener changePanel = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
new window(new panel2());
}
};
nextPanelButton.addActionListener(changePanel);
}
}
第四课:
public class Panel2 extends JPanel {
private static final long serialVersionUID = 1L;
Panel2() {
JLabel text = new JLabel("You pressed the Button!");
add(text);
}
}
但我只是想在不打开新窗口的情况下更改JPanel。有没有办法做到这一点?
提前致谢!
答案 0 :(得分:0)
首先,请查看Java naming conventions,特别是您的班级名称应以大写字母开头。
如果要在每次单击按钮时避免打开新窗口,可以将框架对象传递给Panel1构造函数,并在单击按钮时将新的Panel2实例设置为框架内容窗格。也没有必要将Panel1传递给Window构造函数(请注意Window类已在java.awt包中定义,最好避免可能的名称冲突重命名您的类ApplicationWindow,MyWindow或其他东西)
您可以像这样更改您的代码(仅限相关部分):
public class Program
{
public static void main (String [] args) {
SwingUtilities.invokeLater (new Runnable () {
@Override public void run () {
new Window ().setVisible (true);
}
};
}
}
class Window extends JFrame
{
// ...
Window () {
// ...
setContentPane(new Panel1 (this));
}
}
class Panel1 extends JPanel
{
// ...
Panel1 (JFrame parent) {
// ...
ActionListener changePanel = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
parent.setContentPane (new Panel2 ());
}
};
// ...
}
另请注意SwingUtilities的invokeLater调用,这是在EDT上下文中初始化GUI的最佳方式(有关this question的更多信息,请参阅)。
最后,您可以避免每次单击按钮时创建一个新的Panel2实例,只需使用CardLayout即可。 看看official tutorial。
答案 1 :(得分:0)
这是一个演示
import javax.swing.*;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new MainFrame("Title").setVisible(true);
});
}
}
<强> MainFrame.java 强>
import javax.swing.*;
import java.awt.*;
public class MainFrame extends JFrame {
private JPanel viewPanel;
public MainFrame(String title) {
super(title);
createGUI();
}
private void createGUI() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new BorderLayout());
setMinimumSize(new Dimension(600, 480));
viewPanel = new JPanel(new BorderLayout());
add(viewPanel, BorderLayout.CENTER);
showView(new View1(this));
pack();
}
public void showView(JPanel panel) {
viewPanel.removeAll();
viewPanel.add(panel, BorderLayout.CENTER);
viewPanel.revalidate();
viewPanel.repaint();
}
}
View1.java
import javax.swing.*;
import java.awt.*;
public class View1 extends JPanel {
final private MainFrame owner;
public View1(MainFrame owner) {
super();
this.owner = owner;
createGUI();
}
private void createGUI() {
setLayout(new FlowLayout());
add(new JLabel("View 1"));
JButton button = new JButton("Show View 2");
button.addActionListener(event -> {
SwingUtilities.invokeLater(() -> owner.showView(new View2(owner)));
});
add(button);
}
}
<强> View2.java 强>
import javax.swing.*;
import java.awt.*;
public class View2 extends JPanel {
final private MainFrame owner;
public View2(MainFrame owner) {
super();
this.owner = owner;
createGUI();
}
private void createGUI() {
setLayout(new FlowLayout());
add(new JLabel("View 2"));
JButton button = new JButton("Show View 1");
button.addActionListener(event -> {
SwingUtilities.invokeLater(() -> owner.showView(new View1(owner)));
});
add(button);
}
}
答案 2 :(得分:0)
这是一个旧帖子,但以简化的方式回答它可能会有所帮助。感谢 mcwolf 先生的第一个回答。
如果我们想让 1 个子 jframe 与主 jframe 交互以修改其内容,让我们考虑以下情况。
parent.java
和 child.java
。
所以,在 parent.java 中,我们有这样的东西:
Parent.java
public class Parent extends JFrame implements ActionListener{
//attributes
//here is the class we want to modify
private some_class_to_modify = new some_class_to_modify();
//here is a container which contains the class to modify
private JPanel container = new JPanel();
private some_class = new some_class();
private int select;
//....etc..etc
//constructor
public Parent(){
this.setTitle("My title");
//etc etc
//etc....etc
container.add(some_class_to_modify,borderLayout.CENTER);
}
//I use for instance actionlisteners on buttons to trigger the new JFrame
public void actionPerformed(ActionEvent arg0){
if((arg0.getSource() == source_button_here)){
//Here we call the child class and send the parent's attributes with "this"
Child child = new Child(this);
}
//... all other cases
}//Here is the class where we want to be able to modify our JFrame. Here ist a JPanel (Setcolor)
public void child_action_on_parent(int selection){
this.select = selection;
System.out.println("Selection is: "+cir_select);
if(select == 0) {
//Do $omething with our class to modify
some_class_to_modify.setcolor(Color.yellow);
}
}
在 child.java 中,我们会有这样的东西:
public class Child extends JFrame implements ActionListener {
//Again some attributes here
private blabla;
//Import Parent JFrame class
private Parent owner;
private int select_obj=0;
//Constructor here and via Parent Object Import
public Child(Parent owner){
/*By calling the super() method in the constructor method, we call the parent's
constructor method and gets access to the parent's properties and methods:*/
super();
this.owner = owner;
this.setTitle("Select Method");
this.setSize(400, 400);
this.setContentPane(container);
this.setVisible(true);
}
class OK_Button implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object Selection = select;
if(Selection == something) {
select_obj=0;
valid = JOptionPane.showConfirmDialog(null,"You have chosen option 1. Do you want to continue?","Minimum diameter",2);
}
System.out.println("Option is:"+valid);
if(valid == 0) {
setVisible(false);
//Here we can use our herited object to call the child_action_on_parent public class of the Parent JFrame. So it can modify directly the Panel
owner.child_action_on_parent(select_obj);
}
}
}