简体   繁体   中英

Java JDialogs How To Pass Information Between?

after looking for an answer for 3 hours, I am just about to give up on this idea:

I am making an application that displays the followers of a Twitch streamer. A couple of features i am trying to add:

the display frame is a separate window from the controls frame. I am trying to use (JFrame as display window) (JDialog as controls frame) And furthermore: Settings is in another JDialog (this one has Modal(true)) Settings needs to be able to send the JFrame information such as: "username" and "text color" And the settings JDialog will only pop up from clicking "settings" on the controls JDialog. It will setVisible(false) when you click "save settings" or the X. On the controls JDialog (b_console) needs to receive error messages and info like that. And on the same JDialog, "filler" needs to receive follower count and things like that.

Here follows my code involving the transfers listed above:

package javafollowernotifier;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics.*;
import javax.swing.*;
import java.io.*;
import java.net.URL;

public class JavaFollowerNotifier extends JFrame implements ComponentListener
{
    Settings settings = new Settings();
    ControlPanel ctrlPnl = new ControlPanel();

    public JavaFollowerNotifier()
    {        
        try
        {
            settings.readSettings();
        }
        catch(Exception e)
        {
            ctrlPnl.b_console.setText("Error");
            System.out.println(e);
        }
    }

    public void grabFollower()
    {
        ctrlPnl.b_console.setText("Retrieving Info...");

        try
        {
            URL twitch = new URL("https://api.twitch.tv/kraken/channels/" + savedSettings[1] + "/follows?limit=1&offset=0");

            ctrlPnl.b_console.setText("Retrieved");
        }
        catch(Exception e)
        {
            ctrlPnl.b_console.setText("Error");
            System.out.println(e);
        }
    }

    public void grabStats()
    {            
        ctrlPnl.b_console.setText("Retrieving Info...");

        try
        {
            URL twitch = new URL("https://api.twitch.tv/kraken/channels/" + savedSettings[1] + "/follows?limit=1&offset=0");

            ctrlPnl.filler.setText("Followers: " + totalFollowers + "\nLatest: " + lastFollower);
            ctrlPnl.b_console.setText("Retrieved");
        }
        catch(Exception e)
        {
            ctrlPnl.b_console.setText("Error");
            System.out.println(e);
        }
    }

    public void componentMoved(ComponentEvent arg0)
    {
        //this is only to *attach this JDialog to the JFrame and make it move together my plan is to have it undecorated as well
        int x = this.getX() + this.getWidth();
        int y = this.getY();
        ctrlPnl.movePanel(x, y);
    }

    public void paint(Graphics g)
    {
        if(clearPaint == false)
        {
            //any "savedSettings[n]" are saved in Settings.java (just not in this version)
            g.setColor(Color.decode(savedSettings[3]));
            scaledFont = scaleFont(follower + " followed!", bounds, g, new Font(savedSettings[2], Font.PLAIN, 200));
        }
    }
}



package javafollowernotifier;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;

public class Settings extends JDialog implements ActionListener
{
    JavaFollowerNotifier jfollow = new JavaFollowerNotifier();
    ControlPanel ctrlPnl = new ControlPanel();

    //here are the settings mention above
    String[] savedSettings = {"imgs/b_b.jpg","username","font","color","Nightbot"};

    public Settings()
    {         
        try
        {
           UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e)
        {
            ctrlPnl.b_console.setText("Error");
            System.out.println(e);
        }
    }

    public void saveSettings()
    {
            savedSettings[4] = jfollow.lastFollower;

        try
        {
            PrintWriter save = new PrintWriter("config.cfg");
            ctrlPnl.b_console.setText("Saving...");
            for(int i = 0; i < 5; i++)
            {
                save.println(savedSettings[i]);
            }
            save.close();
            ctrlPnl.b_console.setText("Saved");
        }
        catch(Exception e)
        {
            ctrlPnl.b_console.setText("Error");
            System.out.println(e);
            canClose = false;
        }

        readSettings();
        this.repaint();
    }

    public void readSettings()
    {
        ctrlPnl.b_console.setText("Loading...");

        try
        {
        }
        catch(Exception e)
        {
            ctrlPnl.b_console.setText("Error");
            System.out.println(e);
        }

        jfollow.lastFollower = savedSettings[4];

        try
        {
        }
        catch(Exception e)
        {
            ctrlPnl.b_console.setText("Error");
            System.out.println(e);
        }

        ctrlPnl.b_console.setText("Loaded Settings");
    }
}



package javafollowernotifier;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ControlPanel extends JDialog implements ActionListener
{      
    public ControlPanel()
    {
        try
        {
        }
        catch (Exception e)
        {
            b_console.setText("Error");
            System.out.println(e);
        }
    }

    public void movePanel(int x, int y)
    {
        //here is where i *attach the JDialog to the JFrame
        controlPanel.setLocation(x, y);
    }

    public void actionPerformed(ActionEvent ie)
    {
        if(ie.getSource() == b_settings)
        {
            settings.frame.setVisible(true);
        }
    }
}

I tried to fix your program, but I wasn't too sure about its flow. So I created another simple one. What I did was pass the labels from the main frame to the dialogs' constructors. In the dialog, I took those labels and changed them with text entered in their text fields. If you hit enter after writing text from the dialog, you'll see the text in the frame change

public class JavaFollowerNotifier1 extends JFrame{

    private JLabel controlDialogLabel = new JLabel("  ");
    private JLabel settingDialogLabel = new JLabel("  ");
    private ControlDialog control;
    private SettingsDialog settings;

    public JavaFollowerNotifier1() {
        control = new ControlDialog(this, true, controlDialogLabel);
        settings = new SettingsDialog(this, true, settingDialogLabel);

....

class ControlDialog extends JDialog {
    private JLabel label;

    public ControlDialog(final Frame frame, boolean modal, final JLabel label) {
        super(frame, modal);
        this.label = label;

....

class SettingsDialog extends JDialog {
    private JLabel label;

    public SettingsDialog(final Frame frame, boolean modal, final JLabel label) {
        super(frame, modal);
        this.label = label;

Test it out and let me know if you have any questions

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class JavaFollowerNotifier1 extends JFrame{

    private JLabel controlDialogLabel = new JLabel("  ");
    private JLabel settingDialogLabel = new JLabel("  ");

    private JButton showControl = new JButton("Show Control");
    private JButton showSetting = new JButton("Show Settings");

    private ControlDialog control;
    private SettingsDialog settings;

    public JavaFollowerNotifier1() {
        control = new ControlDialog(this, true, controlDialogLabel);
        settings = new SettingsDialog(this, true, settingDialogLabel);


        showControl.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                control.setVisible(true);
            }
        });
        showSetting.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                settings.setVisible(true);
            }
        });

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(showControl);
        buttonPanel.add(showSetting);

        add(buttonPanel, BorderLayout.SOUTH);
        add(controlDialogLabel, BorderLayout.NORTH);
        add(settingDialogLabel, BorderLayout.CENTER);

        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new JavaFollowerNotifier1();
            }
        });
    }

}

class ControlDialog extends JDialog {
    private JLabel label;
    private JTextField field = new JTextField(15);
    private JButton button = new JButton("Close");
    private String s = "";

    public ControlDialog(final Frame frame, boolean modal, final JLabel label) {
        super(frame, modal);
        this.label = label;

        setLayout(new BorderLayout());
        add(field, BorderLayout.NORTH);
        add(button, BorderLayout.CENTER);

        pack();
        setLocationRelativeTo(frame);

        field.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                s = field.getText();
                label.setText("Message from Control Dialog: " + s);
            }
        });
        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                ControlDialog.this.setVisible(false);
            }
        });
    }
}

class SettingsDialog extends JDialog {
    private JLabel label;
    private JTextField field = new JTextField(15);
    private JButton button = new JButton("Close");
    private String s = "";

    public SettingsDialog(final Frame frame, boolean modal, final JLabel label) {
        super(frame, modal);
        this.label = label;

        setLayout(new BorderLayout());
        add(field, BorderLayout.NORTH);
        add(button, BorderLayout.CENTER);

        pack();
        setLocationRelativeTo(frame);

        field.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                s = field.getText();
                label.setText("Message from Settings Dialog: " + s);
            }
        });
        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                SettingsDialog.this.setVisible(false);
            }
        });
    }
}

在此输入图像描述

Typically when I build GUI's which use modal dialogs to gather user input, I build my own class, which extends the JDialog or in some cases a JFrame. In that class I expose a getter method for an object which I usually call DialgResult. This object acts as the Model for the input I gather from the user. In the class that has the button, or whatever control which triggers asking the user for the information, I create it, show it as a modal dialog, then when it is closed, I retrieve the object using that same getter.

This is a very primitive example:

package arg;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class asdfas extends JFrame {


public static void main(String[] args) {
    asdfas ex = new asdfas();
    ex.setVisible(true);
}

public asdfas() {
    init();
}

private void init() {
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setBounds(100,100,200,200);

    final JButton button = new JButton("Show modal dialog");
    button.addActionListener( new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            Dialog d = new Dialog();
            d.setVisible(true);         

            button.setText(d.getDialogResult().value);
            revalidate();
            repaint();
        }
    });

    this.add(button);       
}
class DialogResult {
    public String value;
}
class Dialog extends JDialog {
    JTextField tf = new JTextField(20);
    private DialogResult result = new DialogResult();
    public Dialog() {
        super();
        init();
    }

    private void init() {
        this.setModal(true);

        this.setSize(new Dimension(100,100));
        JButton ok = new JButton("ok");
        ok.addActionListener( new ActionListener () {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                result = new DialogResult();
                result.value = tf.getText();
                setVisible(false);
            }

        });
        JPanel p = new JPanel();
        p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
        p.add(tf);
        p.add(ok);
        this.add(p);
    }

    public DialogResult getDialogResult() {
        return result;
    }
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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