简体   繁体   English

在另一个JFrame中单击按钮时,更改其他JFrame中的属性

[英]Change attribute in other jframe when a button is clicked in another JFrame

I have 2 jframes, 1 is kinda like the main menu, i want an attribute to change in the level jframe when a button is pressed so i tried: 我有2个jframe,1个有点像主菜单,我想当按下按钮时在jframe级别更改属性,所以我尝试了:

SpeelVeld frame = new SpeelVeld();
    frame.level = 1;
    System.out.println(frame.level);

I used the sout to see what really happens because it wasnt working, but i see that the level goes from 0 to 1 back to 0 and goes on and on, does someone know why and how to fix? 我使用sout来查看实际发生的情况,因为它没有起作用,但是我看到该级别从0变为1,然后又回到0,然后一直不断,有人知道为什么以及如何解决吗?

SpeelVeld frame = new SpeelVeld();


    frame.setBounds(0,0,519,591);
    frame.setLocationRelativeTo(null);
    frame.getContentPane().setBackground(Color.WHITE);
    frame.setTitle("RWINA");
    frame.setVisible(true);
    frame.setLevel(1);

this is in the main method of my original GameProject file. 这是我原始GameProject文件的主要方法。

How can i make a jdialog 我如何制作jdialog

I have 2 jframes, 1 is kinda like the main menu, 我有2个jframe,1个有点像主菜单,

You shouldn't use 2 JFrames for this. 您不应该为此使用2个JFrame。 The dependent sub-window, likely your main menu window, should in fact be a JDialog, probably a non-modal dialog from the looks of it. 从属子窗口(可能是您的主菜单窗口)实际上应该是JDialog,从其外观看可能是非模式对话框。

I want an attribute to change in the level jframe when a button is pressed so i tried: 我希望按下按钮时在jframe级别中更改属性,所以我尝试了:

 SpeelVeld frame = new SpeelVeld(); frame.level = 1; System.out.println(frame.level); 

and here's a big problem. 这是一个大问题。 Understand that in this code, you're creating a new SpeelVeld object, the stress being on the word new . 可以理解,在这段代码中,您正在创建一个新的 SpeelVeld对象,其中的重点是单词new Changing the state of this object will have no effect on the other SeelVeld object that is currently being displayed. 更改该对象的状态将不会对当前正在显示的另一个SeelVeld对象产生影响。 Do do that, your second window will need a valid reference to the displayed SeelVeld object. 这样做,您的第二个窗口将需要对显示的 SeelVeld对象的有效引用。 How to do this will depend all on code not yet shown, but often it can be done simply by passing in the displayed SpeelVeld object into the main menu object by use of a constructor parameter or setter method. 如何执行此操作将取决于所有尚未显示的代码,但是通常可以通过使用构造函数参数或setter方法将显示的SpeelVeld对象传递到主菜单对象中来完成此操作。

For example: 例如:

import java.awt.Dialog.ModalityType;    
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

// JPanel for our main GUI
public class SpeelVeldFoo {

    private static void createAndShowGui() {
        // JPanel used by the main JFrame
        SpeelVeldPanel speelVeldPanel = new SpeelVeldPanel();

        // JPanel used by the main menu JDialog. Pass the above into it
        MainMenuPanel mainMenuPanel = new MainMenuPanel(speelVeldPanel); 

        // create your JFrame
        JFrame frame = new JFrame("Speel Veld");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(speelVeldPanel); // add the JPanel
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        // create your non-modal JDialog
        JDialog menuDialog = new JDialog(frame, "Main Menu", ModalityType.MODELESS);
        menuDialog.add(mainMenuPanel); // add the JPanel that holds its "guts"
        menuDialog.pack();
        menuDialog.setLocationByPlatform(true);
        menuDialog.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            createAndShowGui();
        });
    }
}

@SuppressWarnings("serial")
class SpeelVeldPanel extends JPanel {
    private int level = 1; // simple example just has a level int
    private JLabel levelLabel = new JLabel("1"); // and displays it in a JLabel

    public SpeelVeldPanel() {
        add(new JLabel("Level:"));
        add(levelLabel);

        int ebGap = 50;
        setBorder(BorderFactory.createEmptyBorder(ebGap, 2 * ebGap, ebGap, 2 * ebGap));
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        // whenever level is changed, update the display
        this.level = level;
        levelLabel.setText(String.valueOf(level));
    }
}

// class for the JPanel held by the JDialog
@SuppressWarnings("serial")
class MainMenuPanel extends JPanel {
    private JSpinner levelSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 5, 1));
    private SpeelVeldPanel speelVeldPanel = null; // reference to the main GUI

    // note the parameter.... you pass in the displayed main GUI so you can
    // change it
    public MainMenuPanel(final SpeelVeldPanel speelVeldPanel) {
        this.speelVeldPanel = speelVeldPanel; // set the field

        // respond when the spinner's data changes
        levelSpinner.addChangeListener(new LevelListener());

        add(new JLabel("Set the Speel Veld's level:"));
        add(levelSpinner);

        int ebGap = 10;
        setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
    }

    private class LevelListener implements ChangeListener {

        @Override
        public void stateChanged(ChangeEvent e) {
            // when the spinner's data changes
            int level = (int) levelSpinner.getValue(); // get the data
            speelVeldPanel.setLevel(level); // and send it to the main GUI
        }
    }
}

You'll note that I don't like extending JFrame or JDialog if I can avoid it. 您会注意到,如果可以避免的话,我不喜欢扩展JFrame或JDialog。 My feeling is that one can paint oneself into a corner by having your class extend JFrame, forcing you to create and display JFrames, when often more flexibility is called for. 我的感觉是,可以通过使您的类扩展JFrame,迫使您创建和显示JFrame(通常需要更大的灵活性)来使自己陷入困境。 More commonly your GUI classes will be geared towards creating JPanels, which can then be placed into JFrames or JDialogs, or JTabbedPanes, or swapped via CardLayouts, wherever needed. 更常见的是,您的GUI类将面向创建JPanels,然后将其放置到JFrames或JDialogs或JTabbedPanes中,或者在需要时通过CardLayouts进行交换。 This will greatly increase the flexibility of your GUI coding. 这将大大增加GUI编码的灵活性。

You probably want the JFrame to be the top-level container, then have a JPanel that holds your menu. 您可能希望将JFrame用作顶级容器,然后拥有一个保存菜单的JPanel。 The menu could be whatever you want, I'm using a JTextArea. 菜单可以是您想要的任何菜单,我正在使用JTextArea。 Then, you need a JButton for the JPanel or JFrame that when pressed, changes the text in the JTextArea. 然后,您需要一个用于JPanel或JFrame的JButton,按下该按钮将更改JTextArea中的文本。 Here is an implementation that you could work from. 这是您可以使用的实现。 I'm using the ActionEvent as the trigger for when to mess with the JTextArea: 我使用ActionEvent作为何时与JTextArea混淆的触发器:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class SimpleSwing {
    public static void main(String[] args) {
        JFrame mainFrame = new JFrame();
        JPanel mainMenuPanel = new JPanel();
        JTextArea textAttribute = new JTextArea("Original Text");
        JButton changeAttributeButton = new JButton("Change Attribute");

        changeAttributeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textAttribute.setText("Whatever new text you want");
            }
        });

        mainMenuPanel.add(textAttribute);
        mainMenuPanel.add(changeAttributeButton);
        mainFrame.add(mainMenuPanel);

        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setSize(500, 500);
        mainFrame.setVisible(true);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM